さまざまなタイプの60以上のコントロールを備えたWordユーザーフォームがあります。 control_changeイベントがトリガーされるたびにフォームを評価し、フォームの送信ボタンの有効状態を変更したいと思います。ただし、変更イベントハンドラーで60を記述して維持したくはありません。
特定のタイプのすべてのコントロールのイベント処理コードを含むイベントシンククラスを作成できます。
たとえば、次のようにTextBoxEventHandler
というクラスを作成します。
Private WithEvents m_oTextBox as TextBox
Public Property Set TextBox(ByVal oTextBox as TextBox)
Set m_oTextBox = oTextBox
End Property
Private Sub m_oTextBox_Change()
' Do something
End Sub
次に、フォーム上の適切なタイプのコントロールごとに、そのクラスのインスタンスを作成して接続する必要があります。
Private m_oCollectionOfEventHandlers As Collection
Private Sub UserForm_Initialise()
Set m_oCollectionOfEventHandlers = New Collection
Dim oControl As Control
For Each oControl In Me.Controls
If TypeName(oControl) = "TextBox" Then
Dim oEventHandler As TextBoxEventHandler
Set oEventHandler = New TextBoxEventHandler
Set oEventHandler.TextBox = oControl
m_oCollectionOfEventHandlers.Add oEventHandler
End If
Next oControl
End Sub
イベントハンドラインスタンスをコレクションに追加する必要がある理由は、それらが参照されたままになり、終了する前にガベージコレクタによって破棄されないようにするためです。
明らかに、この手法を拡張して、他のタイプの制御を処理することができます。タイプごとに個別のイベントハンドラークラスを使用することも、処理する必要のあるコントロールタイプごとにメンバー変数(および関連するプロパティとイベントハンドラー)を持つ単一のクラスを使用することもできます。
その場合、イベントハンドラーはVBA/VB6で共有できないため、オプションはほとんどありません。
オプション1:すべてのイベントハンドラーから呼び出される中央処理関数を使用します。
Sub Control1_ChangeEvent()
CommonChangeEvent // Just call the common handler, parameters as needed
End Sub
Sub Control2_ChangeEvent()
CommonChangeEvent
End Sub
...
Sub CommonChangeEvent(/* Add necessary parameters */)
//Do the heavy lifting here
End Sub
オプション2:コントロールをコントロール配列に整理します。
Sub TextBox_ChangeEvent(Index As Integer)
CommonChangeEvent
End Sub
Sub OtherControlType_ChangeEvent(Index As Integer)
CommonChangeEvent
End Sub
両方のオプションを組み合わせると、イベントハンドラーの総数が大幅に減少し、残りのハンドラーは1つの真のイベントハンドラーの頭の悪いスタブになります。