- ベストアンサー
VBAで複数のブックを同時に制御する方法について
- VBAを使用して複数のExcelブックを制御する方法について質問です。
- 具体的には、BookAからコマンドボタンを押してBookBを開き、BookAを閉じると同時にユーザーフォームが表示されるようにしたいです。
- しかし、現在のコードではユーザーフォームが表示されず、処理が終了してしまいます。ヒントや解決策をお知りの方は教えてください。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
ANo2の方が書いておられるように、 呼び出し元を終了したら呼び出し先も終了されてしまいます。 (呼び出し元の終了処理で呼び出し先も終了させないと呼び出し先のプロセスだけ残ってしまい 行き場を失うためだろうと思っています。昔、別件で現象は確認済。) Workbooks.Open (mypath & "BookB.xlsm")を使う限りはタブン無理。 別のプロセスで実行できるといいのだけれど、EXCEL2003で見た限りではそんなパラメタはなさそう。 (私が知らないだけかも。) とりあえず、できそうなのは Workbooks.Open (mypath & "BookB.xlsm") のかわりに、 Shell ("c:\Program Files\Microsoft Office\Office11\excel " & mypath & "BookB.xlsm") を使うとできそうに思う。 但し、 Workbooks("BookA.xlsm").Close は、BookBのOPENイベントではエラーになるはずなので、 BookAのコマンドボタンのEnd Sub の直前に置くこと。 c:\Program Files\Microsoft Office\Office11\excel は、たぶん、EXCELのバージョンによって変わります。 また、インストール時にデフォルト以外を指定したら、その指定したフォルダに変わります。 ## 未検証。(EXCELが起動できることだけは検証しましたが。)
その他の回答 (6)
- end-u
- ベストアンサー率79% (496/625)
OnTimeメソッドを使ってOpenイベント終了後あらためて 別プロシージャで実行すれば良いです。 'BookB.xlsm ThisWorkbookModule Option Explicit Private Sub Workbook_Open() Application.OnTime Now, ThisWorkbook.CodeName & ".try" Workbooks("BookA.xlsm").Close End Sub Private Sub try() test.Show End Sub CodeNameを変更してなければ 『ThisWorkbook.CodeName & ".try"』は『"ThisWorkbook.try"』でも良いです。
お礼
大変遅くなりました。 現在、他の業務に追われてまだ試せていませんが、 落ち着き次第試してみたいと思います。 OnTimeは以前別な処理で一度試してみましたが、 使い方が難しく挫折しました。 今回は腰を据えて勉強していきたいと思います。
- TAKA_R
- ベストアンサー率32% (26/79)
初心者で本末転倒な質問をして悪いのですが、どうしても閉じないといけないのでしょうか? もしユーザーから見えなくなればそれでよいなら、ブックの非表示というのもありだと思います。 フォームの出る前にブックを非表示にして、スクリーンアップデータをfalseして、フォーム出して、ブックを表示して、ブックを閉じて、スクリーンアップデータをtrueにする。 (ちょっと無駄に作業が多いですけど) まあ、タスクバーにギリギリまで表示されるのが難点ですが・・・。
お礼
ありがとうございます。 職場の共有サーバーを利用して、複数部署での作業を可能にするための方法として、 BookA→作業用ブックの入り口用ブックで部署を選択する BookB→同じコードのブックが複数個あり、ここで作業をする そのため、BookAを完全に閉じないと読み取り専用の通知が表示されて、 これを見てエラーだと勘違いしてしまう方が多数出てくるため、 BookAを完全に閉じたいと思っています。 別な方法を考えてみます。
- ki-aaa
- ベストアンサー率49% (105/213)
こんにちわ ユーザーフォームをモードレスで表示してもいいなら No3さんの回答でいいのでは。 test.Show → test.Show vbModeless
お礼
ありがとうございます。 モードレス表示も試してみましたが、Closeするとユーザーフォームまでが消えてしまい(非表示されて)、ワークシートだけが残ってしまいます。そのため、再表示させるのに Showを付け加えても、そこが処理されませんでした。
- watabe007
- ベストアンサー率62% (476/760)
すみません、内容が把握できていないのですが >BooKAからコマンドボタンを利用してBookBを開く。 >BookBは開くとBookAを閉じる。testのユーザーフォームを開く。 これから、推測すると、こんなことかな '--BookAのコマンドボタンのコード--- Private Sub CommandButton1_Click() Dim mypath As String Unload Me mypath = ThisWorkbook.Path Workbooks.Open (mypath & "\BookB.xlsm") ThisWorkbook.Close False End Sub '--BookBのThisWorkbookモジュール--- Private Sub Workbook_Open() test.Show End Sub
お礼
先ほどのご指摘も含めてありがとうございます。 説明不足で申し訳ありません。 BookAのCloseはユーザーフォームの展開の前、つまりユーザーフォームで作業している時には閉じるようにしたいのです。 確かにこのコードでユーザーフォームを展開することは可能ですが、 BookBが開き、ユーザーフォームが開いてユーザーフォームを閉じてから BookAを閉じる処理がされてしまうのです。 もう少し試行錯誤してみます。
- osamuy
- ベストアンサー率42% (1231/2878)
BookAのコマンドボタンのコードに Private Sub CommandButton1_Click() Dim mypath As String mypath = ThisWorkbook.Path Workbooks.Open (mypath & "\BookB.xlsm") msgbox "END A" End Sub BookBのOPENイベントに Private Sub Workbook_Open() msgbox "END B" End Sub ――と書いたものを実行すると、「END B」が表示されてから「END A」が表示されると思います。 そこから考えるに、ブックBのWorkbook_OpenはブックAのCommandButton1_Clickの流れで処理されていて、 ・ブックAをクローズする→CommandButton1_Clickの処理中止が必要 →CommandButton1_Click処理中止→Workbook_Openの処理中止が必要 ――となって、Workbooks().Closeの処理完了とともに、マクロ実行が完了しているとか。
お礼
なるほど! 確かにそんな処理がされているかも知れません。 でも、そこからの解決方法が思い付かないので、もうちょっと試行錯誤してみます。
- watabe007
- ベストアンサー率62% (476/760)
>mypath = ThisWorkbook.Path >Workbooks.Open (mypath & "BookB.xlsm") まず、これでBookB.xlsmが開くか、標準モジュールで確認してみては? 普通は、Workbooks.Open (mypath & "\BookB.xlsm") "\"が要るのでは
補足
すいません。転記ミスです "/"ではなく"\"を入れています。 こちらは正常に作動します。 当然、CloseとShowもそれぞれでは作動します。 Closeの後に入った時のShowだけが処理されません
補足
ありがとうございます。 Excelブックは"Shell"でも開くことができるのですね。 勉強になりました。 職場の共有サーバーでの作業ですので(このため、入り口であるBookAを確実に閉じたかったのですが…) Excelのフォルダの場所などはSEに聞いてみます。 また、ワンクリックでユーザーフォームを展開しないで かつユーザーにストレスを感じさせないような方法を検討していきます。 別な方法もあるかも知れないという淡い期待のもと、 解決方法が決定するまで、 この質問は継続させて下さい。