Microsoft Visual Basic コードを既に作成していると、ほとんどの場合イベント プロシージャも作成されています。"イベント プロシージャ" は、イベントが発生したときに実行されるコードを含んでいます。たとえば、ボタン付きの Visual Basic フォームには、ボタンのクリック イベントを処理するプロシージャを含めることができます。Visio アプリケーションで VBA 環境のイベントに対応するコードを作成する方法は、Microsoft Office アプリケーションなど他の VBA ホスト アプリケーションでイベントに対応するコードを作成する方法と同じです。
すべての Visio VBA プロジェクトは、プロジェクトに関連付けられている Document オブジェクト (ThisDocument) によって生成されたイベントを取得するように設定されています。他の Visio オブジェクトによって生成されたイベントに応答するために、WithEvents キーワードを使ってオブジェクト変数を宣言することができます。このキーワードは、そのオブジェクトの種類について定義されているすべてのイベントを知らせ、プロジェクトのスケルトン イベント処理プロシージャを提供します。ユーザーが行う処理は、処理するイベント コードを作成することだけです。
WithEvents オブジェクト変数はクラス モジュールの中で宣言されなければなりません。WithEvents 変数は、すべての Visio VBA プロジェクトのデフォルトのクラス モジュールである ThisDocument クラスで宣言するか、またはプロジェクトに挿入する別のクラス モジュールの中で宣言することができます。
イベントに対応するコードを作成することによって、プロジェクトに挿入したどの ActiveX コントロールによって生成されたイベントでも処理できます。ActiveX コントロールのイベントの処理の詳細については、「第 23 章 Visio ソリューションでの ActiveX コントロールの使用」を参照してください。
このセクションのすべての情報は、以下の例外を除いて、スタンドアロンの Visual Basic プロジェクトにも適用されます。Visio のタイプ ライブラリへの参照をユーザーの Visual Basic プロジェクトから設定する必要があります。これを設定するには [プロジェクト] メニューから [参照設定] を選択し、[Visio 2000 type library] を選択します。
このセクションの内容...
WithEvents キーワードによるオブジェクト変数の宣言
それぞれの Visio VBA プロジェクトには ThisDocument クラス モジュールが含まれており、プロジェクトに関連する Document オブジェクトによって生成されたイベントに自動的に対応します。
Visual Basic エディタの使い方の詳細については、「第 15 章 Visio での Microsoft VBA プログラミング」を参照してください。
ThisDocument のイベント プロシージャを作成するには
コード ウィンドウの左上隅のリスト ボックスは [オブジェクト] ボックスで、右上隅のリスト ボックスは [プロシージャ] ボックスです。
ThisDocument コード ウィンドウ
次の例は、DocumentOpened と ShapeAdded の 2 つのイベントを処理します。これらのイベントは、Square というマスタシェイプを基にした図面に追加された図形をカウントします。
'Number of squares added to drawing
Dim intSquares As Integer
Private Sub Document_DocumentOpened(ByVal Doc as IVDocument)
'Initialize number of squares added
intSquares = 0
End Sub
Private Sub Document_ShapeAdded(ByVal Shape As IVShape)
Dim mastObj As Master
'Get the Master property of the shape
Set mastObj = Shape.Master
'Check whether the shape has a master. If not, the shape was created locally
If Not ( mastObj Is Nothing ) Then
'Check whether the master is "Square"
If mastObj.Name = "Square" Then
'Increment the count for the number of squares added
intSquares = intSquares + 1
End If
End If
MsgBox "Number of squares: " & intSquares, vbInformation
End Sub
ThisDocument によって生成されたイベントを処理するには
自分のプロジェクトの図面以外の Visio オブジェクトによって生成されたイベントを処理するために、VBA のキーワード WithEvents を使って、そのイベントに関連する Visio オブジェクトのオブジェクト変数を宣言することができます。次の例は、Page オブジェクトによって生成されたイベントを処理するためにオブジェクト変数を設定する方法を示しています。
ThisDocument で WithEvents キーワードおよび Visio オブジェクトの種類を使ってオブジェクト変数を宣言します。
Dim WithEvents pageObj As Visio.Page
通常の方法でオブジェクトのプロパティやメソッドにアクセスするほかに、この宣言でキーワード WithEvents を使用すると、オブジェクト変数はその変数に割り当てられた Page オブジェクトによって生成されたイベントを処理できます。オブジェクトのイベント セットのすべてのイベントが生成されます。処理するイベントのコードを書き込むこともできます。
この WithEvents 変数を "Visio.Page" 型として宣言することによって、VBA は取得しなければならないタイプ ライブラリ (Visio) とイベント セット (Page) を知ることができます。このあと、Visual Basic エディタの [オブジェクト] ボックスで "pageObj" を選択すると、[プロシージャ] ボックスに Page オブジェクトによって生成されたイベントが表示されます。
たとえば、次のイベント プロシージャはプロジェクト (pageObj) のアクティブ ページからシェイプが削除されたときにイミディエイト ウィンドウのシェイプの名前を出力します。
Public Sub pageObj_BeforeShapeDelete (ByVal Shape As IVShape)
Debug.Print Shape.Name
End Sub
しかし、このプロシージャを実行するためには、宣言したオブジェクト (pageObj) をオブジェクトのインスタンスと結合しなければなりません。この結合は BeforeShapeDelete イベントが生成される前に行う必要がありますから、BeforeShapeDelete の前に実行されることがわかっているイベント (たとえばドキュメントの DocumentOpened イベント) のイベント プロシージャにこのステートメントを含めておきます。例を次に示します。
Private Sub Document_DocumentOpened(ByVal doc As IVDocument)
Set pageObj = ActivePage
End Sub
オブジェクト参照が完了したときに変数参照を解放することをお勧めします。これは多くの場合、BeforeDocumentClose イベント ハンドラによって行われます。例を次に示します。
Private Sub Document_BeforeDocumentClose(ByVal doc As IVDocument)
set pageObj = Nothing
End Sub
WithEvents キーワードの詳細については、Microsoft Visual Basic または VBA のマニュアルを参照してください。
ThisDocument でオブジェクト変数 WithEvents を宣言するには
ユーザーが定義したイベント変数およびイベント処理コードを含むクラスを定義することによって、特定の種類の Visio オブジェクトによって生成されるイベントの処理を簡単にすることができます。クラス モジュールの中のイベントに対応するコードを作成する方法は、ThisDocument の中のイベントに対応するコードの作成とほとんど同じです。しかし、クラス モジュールを使ってイベントを受け取る場合には、クラスのインスタンスを作成して、それを実際のオブジェクトと結合しなければなりません。(ThisDocument オブジェクトはデフォルトでインスタンス化され、プロジェクトに関連付けられている Document ドキュメントに結合されます)
イベントを別のクラス モジュールで処理するときは、クラス モジュールとプログラムのそれぞれにコードを書き込みます。
プロジェクトにクラスを追加するには、[挿入] メニューから [クラス モジュール] を選択します。このクラスには、任意の名前を割り当てることができます。このクラスにすべてのイベント処理コードを含めます。たとえば、自分のプロジェクトの中の Visio インスタンスからのイベントを処理するときには、以下の手順を実行します。この場合、ソース オブジェクトは Application オブジェクトです。
Dim WithEvents appObj As Visio.Application
Set appObj = Application
イベント ハンドラが起動していても、クラスのインスタンスを定義し作成するまでは何も起こりません。
Dim MyClass1 As MySinkClass
Set MyClass1 = New MySinkClass
クラスのインスタンスを作成すると、その Initialize イベントが生成され、WithEvents 変数が実際のオブジェクトに結合されます (前のトピックの中の手順のステップ 3 を参照)。クラスのインスタンスの作成が完了したとき、それを Nothing. に設定することによって解放します。多くの場合、プログラムの中の BeforeDocumentClose イベントによって行われます。
Set MyClass1 = Nothing
New キーワードの詳細については、Visual Basic または VBA のマニュアルを参照してください。
プロジェクトの中にイベントを受け取るには
次の例では、Visio プロジェクトは WithEvents 変数を使って Visio インスタンスに発生したイベントをモニタします。プロジェクトが実行されているとき、このイベント ハンドラは Visio インスタンスの中で開いている図面に図形が追加されたときにその図面および図形の名前を表示します。
プロジェクトは "Listener" という名前のクラスを定義します。Listener クラスで以下の処理を行います。
'Code in the Class Module named Listener
Dim WithEvents m_app As Visio.Application
Private Sub Class_Initialize()
Set m_app = Application
End Sub
Private Sub Class_Terminate()
Set m_app = Nothing
End Sub
Private Sub m_app_ShapeAdded(ByVal Shape As IVShape)
Debug.Print Shape.Document.Name; "/"; Shape.Name
End Sub
ThisDocument で以下の処理を行います。
'Code in ThisDocument
Dim m_listener As Listener
Private Sub Document_RunModeEntered(ByVal doc As IVDocument)
Set m_listener = New Listener
End Sub
Private Sub Document_DesignModeEntered(ByVal doc As IVDocument)
Set m_listener = Nothing
End Sub
Private Sub Document_BeforeDocumentClose(ByVal doc As IVDocument)
Set m_listener = Nothing
End Sub