Ricerca…


Migliori pratiche

Un UserForm è un modulo di classe con un designer e un'istanza predefinita . È possibile accedere al progettista premendo Maiusc + F7 mentre si visualizza il code-behind e si può accedere al code-behind premendo F7 durante la visualizzazione del designer .


Lavora con una nuova istanza ogni volta.

Essendo un modulo di classe , una forma è quindi un progetto per un oggetto . Poiché un modulo può contenere dati e stato, è preferibile lavorare con una nuova istanza della classe, anziché con quella predefinita / globale:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        '...
    End If
End With

Invece di:

UserForm1.Show vbModal
If Not UserForm1.IsCancelled Then
    '...
End If

Lavorare con l'istanza predefinita può portare a piccoli bug quando il modulo viene chiuso con il pulsante rosso "X" e / o quando Unload Me viene usato nel code-behind.


Attuare la logica altrove.

Un modulo dovrebbe riguardare solo la presentazione : un pulsante Click gestore che si collega a un database ed esegue una query parametrizzata basata sull'input dell'utente, sta facendo troppe cose .

Invece, implementare la logica applicativa nel codice che è responsabile per la visualizzazione del modulo, o anche meglio, in moduli e procedure dedicate.

Scrivi il codice in modo tale che UserForm sia sempre e solo responsabile di sapere come visualizzare e raccogliere i dati: da dove provengono i dati, o che cosa succede successivamente ai dati, non ne preoccupa.


Il chiamante non dovrebbe essere disturbato dai controlli.

Crea un modello ben definito per il modulo con cui lavorare, nel proprio modulo di classe dedicato o incapsulato all'interno del codice stesso del modulo stesso - esporre il modello con le procedure Property Get e far lavorare il codice client con questi: questo rende la forma un'astrazione sui controlli e i loro dettagli nitty-grintosi, che espongono solo i dati rilevanti al codice cliente.

Questo significa codice che assomiglia a questo:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .Message, vbInformation
    End If
End With

Invece di questo:

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then
        MsgBox .txtMessage.Text, vbInformation
    End If
End With

Gestire l'evento QueryClose.

I moduli hanno in genere un pulsante Chiudi e le finestre di dialogo / prompt hanno pulsanti Ok e Annulla ; l'utente può chiudere il modulo utilizzando la casella di controllo del modulo (il pulsante rosso "X"), che distrugge l'istanza del modulo per impostazione predefinita (un'altra buona ragione per lavorare ogni volta con una nuova istanza ).

With New UserForm1
    .Show vbModal
    If Not .IsCancelled Then 'if QueryClose isn't handled, this can raise a runtime error.
        '...
    End With
End With

Il modo più semplice per gestire l'evento QueryClose è impostare il parametro Cancel su True e quindi nascondere il modulo anziché chiuderlo :

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    Me.Hide
End Sub

In questo modo il pulsante "X" non distruggerà mai l'istanza e il chiamante può accedere in sicurezza a tutti i membri pubblici.


Nascondi, non chiudere.

Il codice che crea un oggetto dovrebbe essere responsabile della sua distruzione: non è responsabilità del modulo scaricare e terminare se stesso.

Evita l'uso di Unload Me nel code-behind di un modulo. Chiama invece. Me.Hide , in modo che il codice chiamante possa ancora utilizzare l'oggetto creato al momento della chiusura del modulo.


Nome cose.

Utilizzare la finestra degli strumenti Proprietà ( F4 ) per assegnare un nome a ciascun controllo su un modulo. Il nome di un controllo viene utilizzato nel code-behind, quindi a meno che non si stia utilizzando uno strumento di refactoring in grado di gestirlo, rinominare un controllo interromperà il codice , quindi è molto più facile fare le cose in modo corretto in primo luogo, piuttosto che provare per scoprire esattamente quale delle 20 caselle di testo TextBox12 rappresenta.

Tradizionalmente, i controlli UserForm sono denominati con prefissi in stile ungherese:

  • lblUserName per un controllo Label che indica un nome utente.
  • txtUserName per un controllo TextBox cui l'utente può immettere un nome utente.
  • cboUserName per un controllo ComboBox cui l'utente può immettere o selezionare un nome utente.
  • lstUserName per un controllo ListBox cui l'utente può selezionare un nome utente.
  • btnOk o cmdOk per un controllo Button etichettato "Ok".

Il problema è che quando ad esempio l'interfaccia utente viene ridisegnata e un ComboBox trasforma in un ListBox , il nome deve cambiare per riflettere il nuovo tipo di controllo: è meglio nominare i controlli per quello che rappresentano, piuttosto che dopo il loro tipo di controllo - per disaccoppiare il controllo codice dall'interfaccia utente il più possibile.

  • UserNameLabel per un'etichetta di sola lettura che indica un nome utente.
  • UserNameInput per un controllo in cui l'utente può immettere o selezionare un nome utente.
  • OkButton per un pulsante di comando con l'etichetta "Ok".

Qualunque sia lo stile scelto, tutto è meglio che lasciare a tutti i controlli i loro nomi predefiniti. Anche la coerenza nello stile dei nomi è ideale.

Gestione di QueryClose

L'evento QueryClose viene generato ogni volta che un modulo sta per essere chiuso, sia tramite azione dell'utente che a livello di programmazione. Il parametro CloseMode contiene un valore enum VbQueryClose che indica come è stato chiuso il modulo:

Costante Descrizione Valore
vbFormControlMenu Il modulo si sta chiudendo in risposta all'azione dell'utente 0
vbFormCode Il modulo si sta chiudendo in risposta a un'istruzione Unload 1
vbAppWindows La sessione di Windows sta finendo 2
vbAppTaskManager Task Manager di Windows sta chiudendo l'applicazione host 3
vbFormMDIForm Non supportato in VBA 4

Per una migliore leggibilità, è preferibile utilizzare queste costanti anziché utilizzare direttamente il loro valore.


Un form utente cancellabile

Dato un modulo con un pulsante Annulla

qualche forma di esempio

Il code-behind del modulo potrebbe assomigliare a questo:

Option Explicit
Private Type TView
    IsCancelled As Boolean
    SomeOtherSetting As Boolean
    'other properties skipped for brievety
End Type
Private this As TView

Public Property Get IsCancelled() As Boolean
    IsCancelled = this.IsCancelled
End Property

Public Property Get SomeOtherSetting() As Boolean
    SomeOtherSetting = this.SomeOtherSetting
End Property

'...more properties...

Private Sub SomeOtherSettingInput_Change()
    this.SomeOtherSetting = CBool(SomeOtherSettingInput.Value)
End Sub

Private Sub OkButton_Click()
    Me.Hide
End Sub

Private Sub CancelButton_Click()
    this.IsCancelled = True
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        this.IsCancelled = True
        Me.Hide
    End If
End Sub

Il codice chiamante potrebbe quindi visualizzare il modulo e sapere se è stato cancellato:

Public Sub DoSomething()
    With New UserForm1
        .Show vbModal
        If .IsCancelled Then Exit Sub
        If .SomeOtherSetting Then
            'setting is enabled
        Else
            'setting is disabled
        End If
    End With
End Sub

La proprietà IsCancelled restituisce True quando si fa clic sul pulsante Annulla o quando l'utente chiude il modulo utilizzando la casella di controllo .



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow