プロが教えるわが家の防犯対策術!

Access2003で作成したテーブルをExcelに出力し、そのファイルをAccessから開き、罫線や列幅等フォーマットを自動的に整え、表示します。表示中にデータ確認し、印刷等の処理を行い、閉じて、またAccessの操作に戻りたいと思います。
この際、アクセスで設定したエクセルのオブジェクト変数をCloseしてしまうと、エクセル画面が閉じられてしまう為、AccessモジュールでのClose処理を行わないままとなっています。この為か、引き続いて条件を変えてエクセルに出力して、同様の処理を行うと、AccessモジュールからのExcelの自動フォーマット化が行われなくなってしまいます。Accessを再起動すれば、正常に処理できるので、オブジェクト変数のClose未処理が原因と考えています。
このような場合、一般にはどのように処理されているのでしょうか?Excel画面表示後、DoループDoEvents関数で待ち状態とし、ボタン操作でExcel操作の終了を知らせて、オブジェクト変数のClose処理を行えばいいのかと思いますが、一般にはどのように処理されているものなのかご教示下さい。

A 回答 (3件)

ANO.1,2です。



>繰り返し、エクセルファイルを作成する試験を行ったところ、オブジェクト変数のclose処理を行ったのに改善されませんでした。
とは、私も意外でした。
なにか他に悪さをしている処理があるのでしょうけど、
ちょっと見当がつかないです。

ただ、最後に1個だけ、
・・・
XLWS.Select
With ActiveSheet.PageSetup
・・・

With XLWS.PageSetup
に変えても動いたと思うのですが、
これでやってみてもだめでしょうか?


例えばExcel自体が2個立ち上がっていると
With ActiveSheet.PageSetup
とすると、どちらのExcel?ってことになるように思われますので。

この回答への補足

ご教示いただいたように冒頭にXLWS.とXLWS.Application.を付加して実行してみました。
当初のコマンドラインは、クリアできましたが、後の方のRangeのところ(下記参照)でエラーとなりました。()内のSelectionの指定方法ではないかと思います。他のSelectionは、XLWS.Application.とすることでクリアしています。Range()内のSelectionは、この方法では、クリアできませんでした。
一回目の処理は、問題なく出来ています。アクセスモジュールからの実行に無理があるのでしょうか?
With XLWS.PageSetup
.PrintTitleRows = "$1:$1"
.PrintTitleColumns = ""
End With

XLWS.Columns("A:A").Select '1列目列削除
XLWS.Application.Selection.Delete Shift:=xlToLeft

XLWS.PageSetup.PrintArea = ""
With XLWS.PageSetup 'ページ書式設定
.LeftHeader = ""
    ・・・
.PrintErrors = xlPrintErrorsDisplayed
End With

XLWS.Range("A1").Select '罫線設定
XLWS.Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select 'ここでNo.1004のエラーとなりました。
XLWS.Application.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
XLWS.Application.Selection.Borders(xlDiagonalUp).LineStyle = xlNone

補足日時:2013/11/12 13:36
    • good
    • 0
この回答へのお礼

XLWS.Range("A1").select
XLWS.Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select を
With XLWS
.Range(.Cells(1, 1), .Cells(1, 1).SpecialCells(xlLastCell)).Select
End With
に変えて確認したところ、問題解決しました。
今回は、種々ご教示、ご検討頂き有難う御座いました。厚く御礼申し上げます。

お礼日時:2013/11/14 21:25

ANo.1です。



補足に書いていただいたソース見ました。
イメージつかめました。

strFilename は毎回同じですか?
毎回同じならば、
必ず、Excelを終了してから、Accessのほうを実行しているならばいいのですが、
Excelを閉じずに動かしてしまうと、おかしなことがおきそうな気がします。

それがあるので、strFilename は毎回違うという前提にして話をします。

XLWS.Visible = True
にして、Excel側で手操作したいのだが、次の処理が動いてしまう、
したがって、続きに、
Set XLAPP = Nothing
Set XLWB = Nothing
Set XLWS = Nothing
と書いてExcelをAccessから切り離している(ように見えますが、本当に切り離せるのかは不明。)

私なら、
XLSWBを保存して、XLSWBをCloseし、XLAPPをCloseし、
set xxx = nothingを実行します。
で、次に、
ShellでExcelを起動します。
(Shellで起動したら最初からAccessと切り離されているため、相互に悪さすることがない。)
Shell ( "C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE " & strFilename
,vbNormalFocus)
という感じです。
ただ、ネックは、EXCEL.EXEのパスがまちまちであること。
(探せはどこかにパス名の取得方法があるのかもしれませんが。)

参考文献:
http://www.accessclub.jp/vbakaisetu/49.html

※これをするとExcelが完全に切り離されるので、Excelを終わらずに、次々とAccessの処理を
してしまい大量にExcelが起動されたままとなる可能性はあります。
(操作、運用上の問題なので、操作、運用でカバーしてもらうべきでしょう。)


