アプリ版:「スタンプのみでお礼する」機能のリリースについて

既に開いているエクセルがあります。ファイル名は既知です。
この開いているエクセルを、アクセスから閉じたいのです。以下のようにコードを書いたところ、結局別のエクセルが開いて、それが閉じるだけで、元のエクセルは閉じません。
既に開いているエクセルを終了させる方法を教えてください。


Dim closefilename As String
closefilename = ”閉じたいエクセルのファイル名”

Set AppObj = CreateObject("Excel.Application") '実行時バインディング
Set WBObj = AppObj.Workbooks.Open(closefilename) 'ワークブックを開く

WBObj.Close SaveChanges:=True
AppObj.Visible = True
WBObj.Close
Set WBObj = Nothing '解放

AppObj.Quit 'Excel の終了
Set AppObj = Nothing

End Function

4行目で、ファイルがロードされていないエクセルが開いて、それが閉じるだけで、すでに開いているエクセルは閉じません。

A 回答 (4件)

まず、「実行時バインディング」には「方法が2つ」あって、



「CreateObject関数」を使う方法

「GetObject関数」を使う方法

の2つです。

※「そう教えてくれる講師は皆無」、といっていいほど全滅状態で「居ない」(CreateObject関数ばっかり教える)ので、僕もちょっと前までは、「実行時バインディング=CreateObject関数だけ」と誤解していました。以下のサイトもご参考に。(ここでも「方法が2つある」とは書いてはありませんが)
http://www016.upp.so-net.ne.jp/cheetah/xlvba/VBA …
http://www.shoeisha.com/book/hp/pc/office/Word/f …

「CreateObject関数」と「GetObject関数」の、それぞれの利用シーンの違いは次の通りです。

(01)「CreateObject関数」→「新規に」Excelのファイルを作りたい時・かつ・それをリモコン操作したい。
(02)「GetObject関数」→既存のファイルを開きたい時、もしくはフルパスの分かっているファイルがすでに開いていて、それをリモコン操作したい時。

なので、今回のご要望では、「CreateObject関数」ではなくて、「GetObject関数」を使います。
ご質問にあった、「結局別のエクセルが開いて、それが閉じるだけ」という動作は、「CreateObject関数」を使う以上は、どうしてもそうなってしまいます。


あと、「GetObject関数」は、「既存のファイル」を扱えるのですが・・・、

(a):もしまだその目的の「既存ファイル」が開かれていなければ、それを開いて、オブジェクトとして取得し、返してくれる。よってその場合は「×××.Application=Visible」というコードが必要です。
(b):すでに目的の「既存ファイル」が開かれていれば、それを、オブジェクトとして取得し、返してくれる。この場合はすでに目に見えているので「×××.Application=Visible」というコードは不要です。

・・・のいずれかを、自動的にやってくれます。

もちろん、「実行時バインディングをしつつ」、(a):と(b):をしてくれます。


今回は、(b):のほうになりますね。


ご希望の動作は、多分ですが、以降に示したような感じのコードで実現できるのではないかと思います。コメントを多く書いてしまいましたので、邪魔だったら全部消して試してみてください。
(F8キーでのステップ実行をして、ローカルウィンドウでどの変数に何が入っているかなども確認すると、より、動作のイメージが明確になると思います。)

ただし、このコードでは、例えばExcel2010以前のバージョンで、「1つのExcelウィンドウの中に、複数のファイルが子ウィンドウで開いていた場合」は、それらのファイルも道連れに閉じてしまいます。
なので、もしそうしたくない場合は、
「先に1つ以上のファイルが開いていたら、目的のファイルだけ閉じて、
残りのファイルは閉じずに、アプリケーションウィンドウは残す。」
という動作に作り変えてください。

がんばってください。

=======================================

Function ExcelCloseTest01()

Dim App01 As Object '言わば「ガワ」を代入するための変数
Dim WBObj As Object '開いているブックを代入するための変数
Dim closefilename As String

'閉じたいファイルのフルパス
closefilename = "フルパスの内容"


'「実行時バインディング」をすると同時に、
'現在、開いているブックを取得(選択)して
'オブジェクト変数に代入します。
Set WBObj = GetObject(closefilename)
'WBObj.Application.Visible = True '既存ファイルが閉じていた場合だけ使う。

'※実行時バインディングは、
'  CreateObject関数だけでなく、
'  GetObject関数でもできます。
'  そういう説明をしてくれるサイトも本も
'  すごく少ないですけど。


'開いているブックのアプリケーションウィンドウ
'(=言わば空っぽの「ガワ」)を
'オブジェクト変数に代入します。
Set App01 = WBObj.Application

'  「Application」オブジェクト(=空っぽの「ガワ」)は
'  「ブック」の1つ上の階層のオブジェクトです。
'  イミディエイトウィンドウにて
'  ? TypeName(ActiveWorkbook.Parent) とか、
'  ? ActiveWorkbook.Parent とやると、
'  多分、上記のコードが何をしているかの意味がわかると思います。




'開いているファイルを保存して閉じる
WBObj.Close SaveChanges:=True
Set WBObj = Nothing '解放

'残ったExcelのアプリケーションウィンドウ(言わばガワ)を閉じる。
App01.Quit
Set App01 = Nothing

End Function


=======================================
    • good
    • 3
この回答へのお礼

ありがとうございました。丁寧なコメント迄つけていただきありがとうございます。無事解決しまし得た。それにしても、いくらGoogl検索しても教えていただいた内容は見つかりませんでした。助かりました。

お礼日時:2019/04/20 17:43

'--------------


Const CloseFile ="********.xls*" 'フルパスは不要です。
On Error Resume Next
Set AppObj = GetObject(,"Excel.Application") 'カンマに注意
AppObj.Workbooks(CloseFile).Close Ture
AppObj.Quit
On Error Goto 0
'--------------
たぶん、これで行けるでしょう。
AppObj.Quit の後に、AppObj が残っているかは調べていません。
直接、GetObject でファイルを開くと、Excel.Application の終わり方が面倒です。
    • good
    • 1
この回答へのお礼

ありがとうございました。GetObject  Google検索してもこのようなものは見つからず質問した次第です、大変助かりました。

お礼日時:2019/04/20 17:45

補足です。



Excel2013 以降は、
『1つのExcelウィンドウの中に、複数の子ウィンドウで複数のファイルが表示される』、
という仕様ではなく、
『ファイルを開くたびに、常に、Excelウィンドウも個別・独立して開く』
という仕様なので、常に、前回の回答のコードで行けるか、もしかしたら、ブックを閉じるだけで「ガワ」のほうも道連れに消えるかもしれません。

そのあたりは、動きを見ながら必要に応じてコードを変えてください。
    • good
    • 1

カテゴリーが違ってますよ。

    • good
    • 0
この回答へのお礼

すみません。初めて質問をするので間違えたみたいです。

お礼日時:2019/04/20 17:45

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A