前のトピック     次のトピック

第 21 章 VISIO のイベントの処理

セクション 2   イベントに対応するコードの作成

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 コントロールの使用」を参照してください。


WithEvents キーワードによるイベントに対応するコードの作成は、VBA および Visual Basic でだけ利用できる機能です。それ以外の環境でプログラミングを行う場合は、「セクション 3   Visio の Event オブジェクト」を参照するか、または COM (Component Object Model) のマニュアルで COM の接続可能なオブジェクトをサポートするインターフェースに関する説明を参照してください。

このセクションのすべての情報は、以下の例外を除いて、スタンドアロンの Visual Basic プロジェクトにも適用されます。Visio のタイプ ライブラリへの参照をユーザーの Visual Basic プロジェクトから設定する必要があります。これを設定するには [プロジェクト] メニューから [参照設定] を選択し、[Visio 2000 type library] を選択します。


このセクションの内容...

ThisDocument によって生成されたイベントの処理

WithEvents キーワードによるオブジェクト変数の宣言

イベントを受け取るクラスの定義

イベントに対応するクラス モジュール : 例

ThisDocument によって生成されたイベントの処理

それぞれの Visio VBA プロジェクトには ThisDocument クラス モジュールが含まれており、プロジェクトに関連する Document オブジェクトによって生成されたイベントに自動的に対応します。

Visual Basic エディタの使い方の詳細については、「第 15 章 Visio での Microsoft VBA プログラミング」を参照してください。

ThisDocument のイベント プロシージャを作成するには

  1. プロジェクト エクスプローラで [ThisDocument] をダブルクリックします。図面のコード ウィンドウが開きます。(Visual Basic エディタにプロジェクト エクスプローラが表示されていない場合は、[表示] メニューから [プロジェクト エクスプローラ] を選択します。)
  2. コード ウィンドウの左上隅のリスト ボックスは [オブジェクト] ボックスで、右上隅のリスト ボックスは [プロシージャ] ボックスです。

  3. [オブジェクト] ボックスで [図面] をクリックします。[プロシージャ] ボックスに Document オブジェクトのイベント セットが表示されます。
  4. [プロシージャ] ボックスでイベントを選択します。VBA は空のイベント プロシージャを作成します。そこにイベントを処理するためのコードを書き込むことができます。イベント プロシージャは常に “object_event" という名前です。

 



ThisDocument コード ウィンドウ

  1. [オブジェクト] ボックス
  2. スケルトン プロシージャ
  3. [プロシージャ] ボックス

次の例は、DocumentOpenedShapeAdded の 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 によって生成されたイベントを処理するには

  1. [開発者用] ツールバーの [Visual Basic エディタ] ボタン () をクリックして Visual Basic エディタを起動します。または、[ツール] メニューから [マクロ] をポイントして [Visual Basic エディタ] を選択します。
  2. [プロジェクト エクスプローラ] で ThisDocument をダブルクリックして、コード ウィンドウを開きます。
  3. [オブジェクト] ボックスで [Document] を選択します。図面によって生成されたイベントが [プロシージャ] ボックスに表示されます。
  4. 処理するイベントを選択します。Visio アプリケーションはそのイベントのための空のイベント プロシージャを作成します。
  5. イベント プロシージャに、イベントが発生したときに実行するコードを書き込みます。

TOP へ

WithEvents キーワードによるオブジェクト変数の宣言

自分のプロジェクトの図面以外の 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 を宣言するには

  1. Visual Basic エディタを起動し、[プロジェクト エクスプローラ] で ThisDocument オブジェクトをダブルクリックします。
  2. コード ウィンドウの中のモジュールの [General] セクションで Visual Basic キーワード WithEvents を使ってオブジェクト変数を定義します。
  3. [オブジェクト] ボックスからオブジェクトを選択します。そのオブジェクトによって生成されるイベントが [プロシージャ] ボックスに表示されます。
  4. 処理するイベントを選択します。Visio アプリケーションはそのイベントのための空のイベント プロシージャを作成します。
  5. イベント プロシージャに、イベントが発生したときに実行するコードを書き込みます。
  6. オブジェクト変数をオブジェクトのインスタンスと同じに設定します。
  7. 完了したとき、変数を Nothing に設定します。

