Excel VBAでフォームアプリケーションを作る土台(2)
前回の記事で作成したエクセルVBAアプリケーションに、他のBookを開いた際の表示を考慮した改造を加えていきます。
前回作成分は、単にApplication.Visible = Falseにするだけなので直感的にわかりやすかったと思いますが、今回はややトリッキーな内容かもしれません。
前回作成分は、単にApplication.Visible = Falseにするだけなので直感的にわかりやすかったと思いますが、今回はややトリッキーな内容かもしれません。
まず
「あとから他のBookを開くと、最初に非表示にしてたBookのシートまで見えてしまう」
という問題の解決は、非常に簡単です。
いったんBookを表示状態にして、メニューで「ウィンドウ」→「表示しない」をクリックして、その状態でいったん保存すればよいのです。

これで、あとから他のBookを開くことでエクセルが表示状態になってしまっても、フォームと結びついたシートは表示されません。
さて、問題はその逆です。
先に他のBookが開いている状態でこのBookを起動し、フォームだけを表示して、かつ先に開いていたBookは表示されたままにするには、どのような挙動が必要か?
1.起動処理で、他のBookが開いていなければエクセルそのものを非表示にする。
2.起動処理で、他のBookが開いていた場合は、エクセルを非表示にしない。
3.終了処理で、他のBookが開いていなければエクセルそのものを終了する。
4.終了処理で、他のBookが開いていた場合は、このBookだけを閉じる。
1.から4.の、どの処理においても「他のBookが開いているかどうかの判定」が必要です。
ここで、最初にメニューで「ウィンドウ」→「表示しない」にしていたことが生きてきます。
この状態ならば、ActiveWorkbookで取得した情報は、常に他のBookの情報になるはずです!
On Error Resume Nextとすることで、他のBookが開いていればその名前が変数に格納され、他のBookが開いていなければ変数には空白文字が格納されます。
あとは、変数に空白文字が格納されていた場合だけ、Application.Visible = Falseにすればよいのです。
これで、1.と2.の要件が満たされました。
終了処理でも、似たようなことをします。
変数に空白文字が格納されていた場合にはエクセルそのものを終了させ、変数に他のBookの名前が格納されていた場合には、ThisWorkbook.CloseでこのBookだけを閉じます。
これで、3.と4.の要件が満たされました。
こうして、あたかも他のエクセルファイルとは独立してフォームアプリケーションが表示されているように見せかけるエクセルVBAアプリケーションが作成できます。

「あとから他のBookを開くと、最初に非表示にしてたBookのシートまで見えてしまう」
という問題の解決は、非常に簡単です。
いったんBookを表示状態にして、メニューで「ウィンドウ」→「表示しない」をクリックして、その状態でいったん保存すればよいのです。
これで、あとから他のBookを開くことでエクセルが表示状態になってしまっても、フォームと結びついたシートは表示されません。
さて、問題はその逆です。
先に他のBookが開いている状態でこのBookを起動し、フォームだけを表示して、かつ先に開いていたBookは表示されたままにするには、どのような挙動が必要か?
1.起動処理で、他のBookが開いていなければエクセルそのものを非表示にする。
2.起動処理で、他のBookが開いていた場合は、エクセルを非表示にしない。
3.終了処理で、他のBookが開いていなければエクセルそのものを終了する。
4.終了処理で、他のBookが開いていた場合は、このBookだけを閉じる。
1.から4.の、どの処理においても「他のBookが開いているかどうかの判定」が必要です。
ここで、最初にメニューで「ウィンドウ」→「表示しない」にしていたことが生きてきます。
この状態ならば、ActiveWorkbookで取得した情報は、常に他のBookの情報になるはずです!
Private Sub Workbook_Open() Dim bookName as String Load UserForm1 UserForm1.Show vbModeless On Error Resume Next bookName = ActiveWorkbook.Name If bookName = "" Then Application.Visible = False End SubWorkbook_Openに赤字の部分を追加しました。他のBookが開いていない状態でこのBookのActiveWorkbook.Nameを求めようとすると、「ウィンドウ」→「表示しない」にしていたことにより、エラーとなってしまいます。
On Error Resume Nextとすることで、他のBookが開いていればその名前が変数に格納され、他のBookが開いていなければ変数には空白文字が格納されます。
あとは、変数に空白文字が格納されていた場合だけ、Application.Visible = Falseにすればよいのです。
これで、1.と2.の要件が満たされました。
終了処理でも、似たようなことをします。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) Dim bookName As String Me.Hide Unload Me On Error Resume Next bookName = ActiveWorkbook.Name If bookName = "" Then Application.Quit Else ThisWorkbook.Close End If End Sub
変数に空白文字が格納されていた場合にはエクセルそのものを終了させ、変数に他のBookの名前が格納されていた場合には、ThisWorkbook.CloseでこのBookだけを閉じます。
これで、3.と4.の要件が満たされました。
こうして、あたかも他のエクセルファイルとは独立してフォームアプリケーションが表示されているように見せかけるエクセルVBAアプリケーションが作成できます。
- 関連記事
- サーブレットでcookie(日本語のURLエンコード)
- Visual StudioなしでC#コンソールアプリケーションを開発
- Excel VBAでフォームアプリケーションを作る土台(2)
- Excel VBAでフォームアプリケーションを作る土台(1)
- Perlを使った超シンプルなゲストブック