VBA: utilizzo di WithEvents in UserForms

Ho un userform di Word con oltre 60 controlli di vari tipi. Vorrei valutare il modulo ogni volta che viene triggersto un evento control_change e modificare lo stato abilitato del pulsante di invio del modulo. Tuttavia, non voglio davvero scrivere e mantenere 60 sui gestori di eventi di cambiamento.

È ansible creare una class di sink di eventi che conterrà il codice di gestione degli eventi per tutti i controlli di un particolare tipo.

Ad esempio, creare una class denominata TextBoxEventHandler come segue:

 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 

Ora è necessario creare e colbind un’istanza di quella class per ciascun controllo del tipo appropriato nel modulo:

 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 

Si noti che il motivo per cui è necessario aggiungere le istanze del gestore di eventi a una raccolta è semplicemente quello di assicurarsi che rimangano referenziati e quindi non vengano scartati dal garbage collector prima di averli terminati.

Chiaramente questa tecnica può essere estesa per gestire altri tipi di controllo. Potresti avere classi di gestori di eventi separati per ogni tipo, oppure puoi utilizzare una singola class che ha una variabile membro (e la proprietà associata e il gestore di eventi) per ciascuno dei tipi di controllo che devi gestire.

In questo caso hai poche opzioni, perché i gestori di eventi non possono essere condivisi in VBA / VB6

Opzione 1: utilizzare una funzione di gestione centrale che viene chiamata da ogni gestore di eventi.

 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 

Opzione 2: organizza i tuoi controlli negli array di controllo.

 Sub TextBox_ChangeEvent(Index As Integer) CommonChangeEvent End Sub Sub OtherControlType_ChangeEvent(Index As Integer) CommonChangeEvent End Sub 

Combinando entrambe le opzioni il numero totale del gestore di eventi si ridurrà considerevolmente e i restanti gestori sono solo matrici senza cervello per l’unico vero gestore di eventi.