Recherche…


Les meilleures pratiques

Un objet UserForm est un module de classe avec un concepteur et une instance par défaut . Vous pouvez accéder au concepteur en appuyant sur Maj + F7 tout en affichant le code-behind , et vous pouvez accéder au code-behind en appuyant sur F7 tout en affichant le concepteur .


Travaillez avec une nouvelle instance à chaque fois.

En tant que module de classe , un formulaire est donc un modèle pour un objet . Un formulaire pouvant contenir des états et des données, il est préférable de travailler avec une nouvelle instance de la classe, plutôt qu'avec une instance par défaut / globale:

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

Au lieu de:

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

Travailler avec l'instance par défaut peut conduire à des bogues subtils lorsque le formulaire est fermé avec le bouton rouge "X" et / ou lorsque Unload Me est utilisé dans le code-behind.


Implémenter la logique ailleurs.

Un formulaire ne doit concerner que la présentation : un bouton Le gestionnaire de Click qui se connecte à une base de données et exécute une requête paramétrée en fonction des entrées de l'utilisateur fait trop de choses .

Au lieu de cela, implémentez la logique applicative dans le code responsable de l'affichage du formulaire, ou même mieux, dans les modules et les procédures dédiés.

Écrivez le code de manière à ce que l'objet UserForm ne soit responsable que de savoir comment afficher et collecter des données: la provenance des données ou les événements ultérieurs ne sont pas concernés.


L'appelant ne devrait pas être dérangé par les contrôles.

Créez un modèle bien défini pour le formulaire avec lequel travailler, soit dans son propre module de classe dédié, soit encapsulé dans le code-behind du formulaire - exposez le modèle avec les procédures Property Get , et faites en sorte que le code client fonctionne avec ceci: la forme une abstraction sur les contrôles et leurs détails les plus concrets, exposant uniquement les données pertinentes au code client.

Cela signifie un code qui ressemble à ceci:

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

Au lieu de cela:

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

Gérez l'événement QueryClose.

Les formulaires ont généralement un bouton Fermer et les invites / boîtes de dialogue ont les boutons Ok et Annuler ; l'utilisateur peut fermer le formulaire en utilisant la boîte de contrôle du formulaire (le bouton rouge "X"), qui détruit l'instance de formulaire par défaut (une autre bonne raison de travailler avec une nouvelle instance à chaque fois ).

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

Le moyen le plus simple de gérer l'événement QueryClose consiste à définir le paramètre Cancel sur True , puis à masquer le formulaire au lieu de le fermer :

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

De cette façon, le bouton "X" ne détruira jamais l'instance et l'appelant peut accéder en toute sécurité à tous les membres publics.


Cachez, ne fermez pas.

Le code qui crée un objet doit être responsable de sa destruction: ce n'est pas la responsabilité du formulaire de se décharger et de se terminer.

Évitez d'utiliser Unload Me dans le code d'un formulaire. Appelez Me.Hide place, afin que le code appelant puisse toujours utiliser l'objet créé lors de la fermeture du formulaire.


Nommez les choses.

Utilisez les propriétés (F4 de) de nommer soigneusement chaque contrôle sur un formulaire. Le nom d'un contrôle est utilisé dans le code-behind, à moins que vous n'utilisiez un outil de refactoring capable de gérer cela, renommer un contrôle va casser le code - il est donc beaucoup plus facile de faire les choses en premier lieu. pour définir exactement laquelle des 20 zones de TextBox12 représente.

Traditionnellement, les contrôles UserForm sont nommés avec des préfixes de style hongrois:

  • lblUserName pour un contrôle Label qui indique un nom d'utilisateur.
  • txtUserName pour un contrôle TextBox où l'utilisateur peut entrer un nom d'utilisateur.
  • cboUserName pour un contrôle ComboBox lequel l'utilisateur peut entrer ou sélectionner un nom d'utilisateur.
  • lstUserName pour un contrôle ListBox où l'utilisateur peut choisir un nom d'utilisateur.
  • btnOk ou cmdOk pour un contrôle Button libellé "Ok".

Le problème est que lorsque par exemple l'interface utilisateur obtient redessinée et un ComboBox des modifications à un ListBox , le nom doit changer pour refléter le nouveau type de contrôle: il est préférable de contrôles de nom pour ce qu'ils représentent, plutôt qu'après leur type de contrôle - à découpler la code de l'interface utilisateur autant que possible.

  • UserNameLabel pour une étiquette en lecture seule qui indique un nom d'utilisateur.
  • UserNameInput pour un contrôle où l'utilisateur peut entrer ou choisir un nom d'utilisateur.
  • OkButton pour un bouton de commande intitulé "Ok".

Quel que soit le style choisi, tout est meilleur que de laisser tous les contrôles à leurs noms par défaut. La cohérence dans le style de nommage est également idéale.

Gestion de la requêteClose

L'événement QueryClose est QueryClose chaque fois qu'un formulaire est sur le point d'être fermé, qu'il s'agisse d'une action utilisateur ou d'un programme. Le paramètre CloseMode contient une valeur enum VbQueryClose qui indique comment le formulaire a été fermé:

Constant La description Valeur
vbFormControlMenu Le formulaire se ferme en réponse à l'action de l'utilisateur 0
vbFormCode Le formulaire se ferme en réponse à une instruction Unload 1
vbAppWindows La session Windows se termine 2
vbAppTaskManager Le gestionnaire de tâches Windows ferme l'application hôte 3
vbFormMDIForm Non pris en charge dans VBA 4

Pour une meilleure lisibilité, il est préférable d'utiliser ces constantes au lieu d'utiliser directement leur valeur.


Un objet utilisateur annulable

Étant donné un formulaire avec un bouton Annuler

un exemple de formulaire

Le code-behind du formulaire pourrait ressembler à ceci:

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

Le code d'appel peut alors afficher le formulaire et savoir s'il a été annulé:

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 propriété IsCancelled renvoie True lorsque le bouton Annuler est cliqué ou lorsque l'utilisateur ferme le formulaire à l'aide de la boîte de contrôle .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow