第 23 章 Visio ソリューションでのActiveX コントロールの使用
ActiveX コントロールが Visio® 図形と連携して動作する方法を理解するには、次の図に示すコントロールと図形の例を見てください。コントロールには、図面上の図形の名前を選択するためのコンボ ボックスがあります。また、選択された図形のテキスト、特定のカスタム プロパティを表示するテキスト ボックス、選択された図形を新しい値で更新するためのコマンド ボタンがあります。この図面では、ぺージ上のすべてのプロセス フローチャート図形の合計費用と合計期間が維持され、図形が追加、削除、変更された場合には合計が更新されます。
ActiveX コントロールと図形が連動する図面
次のコード例は、ComboBox1_Change イベント ハンドラを示します。このハンドラは図面の図形を選択し、ユーザーによりコンボ ボックス一覧の図形名が選択されると、テキスト ボックスにカスタム プロパティを表示します。
Private Sub ComboBox1_Change()
'The user has clicked on an item in the list box
Dim strName As String
On Error GoTo Ignore:
If (bInComboBoxChanged) Then
'Exit without doing anything; already responding to the initial Change event
Exit Sub
End If
'Set flag indicating the program is in the Change routine.If an error occurs
'after this, it skips to the Ignore label, after which the flag is reset.
bInComboBoxChanged = True
'Calling DeselectAll and Select on the Window object set ComboBox1.Text
'(see theWindow_SelectionChanged).Save the current text before calling
'DeselectAll, so that we know which shape to select.
strName = ComboBox1.Text
'Select the item and get its properties
ActiveWindow.DeselectAll
ActiveWindow.Select ActivePage.Shapes(strName), visSelect
With ActivePage.Shapes(strName)
TextBox1.Text = .Text
TextBox2.Text = Format(.Cells("prop.cost").ResultIU, "Currency")
TextBox3.Text = Format(.Cells("prop.duration").Result(visElapsedMin), _
"###0 min.")
End With
Exit Sub
Ignore:
'Set flag indicating the program is NOT in the Change handler any more
bInComboBoxChanged = False
End Sub
このハンドラは次の処理を行います。
グローバル変数の bInComboBoxChanged は、ComboBox1_Change ハンドラが初めて呼び出されたかどうかを示します。選択を解除し、図形を選択すると、Window_SelectionChanged イベントが発生します。ただし、この例のイベント ハンドラでは、ComboBox1.Text プロパティを設定し、これにより ComboBox1_Change イベントが発生され、その結果 ComboBox1_Change ハンドラが再実行されます。ハンドラは、初回実行されるときに bInComboBoxChanged に True を設定するので、二回目は選択処理がスキップされ、プログラムの再帰的なループを防止することができます。
ループを防止する別の方法として、Application オブジェクトの EventsEnabled プロパティを False に設定する方法もあります。これにより、ハンドラが処理を実行している間は、イベントの発生を無効にすることができます。ハンドラの処理中にイベントが発生すると、ハンドラは適切に動作しません。ただし、この方法はお勧めできません。この方法では、Visio のインスタンスのすべてのイベントが無効になり、ユーザーのシステムで実行されている他のソリューションに影響を与える可能性があるからです。特に、そのイベント ハンドラが含まれるソリューションでエラーが発生すると、イベントを再度有効にできなくなり、他のソリューションまで続行できなくなります。Visio イベントを処理するソリューションが他にも存在する場合を考慮して、前のコード例のようにグローバル変数を利用して処理を行うことをお勧めします。