Dialogues, formulaires et alternatives
Ouvrir et fermer un formulaire
Exemple 2: Sélectionner un dossier
Exemple 3: Barre de progression
Exemple 4: Saisir et valider des données
Les programmes utilisent les dialogues et les formulaires pour obtenir des données ou des instructions de l'utilisateur, pendant l'exécution du programme.
Certains formulaires offrent des menus, permettant à l'utilisateur de choisir
entre différentes actions possibles.
En VBA Excel, vous pouvez utiliser une feuille Excel (de préférence la première)
à la place de formulaires VBA pour construire des menus.
Cela se fait simplement
en insérant des objets (boutons de formulaire par exemple) sur la feuille Excel
et en y assignant une macro VBA ou un hyperlien.
Par ailleurs, il se peut que votre programme VBA doive obtenir des instructions ou des données de l'utilisateur.
Si les choix sont simples (continuer ou arrêter, par exemple), il est recommandé d'utiliser la fonction:
MsgBox(message[, boutons] [, titre]) Où:
La fonction MsgBox() retourne une valeur différente selon le bouton cliqué pour fermer la boîte de dialogue:
La boîte de dialogue ouverte par l'instruction MsgBox() est toujours modale, c'est à dire que l'exécution du programme VBA est interrompu et que le classeur Excel n'est pas accessible tante que la boîte de dialogue ne sera pas fermée par l'utilisateur. MsgBox() permet au programme d'offrir jusqu'à 3 choix (3 boutons) à l'utilisateur. |
Si la boîte de dialogue doit permettre à l'utilisateur de fournir une valeur (et une seule), il est possible d'utiliser l'instruction:
InputBox(message[, titre] [, défaut]) Où:
La boîte de dialogue ouverte par l'instruction InputBox() est toujours modale, c'est à dire que l'exécution du programme VBA est interrompu et que le classeur Excel n'est pas accessible tante que la boîte de dialogue ne sera pas fermée par l'utilisateur. InputBox() offre à l'utilisateur une zone de texte et 2 boutons: Ok et Annuler. |
Si Excel dispose d'une boîte de dialogue qui convient au besoin, il est possible de les utiliser à partir d'un programme VBA:
Collection Dialogs Chaque objet Dialog correspond à une boîte de dialogue
Excel. |
|
Dialogs(xlDialogOpen).Show | Ouvrir fichier |
Dialogs(xlDialogSaveAs).Show | Enregistrer sous |
Il y a plus de 250 autres boîtes de dialogues disponibles dans Excel. Voir l'aide VBA, ou utiliser l'enregistreuse de macro-commande pour identifier le nom de la boîte de dialogue que vous voulez utiliser. |
Il y a aussi l'objet FileDialog:
Objet FileDialog Utilisez la propriété DialogType pour spécifier quelle boîte de dialogue ouvrir: |
|
msoFileDialogFilePicker | Choisir un ou plusieurs fichiers, dont les chemins d'accès sont dans la collection FileDialogSelectedItems |
msoFileDialogFolderPicker | Choisir un dossier, dont le chemins d'accès est dans la collection FileDialogSelectedItems |
msoFileDialogOpen | Choisir un ou plusieurs fichiers qui peuvent être ouverts avec la méthode Execute |
msoFileDialogSaveAs | Choisir un nom de fichier et un chemin d'accès, et d'enregistrer le classeur Excel sous ce nom avec la méthode Execute |
Plusieurs autres propriétés de cet objet permettent de spécifier le
titre, des valeurs par défaut, des filtres, etc. L'objet FileDialog a 2 méthodes:
|
Pour les besoins plus complexes, comme la saisie de plusieurs valeurs avec une validation importante, vous pouvez utiliser un formulaire VBA.
Finalement, pour une saisie vraiment efficace de données vous devriez utiliser Access, dont les formulaires sont beaucoup plus puissants que ceux que vous pouvez programmer en VBA Excel.
L'éditeur VBA comporte une fenêtre spécifique pour créer ou modifier un formulaire.
Créez un formulaire:
Du menu Insertion, sélectionnez UserForm | |
L'explorateur de projet ouvre une branche Feuilles qui ne contient pas des feuilles Excel, mais des formulaires VBA. | |
La fenêtre principale affiche le cadre d'un formulaire. | |
C'est l'entête de l'explorateur de projet qui contrôle l'affichage de la
fenêtre principale: Affichage du
code VBA associé au formulaire (une sorte de module incorporé) Affichage du formulaire Modifie le mode d'affichage de l'explorateur de projets. Inutile.
|
|
La boîte à outils devrait aussi apparaître.
Sinon, du menu Affichage, sélectionnez : |
|
Finalement, remarquez sous l'explorateur de projet, la feuille de
propriétés du formulaire. C'est là que seront affichées les propriétés
de l'objet sélectionné dans le formulaire (ou celles du formulaire
lui-même)
Empressez-vous de changer le nom du formulaire que VBA a nommé UserForm1 (ou n). Il est important de choisir le nom définitif du formulaire AVANT de commencer à lui ajouter du code VBA. |
On attache des procédures Sub aux événements que subit le formulaire.
Par exemple, une procédure sub nommée
Sub UserForm_Initialize()
est exécutée à chaque fois que le formulaire est ouvert (initialisé).
Pour écrire une procédure événementielle, afficher la fenêtre code du formulaire (), sélectionner l'objet qui subit l'événement (le formulaire ou un contrôle du formulaire), dans la liste déroulante de gauche, et l'événement voulu dans la liste de droite. L'éditeur VBA crée alors une procédure Sub vide correspondant à l'événement.
Il est aussi possible de créer une procédure
Sub événementielle d'un contrôle
en double-cliquant dessus.
C'est alors l'événement par défaut du contrôle qui
est choisi.
On appelle contrôle les classes d'objet qu'on peut insérer dans un
formulaire. La description détaillée de chacun
de ceux qui sont disponibles en VBA dépasse le cadre du présent texte, mais voici une présentation sommaire de
chacun d'entre eux:
|
|||
outil de sélection |
n'est pas un contrôle, mais l'outil à utiliser pour sélectionner un ou
plusieurs contrôles.
|
||
libellé (intitulé ou label) |
sert à ajouter du texte explicatif dans le formulaire, comme des
instructions à l'utilisateur ou des étiquettes pour les zones de texte.
|
Propriétés intéressantes:
|
|
zone de texte (textbox) |
sert à inclure dans le formulaire une zone dans laquelle l'utilisateur
sera invité à entrer des valeurs. La valeur entrée est TOUJOURS
enregistrées en format texte, et le programme VBA devra identifier et
faire les conversions appropriées.
|
Propriétés intéressantes:
Événements intéressants:
|
|
Zone de liste modifiable (déroulante ou ComboBox) | Sert à inclure dans le formulaire une zone de texte offrant aussi une liste de choix possibles. |
Propriétés intéressantes:
Événements intéressants:
|
|
Zone de liste (ListBox) | Sert à inclure dans le formulaire une zone de liste de choix possibles. |
Propriétés intéressantes:
Événements intéressants:
|
|
Case à cocher (CheckBox) | Sert à inclure dans le formulaire une (souvent plusieurs) case(s) à cocher |
Propriétés intéressantes:
Événements intéressants:
|
|
Bouton d'option (OptionButton) | Sert à inclure dans le formulaire un (souvent plusieurs) boutons d'option |
Propriétés intéressantes:
Événements intéressants:
|
|
Bouton Bascule (ToggleButton) | Désuet: utiliser une case à cocher | ||
Cadre (Frame) | Sert à regrouper plusieurs contrôles d'un formulaire |
Propriétés intéressantes:
Événements intéressants:
|
|
Bouton de commande (CommandButton) | Sert à inclure dans le formulaire un (souvent plusieurs) bouton(s) |
Propriétés intéressantes:
Événements intéressants:
|
|
Contrôle d'onglet (TabStrip) | Sert à inclure des onglets dans le formulaire |
Propriétés intéressantes:
Événements intéressants:
|
|
Multi Page (Page) | Sert à inclure des pages dans le formulaire |
Propriétés intéressantes:
Événements intéressants:
|
|
Barre de défilement (ScrollBar) | Sert à inclure une barre de défilement dans le formulaire. |
Propriétés intéressantes:
Événements intéressants:
|
|
Toupie (SpinButton) | Sert à inclure des flèches de défilement |
Propriétés intéressantes:
Événements intéressants:
|
|
Image | Sert à inclure une image dans le formulaire |
Propriétés intéressantes:
Événements intéressants:
|
|
RefEdit |
Sert à inclure une zone de sélection de plage Excel dans le formulaire Remarque : si il y n'a aucun bouton RefEdit dans la boîte à outils, procédez
comme suit : |
Propriétés intéressantes:
Événements intéressants:
|
Pour ouvrir un formulaire, il n'y a pas d'instruction VBA. On utiliser plutôt la méthode Show (voir exemples).
Pour réafficher un formulaire déjà ouvert, parce qu'un contrôle a pu changer, ou utilise la méthode RePaint.
Pour fermer un formulaire, on peut utiliser la méthode Close (ou même Hide), mais celle-ci ne libère pas l'espace mémoire occupée par le formulaire.
On utilise plus souvent l'instruction VBA:
Unload objet Où:
|
Lorsque l'instruction est utilisée dans le module VBA appartenant au
formulaire, on préfère utiliser:
Unload Me
L'objet Me étant le formulaire en cours.
Il est fortement déconseillé d'utiliser quelque forme de dialogue que ce soit
dans une fonction (Function) VBA.
Une fonction ne devrait communiquer avec l'environnement et l'utilisateur que
par ses paramètres (en entrée) et sa valeur (en sortie).
Les exemples ci-dessous ne sont donc que des procédures Sub.
Technique 1: utilisant une feuille Excel
Cet exemple requiert:
apparaît alors..
Option Explicit
Private Sub Workbook_Open()
'Auteur Michel Berthiaume
'Afficher une feuille Excel de présentation de l'application
Dim dtDate As Date
On Error GoTo Erreur:
If Sheets("Accueil").Range("Accueil").Value = False Then 'Si l'utilisateur n'a rien coché
Sheets("Accueil").Visible = True
Sheets("Accueil").Select
dtDate = Now()
Do Until Now() - dtDate > (1 / 24 / 60 / 60 * 3) 'Boucle d'attente de 3 secondes
DoEvents 'Permet à l'utilisateur de cocher la case
Loop
End If
Sheets("Accueil").Visible = False
Exit Sub
Erreur:
MsgBox "Erreur inattendue: " & Err.Description
End Sub
La feuille Accueil sera affichée lors de l'ouverture du classeur.
Technique 2: utilisant un formulaire
Note: le document VBA Excel - Créer un formulaire (User Form) d'accueil décrit les étapes de création du formulaire ci-dessous.
Cet exemple requiert:
dont la propriété
Contenant les contrôles (objets) suivants:
Option Explicit Private Sub Workbook_Open() End Sub |
apparaît alors.
Option Explicit
Private Sub Workbook_Open()
'Auteur Michel Berthiaume
'Afficher un formulaire VBA Excel (Microsoft Forms) de présentation de l'application
Option Explicit Private Sub UserForm_Activate() End Sub |
apparaît alors.
Option Explicit
Private Sub UserForm_Activate()
'Auteur: Michel Berthiaume
'Accueil dans un classeur Excel
Dim dtDate As Date
On Error GoTo Erreur:
If Me.cbMessage.Value = False Then 'Seulement si la case n'est pas cochée
Me.Repaint 'Afficher le formulaire
dtDate = Now()
Do Until (Now() - dtDate) > (1 / 24 / 60 / 60 * 3) 'Boucle d'attente de 3 secondes
DoEvents 'Permet à l'utilisateur de cocher la case
Loop
End If
Unload Me 'Effacer le formulaire
Exit Sub
Erreur:
MsgBox "Erreur inattendue: " & Err.Description
L'exemple ci-dessous crée une liste de fichiers d'un dossier choisi par l'utilisateur.
Il requiert une feuille Excel contenant des plages nommées:
Sub ListeFichiers() 'Auteur: Michel Berthiaume 'Créer une feuille Excel contenant la liste des fichiers d'un dossier choisi par l'utilisateur Dim FSO As New Scripting.FileSystemObject 'Requiert une référence à Microsoft Scripting Runtime Dim fsFichier As File Dim lLigne As Long On Error GoTo Erreur: 'Obtenir le nom du dossier With Application.FileDialog(msoFileDialogFolderPicker) .show 'Afficher la boîte de dialogue If .SelectedItems.Count <> 1 Then 'Opération annulée Exit Sub End If Range("NomDossier").Value = .SelectedItems(1) 'Inscrire dans la feuille End With 'Inscrire les fichiers With Range("ListeFichiers") 'Effacer les données présentes .Range(.Offset(0, 0), .Offset(.CurrentRegion.Rows.Count, _ .CurrentRegion.Columns.Count)).Clear lLigne = 1 'Offset initial For Each fsFichier In FSO.GetFolder(Range("NomDossier").Value).Files .Offset(lLigne, 0).Value = fsFichier.Name .Offset(lLigne, 1).Value = fsFichier.Size .Offset(lLigne, 2).Value = fsFichier.DateLastModified lLigne = lLigne + 1 Next End With Exit Sub Erreur: MsgBox "Erreur inattendue: " & Err.Description End Sub |
Commentaires:
L'exemple précédent peut être long à exécuter, si le dossier choisi contient
beaucoup de fichiers.
Ajoutons une barre de progression.
Technique 1: En utilisant la ligne d'état
Excel permet d'afficher un message dans la ligne d'état en bas le l'écran, en utilisant la propriété StatusBar.
Un programme peut appeler la procédure suivante pour afficher un % de progression. Il suffit qu'il rappelle la procédure à chaque fois que le % est modifié.
Sub AfficheProgression(PourcentageEffectué) 'Affiche un pourcentage et une barre de progression dans la barre d'état Excel 'PourcentageEffectué doit être entre 0 et 1 (inclus) 'Si 0, négatif ou >1, efface barre d'état 'Par Michel Berthiaume 'Inspiré du programme de Dick Kusleika If IsNumeric(PourcentageEffectué) And _ (PourcentageEffectué > 0) And _ (PourcentageEffectué <= 1) Then Application.StatusBar = Format(PourcentageEffectué, "0%") & " " & String(PourcentageEffectué * 50, Chr(31)) Else Application.StatusBar = False End If End Sub |
Commentaires:
On modifie donc le programme de l'exemple précédent ainsi:
Sub ListeFichiers1() 'Auteur: Michel Berthiaume 'Créer une feuille Excel contenant la liste des fichiers d'un dossier choisi par l'utilisateur DimFSO As New Scripting.FileSystemObject 'Requiert une référence à Microsoft Scripting Runtime Dim fsFichier As File Dim lLigne As Long Dim lNombre As Long 'Nombre de fichiers 'Obtenir le nom du dossier With Application.FileDialog(msoFileDialogFolderPicker) .show 'Afficher la boîte de dialogue If .SelectedItems.Count <> 1 Then 'Opération annulée Range("NomDossier").Value = "" Exit Sub End If Range("NomDossier").Value = .SelectedItems(1) 'Inscrire dans la feuille End With
Call AfficheProgression(0) 'Effacer la barre de progression |
Technique 2: En utilisant un formulaire
Cet technique requiert:
dont la propriété
Contenant les contrôles (objets) suivants:
contenant:
Il faut associer au formulaire (et à ses contrôles) le code VBA suivant:
Option Explicit 'Auteur: Michel Berthiaume 'Inspiré du travail de John Walkenbach 'Formulaire de production de liste de fichiers Private Sub UserForm_Initialize() 'Initialiser le formulaire If tDossier.Value = "" Then tDossier.Value = ActiveWorkbook.Path 'Dossier par défaut End If End Sub Private Sub bChoisirDossier_Click() 'Obtenir le nom du dossier With Application.FileDialog(msoFileDialogFolderPicker) .Show 'Afficher la boîte de dialogue If .SelectedItems.Count <> 1 Then 'Opération annulée Range("NomDossier").Value = "" Exit Sub End If tDossier.Value = .SelectedItems(1) 'Inscrire dans le formulaire et la feuille End With End Sub Private Sub bGo_Click() 'Produire la liste des fichiers 'Inscrire les fichiers Dim FSO As New Scripting.FileSystemObject 'Requiert une référence à Microsoft Scripting Runtime Dim fsFichier As File Dim lLigne As Long Dim lNombre As Long 'Nombre de fichiers On Error GoTo DossierInexistant lNombre = FSO.GetFolder(Range("NomDossier").Value).Files.Count On Error GoTo 0 If lNombre = 0 Then Exit Sub End If With Range("ListeFichiers") 'Effacer les données présentes .Range(Cells(2, 1), Cells(.CurrentRegion.Rows.Count - 1, _ .CurrentRegion.Columns.Count)).Clear lLigne = 1 'Offset initial For Each fsFichier In FSO.GetFolder(Range("NomDossier").Value).Files Call AfficheProgression(lLigne / lNombre) 'Afficher progression .Offset(lLigne, 0).Value = fsFichier.Name .Offset(lLigne, 1).Value = fsFichier.Size .Offset(lLigne, 2).Value = fsFichier.DateLastModified lLigne = lLigne + 1 Next End With Exit Sub DossierInexistant: MsgBox "Dossier inexistant", , "Liste de fichiers d'un dossier" End Sub Private Sub bQuitter_Click() Unload Me End Sub Sub AfficheProgression(PourcentageEffectue) FrameProgress.Caption = Format(PourcentageEffectue, "0%") LabelProgress.Width = PourcentageEffectue * (FrameProgress.Width - 10) Me.Repaint End Sub |
Finalement, ajouter la procédure:
Sub OuvrirfrmListeFichiers()
FrmListeFichiers.Show
End Sub
dans un module.
Lorsque exécutée, cette dernière procédure exécutera le formulaire.
Voyons comment on peut utiliser Excel pour saisir les informations nécessaires à une facturation de vente.
Technique 1: utilisant une feuille Excel
Créez la feuille Excel suivante:
Ayant les caractéristiques suivantes:
Chacun des trois boutons est associé au procédures correspondantes:
Sub Initial()
'Auteur: Michel Berthiaume
'Initialiser ou réinitialiser la feuille facture
'l'action est déterminée par le contenu du bouton: Démarrer la saisie ou Terminer la saisie
'Configuré pour Excel 2007
Dim sBouton As Shape
'Trouver le bouton
For Each sBouton In ActiveSheet.Shapes 'Examiner chaque bouton
If sBouton.AlternativeText = "Démarrer la saisie" Then
'Initialiser
With ActiveWindow 'Déactive certains affichages
.DisplayHeadings = False
.DisplayHorizontalScrollBar = False
.DisplayVerticalScrollBar = False
.DisplayWorkbookTabs = False
End With
With Application
.DisplayFormulaBar = False
.DisplayStatusBar = False
End With
'Modifier le bouton
Worksheets("Facture").Unprotect
sBouton.AlternativeText = "Terminer la saisie"
sBouton.Select 'Impossible de modifier l'étiquette directement
Selection.Characters.Text = "Terminer la saisie"
Range("NomClient").Select
Worksheets("Facture").Protect
Exit For 'Pas besoin de regarder les autres boutons
ElseIf sBouton.AlternativeText = "Terminer la saisie" Then
'Rétablir l'affichage
With ActiveWindow
.DisplayHeadings = True
.DisplayHorizontalScrollBar = True
.DisplayVerticalScrollBar = True
.DisplayWorkbookTabs = True
End With
With Application
.DisplayFormulaBar = True
.DisplayStatusBar = True
End With
'Modifier le bouton
Worksheets("Facture").Unprotect
sBouton.AlternativeText = "Démarrer la saisie"
sBouton.Select 'Impossible de modifier l'étiquette directement
Selection.Characters.Text = "Démarrer la saisie"
Range("NomClient").Select
Worksheets("Facture").Protect
Exit For 'Pas besoin de regarder les autres boutons
End If
Next
End Sub
Sub Nouvelle()
'Auteur: Michel Berthiaume
'Prépare la feuille pour une nouvelle facture
Range("B3:D5").ClearContents
Range("B7:D16").ClearContents
Worksheets("Facture").Unprotect
Range("Référence") = Range("Référence") + 1
Worksheets("Facture").Protect
Range("NomClient").Select
End Sub
Sub Enregistrer()
'Auteur: Michel Berthiaume
'Exécuté par bouton Ok de boîte de dialogue
With Application.FileDialog(msoFileDialogSaveAs)
.InitialFileName = "Facture de " & Range("NomClient").Value & " du " & Format(Date, "Long Date") & ".xls"
.Show 'Afficher la boîte de dialogue
If .SelectedItems.Count <> 1 Then 'Opération annulée
Exit Sub
End If
ActiveWorkbook.SaveAs Filename:=.SelectedItems(1)
End With
End Sub
Technique 2: utilisant un formulaire
Ici, les factures seront enregistrées dans une liste Excel.
Chaque facture est identifiée par un numéro de référence (séquentiel).
Chaque facture est décrite sur plusieurs lignes:
Cette liste de factures est facilement utilisable avec les filtres, le tris et le tableau croisé dynamique d'Excel.
Créez la feuille Excel selon le modèle ci dessous:
La partie gauche contiendra la liste de facture.
Au milieu (colonne K), le bouton qui appelle le formulaire.
À droite, les colonnes L, M et N contiennent des valeurs qui seront utilisées par le formulaire.
Pour que le bouton Saisir factures ouvre le formulaire:
Sub OuvrirfrmFacture() frmFacture.Show End Sub |
Le formulaire frmFacture est conçu de la façon suivante:
Le formulaire compte les zones de texte suivantes:
Nom | Propriétés importantes | Description |
tClient | TabIndex: 0 | Contiendra le nom du client |
tAdresse1 | TabIndex: 1 | Ligne 1 de l'adresse du client |
tAdresse2 | TabIndex: 2 | Ligne 2 de l'adresse du client |
tLigne | Enabled: False | Numéro de la ligne dans la facture |
tItem | TabIndex: 4 | Description de l'item acheté |
tNombre | TabIndex: 5 | Nombre d'items achetés |
tPrix | TabIndex: 6 | Prix unitaire |
tMontant | Enabled: False | Extension (Nombre * Prix) |
Notez que les zones tLignes et tMontant, qui sont gérées par le programme, sont désactivées (Enabled: False).
Chacune de ces zones de texte est accompagnée d'une étiquette (Lablel) qui la décrit.
6 autres zones de texte servent à afficher des informations sur la facture en cours de traitement:
Nom | Propriétés importantes | Description |
tFacture |
Enabled: False ControlSource: NoFacture |
Contiendra le numéro de facture |
tSousTotal |
Enabled: False ControlSource: SousTotal |
Sous-total de la facture |
tTPS |
Enabled: False ControlSource: TPS |
TPS |
tTVQ |
Enabled: False ControlSource: TVQ |
TVQ |
tTotal |
Enabled: False ControlSource: Total |
Total |
tLigneDébutFacture |
Enabled: False Visible: False |
Numéro de ligne Excel où commence la facture |
tPrix | TabIndex: 6 | Prix unitaire |
tMontant | Enabled: False | Extension (Nombre * Prix) |
Il y a aussi les 4 étiquettes qui décrivent les montants de la facture.
Deux autres étiquettes, tRéférence et tDate afficheront le numéro de la facture affichée et sa date.
Finalement, le formulaire compte 5 boutons:
Nom | Propriétés importantes | Description |
bLignePréc |
TabStop: False Enabled: False Picture: Image d'un triangle |
Enregistre la ligne affichée. Permet de reculer d'une ligne dans la facture. |
bLigneSuiv |
TabStop: False Enabled: False Picture: Image d'un triangle |
Enregistre la ligne affichée. Permet de passer à la ligne suivante dans la facture |
bEnregistrer |
TabIndex: 10 Caption: Enregistrer Enabled: False |
Enregistre la facture. |
bAnnuler |
TabIndex: 11 Caption: Annuler facture Enabled: False |
Annule la facture (et les lignes enregistrées) |
bQuitter |
TabIndex: 12 Caption: Quitter Enabled: True |
Ferme le formulaire |
Le code VBA associé à ce formulaire peut être groupé en quelques blocs:
D'abord la documentation:
Option Explicit 'Auteur: Michel Berthiaume 'Formulaire d'enregistrement de factures 'Noter que le programme n'utilise aucune variable globale. 'Les données externes aux procédures sont stockées 'Soit dans le formulaire, soit dans la feuille Excel 'Ce qui les rend plus accessibles. ' 'Données critiques: 'Range("NoFacture"): numéro de la facture en cours (liée à tFacture) 'Range("NoLigne"): numéro de la ligne de facture en cours (liée à tLigne) 'Range("NoLigneVide"): Numéro de la prochaine ligne Excel vide 'tLigneDébutFacture: Numéro de la ligne Excel de la 1ère ligne de la facture |
L'initialisation:
Private Sub UserForm_Initialize() 'Initialiser le formulaire lDate.Caption = Date tLigneDébutFacture = [NoLigneVide] 'Ajouter 1 au numéro de la dernière facture ActiveSheet.Unprotect 'Désactiver la protection de la feuille If tLigneDébutFacture = 2 Then 'Première facture! tFacture.Value = 1 Else tFacture.Value = Cells(Val(tLigneDébutFacture.Value) - 1, 1).Value + 1 End If tLigne.Value = 1 'Ligne 1 de nouvelle facture ActiveSheet.Protect 'Activer la protection de la feuille Call AfficherTot End Sub |
Commentaires:
Le traitement des lignes de facture:
Private Sub tNombre_Change() tMontant.Value = Val(tNombre.Value) * Val(tPrix.Value) 'Déclenche Sub tMontant_Change() End Sub Private Sub tPrix_Change() tMontant.Value = Val(tNombre.Value) * Val(tPrix.Value) 'Déclenche Sub tMontant_Change() End Sub Private Sub tMontant_Change() 'Activer les boutons de changement de ligne If tMontant.Value <> 0 Then bLigneSuiv.Visible = True Else bLigneSuiv.Visible = False 'On ne peut pas enregistrer une ligne sans montant End If End Sub Private Sub bLignePréc_Click() 'Le formulaire n'affiche qu'une ligne de facture à la fois 'L'utilisateur peut se déplacer d'une ligne à l'autre avec des flèches 'Mais ne peut pas changer de facture. If tLigne.Value = 1 Then Beep 'On ne peut pas reculer avant la ligne 1 Exit Sub End If 'Traiter la ligne en cours If tMontant.Value <> 0 Then 'Enregistrer la ligne s'il y a un montant Call EnregistrerLigne Else 'Pas de montant, pas d'enregistrement End If 'Passer à la ligne précédente tLigne.Value = tLigne.Value - 1 'Édition de nouvelle ligne active Call LireLigne If tLigne.Value = 1 Then bLignePréc.Visible = False 'On ne peut pas reculer plus loin End If tItem.SetFocus 'Activer le 1er champ End Sub Private Sub bLigneSuiv_Click() 'Sert à enregistrer une ligne de facture 'Traiter la ligne en cours If Val(tMontant.Value) = 0 Then 'Ne pas enregistrer ligne nulle Beep Exit Sub ElseIf (Val(tLigne.Value) + 1) > 899 Then 'Pas plus de 899 lignes dans une facture Beep Exit Sub Else 'enregistrer la ligne active avant de passer à la suivante Call EnregistrerLigne End If If tClient.Enabled Then 'C'est la première ligne de la facture tClient.Enabled = False 'Il faut désactiver ces champs tAdresse1.Enabled = False 'Jusqu'à enregistrement ou annulation de la facture tAdresse2.Enabled = False End If 'Initialiser les champs If Cells(Val(tLigneDébutFacture) + Val(tLigne), 1) <> "" Then 'Édition de ligne existante tLigne.Value = tLigne.Value + 1 Call LireLigne Else Call NouvelleLigne End If bLignePréc.Visible = True tItem.SetFocus 'Activer le 1er champ End Sub Sub EnregistrerLigne() 'Enregistrer une ligne de la facture Dim lligne As Long lligne = Val(tLigneDébutFacture.Value) + Val(tLigne.Value) - 1 ActiveSheet.Unprotect Cells(lligne, 1) = tFacture.Value Cells(lligne, 2) = lDate.Caption Cells(lligne, 3) = tLigne.Value Cells(lligne, 4) = tClient.Value Cells(lligne, 5) = tAdresse1.Value Cells(lligne, 6) = tAdresse2.Value Cells(lligne, 7) = tItem.Value Cells(lligne, 8) = tPrix.Value Cells(lligne, 9) = tNombre.Value Cells(lligne, 10) = tMontant.Value ActiveSheet.Protect End Sub Sub LireLigne() 'Lire une ligne de la facture Dim lligne As Long lligne = Val(tLigneDébutFacture.Value) + Val(tLigne.Value) - 1 lRéférence.Caption = Cells(lligne, 1) lDate.Caption = Cells(lligne, 2) tClient.Value = Cells(lligne, 4) tAdresse1.Value = Cells(lligne, 5) tAdresse2.Value = Cells(lligne, 6) tItem.Value = Cells(lligne, 7) tPrix.Value = Cells(lligne, 8) tNombre.Value = Cells(lligne, 9) Call AfficherTot End Sub |
Commentaires:
Le traitement de facture:
Private Sub bEnregistrer_Click() 'Enregistrer la facture Dim lLigne As Long If Val(tMontant.Value) <> 0 Then 'Enregistrer ligne en cours au besoin bLigneSuiv_Click End If lligne = [NoLigneVide] ActiveSheet.Unprotect 'Sous-total lLigne = lLigne + 1 Cells(lligne, 1).Value = tFacture.Value Cells(lligne, 2).Value = lDate.Caption Cells(lligne, 3).Value = 900 Cells(lligne, 4).Value = tClient.Value Cells(lligne, 5).Value = tAdresse1.Value Cells(lligne, 6).Value = tAdresse2.Value Cells(lligne, 7).Value = "Sous-total" Cells(lligne, 10).Value = Val(tSousTotal.Value) 'TPS lligne = lligne + 1 Cells(lligne, 1).Value = tFacture.Value Cells(lligne, 2).Value = lDate.Caption Cells(lligne, 3).Value = 901 Cells(lligne, 4).Value = tClient.Value Cells(lligne, 5).Value = tAdresse1.Value Cells(lligne, 6).Value = tAdresse2.Value Cells(lligne, 7).Value = "TPS" Cells(lligne, 10).Value = Val(tTPS.Value) 'TVQ lligne = lligne + 1 Cells(lligne, 1).Value = tFacture.Value Cells(lligne, 2).Value = lDate.Caption Cells(lligne, 3).Value = 902 Cells(lligne, 4).Value = tClient.Value Cells(lligne, 5).Value = tAdresse1.Value Cells(lligne, 6).Value = tAdresse2.Value Cells(lligne, 7).Value = "TVQ" Cells(lligne, 10).Value = Val(tTVQ.Value) 'Total lligne = lligne + 1 Cells(lligne, 1).Value = tFacture.Value Cells(lligne, 2).Value = lDate.Caption Cells(lligne, 3).Value = 999 Cells(lligne, 4).Value = tClient.Value Cells(lligne, 5).Value = tAdresse1.Value Cells(lligne, 6).Value = tAdresse2.Value Cells(lligne, 7).Value = "Total" Cells(lligne, 10).Value = Val(tTotal.Value) ActiveSheet.Protect Call NouvelleFacture End Sub Private Sub bAnnuler_Click() If MsgBox("Abandonner la facture en cours?", vbOKCancel, "Annuler facture") = vbOK Then Call Annuler End If End Sub Private Sub bQuitter_Click() If Val(tTotal.Value) <> 0 Then If MsgBox("Abandonner la facture en cours?", vbOKCancel, "Quitter sans enregistrer?") = vbOK Then Call Annuler Unload Me End If Else Unload Me End If End Sub |
Commentaires:
Les procédures utilitaires:
Sub
Annuler() 'On ne peut annuler que la facture en cours. Dim lligne As Long 'Annuler les lignes de la facture annulée ActiveSheet.Unprotect For lligne = ([NoLigneVide] - 1) To 1 Step -1 If Cells(lligne, 1).Value = Val(lRéférence.Caption) Then Range(Cells(lligne, 1), Cells(lligne, 10)).ClearContents Else Exit For End If Next ActiveSheet.Protect 'Annuler ligne en cours Call NouvelleFacture End Sub Sub NouvelleFacture() ActiveSheet.Unprotect tFacture.Value = Val(tFacture.Value) + 1 lRéférence.Caption = tFacture.Value tClient.Enabled = True tAdresse1.Enabled = True tAdresse2.Enabled = True tLigne.Value = 0 'Pour démarrer la prochaine ligne à 1 ActiveSheet.Protect Call NouvelleLigne End Sub Sub NouvelleLigne() ActiveSheet.Unprotect tLigne.Value = tLigne.Value + 1 ActiveSheet.Protect tItem.Value = "" tPrix.Value = "" tNombre.Value = "" Call AfficherTot End Sub Sub AfficherTot() 'Afficher les totaux de facture 'et activer/désactiver les boutons appropriés. Calculate 'S'assurer que Excel a les bonnes valeurs tSousTotal = [SousTotal] tTPS.Value = [TPS] tTVQ.Value = [TVQ] tTotal.Value = [Total] If Val(tTotal.Value) <> 0 Then bAnnuler.Enabled = True bEnregistrer.Enabled = True bLigneSuiv.Visible = True Else bAnnuler.Enabled = False bEnregistrer.Enabled = False bLigneSuiv.Visible = False 'Les autres boutons sont gérés par AfficherTot End If If tLigne = 1 Then bLignePréc.Visible = False Else bLignePréc.Visible = True End If End Sub |
Commentaires: Ces procédures contiennent des opérations qui sont utilisées
par plusieurs autres procédures du formulaire.
On préfère regrouper ces
opérations plutôt que les copier dans les différentes procédures qui les
utilisent.
Les programmes VBA Excel peuvent communiquer avec l'utilisateur en utilisant:
Le fichier Excel Tutoriel Exemples Dialogues.xlsm contient les exemples présentés dans la présente section.