燈明ブログ

現状は小池啓仁の応援ブログ

WithEventsキーワードとは

EXCELVBAは、当然、EXCELのイベントが拾えます。
しかし、VB6からEXCELのイベントを拾うにはどうしたらよいでしょうか…。

それには、WithEventsキーワードを使います。
ちなみに、WithEventsキーワードは、標準モジュール内では使えません。
また、Excelを使う場合は、参照設定でそのObject Libraryをチェックする。

'クラスモジュール---------------------------------------
'
'Class1:WithEventsキーワードテストサンプルクラス
'
'-------------------------------------------------------
Private WithEvents xlsApp   As Excel.Application
Private bokWork             As Excel.Workbook
Private shtSheet            As Excel.Worksheet
Private Declare Sub Sleep Lib "kernel32" (ByVal dmMilliseconds As Long)
Private intFg As Integer    '初回フラグ

Private Sub Class_Initialize()
    '
    '初期処理:インスタンス時に呼ばれる。
    '
    intFg = 0
    Set xlsApp = CreateObject("Excel.Application")
    Set bokWork = xlsApp.Workbooks.Open(App.Path & "\" & App.EXEName & ".xls")
    Set shtSheet = bokWork.Worksheets("sheet1")
    bokWork.Activate
    shtSheet.Activate
End Sub

Private Sub Class_Terminate()
    '
    '終了処理:インスタンスNoting時に呼ばれる。
    '
    xlsApp.Quit
    Set shtSheet = Nothing
    Set bokWork = Nothing
    Set xlsApp = Nothing
End Sub

Private Sub xlsApp_WorkbookOpen(ByVal Wb As Excel.Workbook)
    '
    'ブックオープン時に呼ばれる。
    '
    MsgBox "イベントキターーーーーーーーーー"
    '初回の自分の起動以外は、起動されてもクローズする。
    If (intFg <> 0) Then
      Wb.Close
    Else
      intFg = 1
    End If
End Sub

Public Sub dmy()
    '
    'ブックオープン時に呼ばれる。
    '
    Dim i As Integer

    For i = 1 To 10
        DoEvents
        shtSheet.Cells(i, 1) = i
        Sleep 1000
    Next
    bokWork.Save
End Sub
'標準モジュール-----------------------------------------
'
'WithEventsキーワードテストサンプルプログラム
'
'-------------------------------------------------------
Sub main()
    '
    'メイン処理
    '
    Dim objClass1 As Object
    
    'クラスClass1をインスタンスする。
    Set objClass1 = New Class1
    
    'dmyメソッド実行する。
    objClass1.dmy
    
    'インスタンス破棄する。
    Set objClass1 = Nothing
End Sub

処理概説

EXCELは、MDIアプリケーションです。
全く関係のない複数のブックを起動すると『同一 Excelアプリケーション内』となって、影響し合う場合があります。
そこで、影響が想定される場合は、後から起動されたブックを即座にクローズさせれば、影響回避ができるわけです。

上記の処理は、自ブックのシートのセルにデータを格納します。
格納中に自ブック以外がオープンされた場合、WorkbookOpenイベントを拾って、即座にそれをクローズさせます。


また、上記のイベント取得はEXCELウィンドウ内ですが、ブック内、シート内のイベントを拾うには以下のようにWithEventsキーワードを指定します。

Private WithEvents bokWork   As Excel.Workbook
Private WithEvents shtSheet  As Excel.Worksheet