[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『他のブックの変数を制御』(田吾作)
こんにちは、よろしくお願いいたします。
ブックやアプリケーションの閉じるボタン(×)ではなく、ユーザーフォームの コマンドボタンクリックでブックを閉じるようにしています。
ブック起動時に変数をFalseにし、×ボタンをクリックしても閉じなく、 コマンドボタンをクリックすることによって変数をTrueにし、変数がTrue だったら閉じるようにしています。
−−−−−−−−−−−−−−− '標準モジュール Public clsflg As Boolean
Sub cls() ThisWorkbook.Saved = True If Workbooks.Count = 1 Then Application.Quit Else ThisWorkbook.Close End If End Sub
'ThisWorkbookモジュール Private Sub Workbook_Open() clsflg = False UserForm1.Show 0 End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean) If clsflg = True Then Call cls Else Cancel = True End If End Sub
'ユーザーフォーム Private Sub CommandButton1_Click() clsflg = True Call cls End Sub −−−−−−−−−−−−−−−
これは問題なく動いています。
ただ、これだと、開いているブックを他のブックから閉じようとするときに 逆に邪魔になってしまいます。 他のブックは閉じますが、上記のコードを記述してあるブックは閉じずに 残ってしまいます。
たとえば、下記のようなコードで開いているブックを閉じるような場合です。
−−−−−−−−−−−−−−− Sub wbcls() Dim mypath As String Dim wb As Workbook mypath = ThisWorkbook.FullName For Each wb In Workbooks If wb.FullName <> mypath Then If wb.Saved = True Then wb.Close End If Next wb End Sub −−−−−−−−−−−−−−−
他のブックから、閉じたいブックの変数「clsflg」をTrueにする、という 操作ができたらブックを閉じることができるように思うのですが、他の ブックの変数を操作する、という方法がわかりません。
全然別のアプローチでもいいのでご教示いただきましたら幸甚です。 よろしくお願いいたします。
< 使用 Excel:Excel2007、使用 OS:WindowsVista >
変数でのハンドリングは、いろいろやっかいなことになるかもしれません。 該当のブックの変数を取得する方法はいくつかありますが、 Sub wbcls() で抽出されたブックが、すべて そのように変数を返す構成になっているか、ただのブックで、そんなことは不要のブックなのかの判断も必要になりますね。 そういった構成になっていないブックに対して変数を取得しようとすると、不都合というかエラーになると思いますし。
1つの方法としては、現在、変数で閉じていいかどうかを制御していることをすべてやめて、 Workbook_Openで。このブックのXボタンそのものを無効にしておく。そうすると、操作者がXボタンをクリックすること、そのものができなくなりますので。
'閉じるボタンの無効化 Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
Const MF_BYCOMMAND = &H0& Const SC_CLOSE = &HF060
Private Sub Workbook_Open() Dim hWnd As Long Dim rtn As Long
hWnd = Application.hWnd rtn = GetSystemMenu(hWnd, 0) rtn = RemoveMenu(rtn, SC_CLOSE, MF_BYCOMMAND) ' 閉じるボタンの無効化
End Sub
なお、以下のようなレスキューコードを標準モジュールに書いておくといいかも。
Sub TestClose() ThisWorkbook.Close True End Sub
(β) 2015/04/15(水) 09:07
標準モジュールではなく、ThisWorkbookモジュールに当該変数を設置して見ては?
Thisworkbookのモジュールに
public clspermit as boolean
とすれば、
別ブックからでも Workbooks("対象ブック").clspermit=true このような指定ができます。
標準モジュールにPublic変数は 置かなくてもプログラムは作れます。 いえ、その方がよいです。
(ichinose) 2015/04/15(水) 13:31
当該ブック内に、フラグをFalseにするサブプロシージャを記述して
他ブックから、そのプロシージャをapplication.runで呼び出すのはどうでしょう。
( 佳 ) 2015/04/15(水) 19:43
βさん、ichinoseさん、佳さん、ご回答ありがとうございます。 御三方の方法を試してみました。いずれもうまくいきました。
コードは下記のとおりです。 ※βさんの方法はご教示いただきましたコードをそのまま実行 しました。
最終的にどのようにするかはいろいろ勘案してみます。 ありがとうございました。
閉じる対象のブック
'ThisWorkbookモジュール
Public clsflg As Boolean
Private Sub Workbook_Open() clsflg = False UserForm1.Show 0 End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean) If clsflg = True Then Call cls Else Cancel = True End If End Sub
'標準モジュール
Sub cls() Application.WindowState = xlNormal ThisWorkbook.Saved = True If Workbooks.Count = 1 Then Application.Quit Else ThisWorkbook.Close End If End Sub
Sub flgtrue() ThisWorkbook.clsflg = True End Sub
マクロ実行ブック
'ichinoseさんご教示の方法 Sub wbclsA() Dim mypath As String Dim wb As Workbook mypath = ThisWorkbook.FullName For Each wb In Workbooks If wb.FullName <> mypath Then If wb.Saved = True Then Err.Clear On Error Resume Next wb.clsflg = True wb.Close On Error GoTo 0 End If End If Next wb End Sub
'佳さんご教示の方法 Sub wbclsB() Dim mypath As String Dim wb As Workbook mypath = ThisWorkbook.FullName For Each wb In Workbooks If wb.FullName <> mypath Then Application.Run wb.Name & "!flgtrue" If wb.Saved = True Then wb.Close End If Next wb End Sub (田吾作) 2015/04/16(木) 00:41
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.