>Excel画面表示後、DoループDoEvents関数で待ち状態とし、
>ボタン操作でExcel操作の終了を知らせて、
>オブジェクト変数のClose処理を行えばいいのかと思いますが、
確かにそうかもしれませんし、
他にも考えられる手はいくつかあるのですが、
いずれもAccess側の負荷が・・・。
(Do loopまわすと負荷がかかるので、タイマ割り込みとかの方がいいけど、タイムラグがでる。)

いっそ、
Set XLAPP = Nothing
Set XLWB = Nothing
Set XLWS = Nothing
もしないで、このボタンの処理の最初とプログラムの終了前の処理で、
if XLAPP is not nothing then
XLWB.close
XLAPP.close
Set XLAPP = Nothing
Set XLWB = Nothing
Set XLWS = Nothing
end if
が出来たかどうかわかりませんが、ダメでも、
XLAPP is not nothing の変わりにフラグでも用意すればできるはず。
という感じで終了させたら?とも思いますが、
・・・Excel側で終了させてしまってこの処理が動くとエラーになりそうです。
ならば、いっそ、
On Error Resume Next
XLWB.close
XLAPP.close
Set XLAPP = Nothing
Set XLWB = Nothing
Set XLWS = Nothing
On Error goto 0
としたら?というのもありますが。
(但し、この場合のエラーがOn Error Resume Nextで処理してくれるかは確認必要。)

以上どこまで役に立つ情報かわかりませんが、ご参考まで。
(今日はもう遅いですので検証とかする時間がとれないです。2003の環境はあるので、
 うまくいかないようなら、明日以後にでもこちらでも試してみます。)

この回答への補足

詳細にご教示頂き、感謝いたします。
ご推奨頂いたShell関数を使用する方法で確認致しました。
下記のように、プログラム変更したところ、希望どおりの処理ができました。
Excelは、2010を使用しており、フォルダをOffice14に変えています。
取り急ぎ、状況報告です。更に、問題ないか確認してみます。

'XLWS.Visible = True
XLWB.Save
XLWB.Close
XLAPP.Quit

Set XLAPP = Nothing
Set XLWB = Nothing
Set XLWS = Nothing

Shell "C:\Program Files\Microsoft Office\OFFICE14\EXCEL.EXE " & strFileName, vbNormalFocus

End Sub

補足日時:2013/11/11 09:57
    • good
    • 0
この回答へのお礼

繰り返し、エクセルファイルを作成する試験を行ったところ、オブジェクト変数のclose処理を行ったのに改善されませんでした。

With ActiveSheet.PageSetup
.PrintTitleRows = "$1:$1"
.PrintTitleColumns = ""
End With

上記1行目で、「91:オブジェクト変数又はWithブロック変数が設定されていません。」というエラーが起こり、2回目以降フォーマット化を行う事が出来ませんでした。
今回は、Shell関数の使用方法をご教示頂き有難うございました。予想に反し、解決に至りませんでしたが、またよろしくお願い申し上げます。もう少し解決法を検討後、改めて質問させて頂く事に致します。
有難う御座いました。

お礼日時:2013/11/11 20:20

どうやってExcelを制御しているのかわからないのでピントハズレかもしれませんが


(プログラムソースの関連する部分でも書いてもらうとわかりやすいかと。)

>アクセスで設定したエクセルのオブジェクト変数をCloseしてしまうと
ではなくって、エクセルで開いているブックをCloseすると思います。
そして、アクセスのプログラムの最後で、エクセルをCloseする。
(エクセルのCloseは、しておかないとメモリリークの原因になりかねないので。
 ・・・なるとは限りませんが。)

この回答への補足

早速ご検討頂きありがとう御座います。
コードの主要部分は、下記のようになっております。

Public Sub ExcelMaking(QueryName As String)
Dim strFileName As String
Dim XLAPP As Excel.Application
Dim XLWB As Excel.Workbook
Dim XLWS As Excel.Worksheet

strFilename= ファイルパス名
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, QueryName, strFileName

Set XLAPP = CreateObject("Excel.Application")
Set XLWB = XLAPP.Workbooks.Open(strFileName)
Set XLWS = XLWB.Worksheets(1)

XLAPP.Visible = True
XLWS.Select

With ActiveSheet.PageSetup
.PrintTitleRows = "$1:$1"
.PrintTitleColumns = ""
End With

  ・・・エクセル外観のフォーマット処理

XLWS.Visible = True 'ここでフォーマット後のシートを画面表示させます。ここで、表示確認や印刷を行います。

Set XLAPP = Nothing 'プログラムはそのまま実行されていくので、画面表示を残す為、Closeせずに、
Set XLWB = Nothing  ’取りあえずオブジェクト変数にNothingを代入しています。
Set XLWS = Nothing

End Sub

以上のようなプログラムで、本来Nothing設定前に、XLAPP、XLWB、XLWSをCloseする必要があると思うのですが、これを行うと、エクセル画面を確認できないので、こんなことをしてしまっています。
エクセル画面を表示させた状態で、オブジェクト変数を適切に処置するにはどうすればよいでしょうか?
よろしくお願い致します。

補足日時:2013/11/10 20:49
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す