TOP へ

イベントを受け取るクラスの定義

ユーザーが定義したイベント変数およびイベント処理コードを含むクラスを定義することによって、特定の種類の Visio オブジェクトによって生成されるイベントの処理を簡単にすることができます。クラス モジュールの中のイベントに対応するコードを作成する方法は、ThisDocument の中のイベントに対応するコードの作成とほとんど同じです。しかし、クラス モジュールを使ってイベントを受け取る場合には、クラスのインスタンスを作成して、それを実際のオブジェクトと結合しなければなりません。(ThisDocument オブジェクトはデフォルトでインスタンス化され、プロジェクトに関連付けられている Document ドキュメントに結合されます)

イベントを別のクラス モジュールで処理するときは、クラス モジュールとプログラムのそれぞれにコードを書き込みます。

クラス モジュールのコード

プロジェクトにクラスを追加するには、[挿入] メニューから [クラス モジュール] を選択します。このクラスには、任意の名前を割り当てることができます。このクラスにすべてのイベント処理コードを含めます。たとえば、自分のプロジェクトの中の Visio インスタンスからのイベントを処理するときには、以下の手順を実行します。この場合、ソース オブジェクトは Application オブジェクトです。

  1. クラス モジュールで、次のステートメントを使ってモジュール レベルの WithEvents 変数を宣言します。
  2. Dim WithEvents appObj As Visio.Application

  3. この変数を宣言すると、クラス モジュールの [オブジェクト] ボックスに "appObj" が表示され、それを選択したときそのオブジェクトの有効なイベントが [プロシージャ] ボックスに表示されます。[プロシージャ] ボックスからイベントを選択します。クラス モジュールに空のプロシージャが追加されます。そこに選択したイベントに対応するコードを書き込むことができます。たとえば、ユーザーのソリューションは、図面の中の NoEventsPending イベントが生成されたときに処理する図形に関する情報を収集することができます。
  4. WithEvents 変数を実際のソース オブジェクトに関連付けなければなりません。ソース オブジェクトと WithEvents 変数を結合するには、Set ステートメントを使用します。WithEvents 変数は多くの場合、クラス モジュールの Initialize プロシージャの中で割り当てられ、モジュールの Terminate イベントでNothing に設定されます。
  5. Set appObj = Application

プログラムのコード

イベント ハンドラが起動していても、クラスのインスタンスを定義し作成するまでは何も起こりません。

  1. 次の宣言を使って (通常はモジュール レベルで) クラスの参照を追加します。
  2. Dim MyClass1 As MySinkClass

  3. クラスのインスタンスを作成します。たとえば、前のトピックで説明したように Application オブジェクトによって生成されたイベントに対応するために、図面のDocumentOpened イベントの中にクラス モジュールのインスタンスを作成することができます。クラス モジュールのインスタンスを作成するには、New キーワードを使用します。
  4. Set MyClass1 = New MySinkClass

    クラスのインスタンスを作成すると、その Initialize イベントが生成され、WithEvents 変数が実際のオブジェクトに結合されます (前のトピックの中の手順のステップ 3 を参照)。クラスのインスタンスの作成が完了したとき、それを Nothing. に設定することによって解放します。多くの場合、プログラムの中の BeforeDocumentClose イベントによって行われます。

    Set MyClass1 = Nothing

    New キーワードの詳細については、Visual Basic または VBA のマニュアルを参照してください。

プロジェクトの中にイベントを受け取るには

  1. プロジェクトにクラス モジュールを挿入します。
  2. クラス モジュールで WithEvents キーワードを使ってモジュール レベルのオブジェクト変数を宣言します。
  3. クラス モジュールで、[オブジェクト] ボックスからオブジェクト変数を選択します。その変数によって処理できるイベントが [プロシージャ] ボックスに表示されます。
  4. 処理したいイベントを選択し、スケルトン プロシージャにコードを提供します。
  5. プログラムの中にクラス モジュールのインスタンスを作成します。
  6. WithEvents 変数を、受け取るイベントのソース オブジェクトに設定します。

TOP へ

イベントに対応するクラス モジュール : 例

次の例では、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

Top