- ベストアンサー
AccessからExcel立ち上げ
- Access2003で作成したテーブルをExcelに出力し、そのファイルをAccessから開き、罫線や列幅等フォーマットを自動的に整え、表示します。
- アクセスで設定したエクセルのオブジェクト変数をCloseしてしまうと、エクセル画面が閉じられてしまう為、AccessモジュールでのClose処理を行わないままとなっています。
- Excel画面表示後、DoループDoEvents関数で待ち状態とし、ボタン操作でExcel操作の終了を知らせて、オブジェクト変数のClose処理を行えばいいのかと思いますが、一般にはどのように処理されているものなのかご教示下さい。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ANO.1,2です。 >繰り返し、エクセルファイルを作成する試験を行ったところ、オブジェクト変数のclose処理を行ったのに改善されませんでした。 とは、私も意外でした。 なにか他に悪さをしている処理があるのでしょうけど、 ちょっと見当がつかないです。 ただ、最後に1個だけ、 ・・・ XLWS.Select With ActiveSheet.PageSetup ・・・ With XLWS.PageSetup に変えても動いたと思うのですが、 これでやってみてもだめでしょうか? ( 例えばExcel自体が2個立ち上がっていると With ActiveSheet.PageSetup とすると、どちらのExcel?ってことになるように思われますので。 )
その他の回答 (2)
- Siegrune
- ベストアンサー率35% (316/895)
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の環境はあるので、 うまくいかないようなら、明日以後にでもこちらでも試してみます。)
お礼
繰り返し、エクセルファイルを作成する試験を行ったところ、オブジェクト変数のclose処理を行ったのに改善されませんでした。 With ActiveSheet.PageSetup .PrintTitleRows = "$1:$1" .PrintTitleColumns = "" End With 上記1行目で、「91:オブジェクト変数又はWithブロック変数が設定されていません。」というエラーが起こり、2回目以降フォーマット化を行う事が出来ませんでした。 今回は、Shell関数の使用方法をご教示頂き有難うございました。予想に反し、解決に至りませんでしたが、またよろしくお願い申し上げます。もう少し解決法を検討後、改めて質問させて頂く事に致します。 有難う御座いました。
補足
詳細にご教示頂き、感謝いたします。 ご推奨頂いた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
- Siegrune
- ベストアンサー率35% (316/895)
どうやって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する必要があると思うのですが、これを行うと、エクセル画面を確認できないので、こんなことをしてしまっています。 エクセル画面を表示させた状態で、オブジェクト変数を適切に処置するにはどうすればよいでしょうか? よろしくお願い致します。
お礼
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 に変えて確認したところ、問題解決しました。 今回は、種々ご教示、ご検討頂き有難う御座いました。厚く御礼申し上げます。
補足
ご教示いただいたように冒頭に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