こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

EXCELのVBAについての質問です

現在、2つのブックでVBAを使用して作業中ですが、
どうしてもうまく作動しない箇所があります。
BookAとBookBがあり、BookBにはtesというユーザーフォームを設置しています。


やりたい作業は以下の通りです。
BooKAからコマンドボタンを利用してBookBを開く。
BookBは開くとBookAを閉じる。testのユーザーフォームを開く。


BookAのコマンドボタンのコードは

Private Sub CommandButton1_Click()
Dim mypath As String
mypath = ThisWorkbook.Path
Workbooks.Open (mypath & "BookB.xlsm")
End Sub

BookBのOPENイベントに

Private Sub Workbook_Open()
Workbooks("BookA.xlsm").Close
test.Show
End Sub

を入力しています。

これを実行すると
エラーが発生せず、デバッグで1行ずつコードを確認すると
test.Showが実行されずに
closeで処理が終了されています。


・ユーザーフォームのActiveイベントでclose処理を入れるとcloseが処理されずに
モードレスでフォームを開くと、close後にフォームが閉じられてしまいます。
・クッション用のブックを作成して、そこにBookAをclose処理とBooKBのOPEN処理を入れても
closeで処理が終了されてしまいます。

エラーが出ると対応の使用があるのですが、エラーも無く静かに処理だけが終了してしまうため、
対応ができず困っています。

あちこち検索して調べてみましたが、いずれも当てはまらない状況です。

何かヒント等でもお持ちの方は、ご教授下さい。

投稿日時 - 2012-05-13 17:09:33

QNo.7473642

困ってます

質問者が選んだベストアンサー

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が起動できることだけは検証しましたが。)

投稿日時 - 2012-05-13 22:00:37

補足

ありがとうございます。
Excelブックは"Shell"でも開くことができるのですね。
勉強になりました。

職場の共有サーバーでの作業ですので(このため、入り口であるBookAを確実に閉じたかったのですが…)
Excelのフォルダの場所などはSEに聞いてみます。


また、ワンクリックでユーザーフォームを展開しないで
かつユーザーにストレスを感じさせないような方法を検討していきます。


別な方法もあるかも知れないという淡い期待のもと、
解決方法が決定するまで、
この質問は継続させて下さい。

投稿日時 - 2012-05-13 22:34:24

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

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"』でも良いです。

投稿日時 - 2012-05-15 21:07:24

お礼

大変遅くなりました。
現在、他の業務に追われてまだ試せていませんが、
落ち着き次第試してみたいと思います。
OnTimeは以前別な処理で一度試してみましたが、
使い方が難しく挫折しました。

今回は腰を据えて勉強していきたいと思います。

投稿日時 - 2012-05-20 21:15:02

ANo.6

初心者で本末転倒な質問をして悪いのですが、どうしても閉じないといけないのでしょうか?

もしユーザーから見えなくなればそれでよいなら、ブックの非表示というのもありだと思います。
フォームの出る前にブックを非表示にして、スクリーンアップデータをfalseして、フォーム出して、ブックを表示して、ブックを閉じて、スクリーンアップデータをtrueにする。
(ちょっと無駄に作業が多いですけど)
まあ、タスクバーにギリギリまで表示されるのが難点ですが・・・。

投稿日時 - 2012-05-14 18:12:35

お礼

ありがとうございます。

職場の共有サーバーを利用して、複数部署での作業を可能にするための方法として、
BookA→作業用ブックの入り口用ブックで部署を選択する
BookB→同じコードのブックが複数個あり、ここで作業をする

そのため、BookAを完全に閉じないと読み取り専用の通知が表示されて、
これを見てエラーだと勘違いしてしまう方が多数出てくるため、
BookAを完全に閉じたいと思っています。


別な方法を考えてみます。

投稿日時 - 2012-05-14 18:51:51

ANo.5

こんにちわ

ユーザーフォームをモードレスで表示してもいいなら
No3さんの回答でいいのでは。

test.Show → test.Show vbModeless

投稿日時 - 2012-05-14 15:36:29

お礼

ありがとうございます。
モードレス表示も試してみましたが、Closeするとユーザーフォームまでが消えてしまい(非表示されて)、ワークシートだけが残ってしまいます。そのため、再表示させるのに
Showを付け加えても、そこが処理されませんでした。

投稿日時 - 2012-05-14 18:41:10

ANo.3

すみません、内容が把握できていないのですが
>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

投稿日時 - 2012-05-13 21:48:30

お礼

先ほどのご指摘も含めてありがとうございます。
説明不足で申し訳ありません。
BookAのCloseはユーザーフォームの展開の前、つまりユーザーフォームで作業している時には閉じるようにしたいのです。


確かにこのコードでユーザーフォームを展開することは可能ですが、
BookBが開き、ユーザーフォームが開いてユーザーフォームを閉じてから
BookAを閉じる処理がされてしまうのです。

もう少し試行錯誤してみます。

投稿日時 - 2012-05-13 22:21:40

ANo.2

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の処理完了とともに、マクロ実行が完了しているとか。

投稿日時 - 2012-05-13 21:21:44

お礼

なるほど!
確かにそんな処理がされているかも知れません。

でも、そこからの解決方法が思い付かないので、もうちょっと試行錯誤してみます。

投稿日時 - 2012-05-13 22:09:20

ANo.1

>mypath = ThisWorkbook.Path
>Workbooks.Open (mypath & "BookB.xlsm")

まず、これでBookB.xlsmが開くか、標準モジュールで確認してみては?
普通は、Workbooks.Open (mypath & "\BookB.xlsm")
"\"が要るのでは

投稿日時 - 2012-05-13 19:22:52

補足

すいません。転記ミスです
"/"ではなく"\"を入れています。

こちらは正常に作動します。
当然、CloseとShowもそれぞれでは作動します。
Closeの後に入った時のShowだけが処理されません

投稿日時 - 2012-05-13 20:31:19

あなたにオススメの質問