Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :
Gestion des rendez-vous en VBA Excel
Dans cette
formation VBA Excel , nous poursuivons les travaux que nous avons initiés dans la précédente formation. Ils avaient consisté Ã
automatiser l'intégration de rendez-vous et tâches programmées dans un
calendrier annuel . Chacun est d'ailleurs repéré par la coche d'un commentaire dans la case du jour et du mois qui lui correspondent. Ce
commentaire décrit le rendez-vous. Souvenez-vous, l'utilisateur choisit un mois avec la première liste déroulante puis un jour avec la seconde. Il décrit la
tâche planifiée dans la cellule prévue à cet effet et clique sur le
bouton + . Une nouvelle coche apparaît alors dans la cellule concernée, repérant la date précise d'exécution dans le
calendrier .
Nous devons désormais construire l'
interface de gestion des rendez-vous au clic sur l'autre bouton, le
bouton - . Elle doit permettre de modifier ou supprimer une tâche. Cette dernière action doit effacer le rendez-vous du
calendrier annuel . C'est ce qu'illustre la capture ci-dessus de l'application finalisée.
Source et présentation de la problématique
Nous devons reprendre les travaux là où nous les avions laissés. Il s'agit donc de récupérer le
classeur Excel permettant de créer de nouvelles tâches.
La
feuille Calendrier est active par défaut. Le fait de changer l'année en
cellule C3 enclenche la reconstruction automatique du
calendrier annuel . Les
jours de Week End ainsi que les
jours fériés sont dynamiquement repérés par des
règles de mise en forme conditionnelle . Ces jours fériés sont recensés dans la troisième feuille de ce classeur, la
feuille Jour_feries . Nous proposons d'ajouter une nouvelle tâche afin de rappeler le fonctionnement du processus bâti jusqu'alors.
Afficher la feuille Calendrier ,
Avec la liste déroulante en I3 , choisir un mois de l'année,
Avec la liste déroulante en J3 , choisir un jour pour ce mois,
En K2 , saisir son descriptif, par exemple : 9H : Congrès Expo.Grenoble ,
Puis, cliquer sur le bouton + situé en colonne N,
Presqu'aussitôt, la nouvelle tâche est repérée dans le calendrier, dans la case de la date programmée.
Comme l'illustre la capture ci-dessus, elle est repérée par la coche d'un commentaire. Ce dernier restitue la description associée. C'est le résultat du
code VBA que nous avons conçu jusqu'alors. Souvenez-vous, tous ces
rendez-vous sont empilés dans un tableau intermédiaire sur la
feuille Liste_rv .
Interface de gestion des rendez-vous
En revanche, si vous cliquez sur le
bouton - de la
feuille Calendrier , vous le sélectionnez. Aucune action n'est déclenchée pour l'instant. Il s'agit de l'enjeu de ce second volet. Dans un premier temps, nous devons enclencher l'affichage du
formulaire de gestion .
Basculer dans l'éditeur de code VBA Excel à l'aide du raccourci clavier ALT + F11 ,
Dans l'explorateur de projet, déployer l'affichage du dossier Feuilles ,
Puis, cliquer sur l'élément gestion ,
Comme vous le remarquez, le
UserForm est déjà construit. Il est reconnu sous le nom
gestion . Mais il n'est encore associé à aucun
code VBA . Nous devons commencer par l'afficher au clic sur le
bouton - , depuis la
feuille Calendrier . Pour cela, nous proposons de créer une petite procédure dans le
module de code de la formation précédente. Nous l'associerons au bouton de la feuille. Un clic sur ce dernier aura donc pour effet de déclencher son code.
Dans l'explorateur de projet, déployer l'affichage du dossier Modules ,
Puis double cliquer sur l'élément code_rv pour afficher sa feuille de code au centre de l'écran,
Nous y retrouvons les
procédures et
fonctions que nous avions développées lors de la formation précédente. Elles permettent cette
intégration des rendez-vous avec leurs
commentaires . Plus précisément, c'est la
procédure ajouter qui est en liaison avec le
bouton + de la
feuille Calendrier .
Au-dessus de la procédure ajouter , créer la procédure gerer , comme suit :
Sub gerer()
gestion.Show
End Sub
Nous exploitons la
méthode Show de l'
objet UserForm reconnu par son nom, soit
gestion . Cette méthode a pour effet de commander l'affichage du
formulaire . Pour en avoir la confirmation, il est désormais opportun d'établir la liaison entre le bouton et cette procédure.
Enregistrer les modifications (CTRL + S),
Basculer sur la feuille Calendrier (ALT + F11),
Cliquer avec le bouton droit de la souris sur le bouton - situé en colonne N,
Dans le menu contextuel, choisir Affecter une macro ,
Dans la boîte de dialogue qui suit, sélectionner la macro gerer et cliquer sur Ok,
Cliquer sur n'importe quelle cellule de la feuille pour désactiver la sélection du bouton,
Puis, cliquer sur le bouton - ,
Le
UserForm s'affiche en effet. Pour l'instant certes, il n'est pas fonctionnel puisqu'aucun
code VBA ne lui est encore associé.
Remplir une liste déroulante de formulaire
Pour gérer ses rendez-vous, l'utilisateur doit pouvoir les désigner. C'est pourquoi, au
chargement du formulaire , nous devons remplir la liste déroulante de toutes les dates des tâches recensées. Ces dates sont toutes archivées dans la
feuille Liste_rv , en colonne D, soit la quatrième.
Cliquer sur la croix en haut à droite du UserForm pour fermer le formulaire,
Revenir dans l'éditeur de code VBA (ALT + F11),
Afficher le formulaire et sélectionner sa liste déroulante ,
Si vous consultez la
fenêtre des propriétés , vous constatez que cette liste déroulante est reconnue sous le
nom d'objet liste_dates . C'est par ce nom que nous allons pouvoir la manipuler par le
code VBA .
Double cliquer sur un emplacement vide du formulaire,
Nous basculons ainsi dans la feuille de code, entre les bornes de la
procédure UserForm_Click . Il ne s'agit pas de celle qui nous intéresse. Nous souhaitons un code se déclenchant au
chargement du formulaire et non au clic.
En haut de la feuille de code, à l'aide de la seconde liste déroulante, choisir l'événement associé Activate ,
Nous générons ainsi la
procédure événementielle UserForm_Activate . Son code se déclenchera à l'activation du formulaire, soit au chargement.
Supprimer la procédure événementielle UserForm_Click ,
Nous devons parcourir l'ensemble des lignes du tableau de la
feuille Liste_rv . L'objectif est de réceptionner toutes les
dates de rendez-vous , pour les charger dans la
liste déroulante . Il s'agit de débuter par la
déclaration des variables nécessaires .
Entre les bornes de la procédure UserForm_Activate , ajouter les déclarations et affectations suivantes :
Dim la_date As String
Dim ligne As Integer: Dim colonne As Integer
ligne = 4: colonne = 2
Les
variables ligne et colonne , déclarées comme des entiers, parlent d'elles-mêmes. Elles doivent servir à parcourir les cellules de la
feuille Liste_rv . La
variable la_date , déclarée comme une chaîne de texte, doit bien sûr mémoriser la date de chaque rendez-vous. Pour cela, son affectation doit intervenir dans une
boucle de traitement . Cette boucle doit consister à parcourir toutes les lignes des tâches recensées. Elle doit passer à la ligne suivante, tant qu'une cellule non vide est détectée, indiquant qu'une tâche est bien référencée. Nous l'avions mise en oeuvre dans la formation précédente pour insérer les nouveaux rendez-vous à la suite des autres. C'est une
boucle While en VBA qui permet de poursuivre son traitement en fonction d'une condition à vérifier.
A la suite de la procédure, ajouter le code suivant :
While(Sheets('liste_rv').Cells(ligne, colonne).Value <> '')
la_date = Sheets('liste_rv').Cells(ligne, 4).Value
liste_dates.AddItem la_date
ligne = ligne + 1
Wend
Tant qu'une cellule non vide est détectée pour la ligne en cours (Cells(ligne, colonne).Value <> ''), nous passons à la ligne suivante (ligne = ligne + 1), pour poursuivre le traitement. Mais avant cela, nous récupérons la date inscrite en colonne D (Sheets('liste_rv').Cells(ligne, 4).Value), dans la
variable la_date . Et nous exploitons la
méthode AddItem de l'
objet Zone de liste déroulante pour ajouter chacune d'elle tour à tour, soit à chaque nouvelle ligne analysée dans la boucle. Lorsque cette boucle termine son traitement, cela signifie que la fin du tableau des tâches est atteinte. Toutes les dates doivent donc être chargées. C'est ce que nous proposons de vérifier.
Enregistrer les modifications (CTRL + S) et basculer sur la feuille Calendrier (ALT + F11),
Cliquer sur le bouton - situé en colonne N,
Déployer l'affichage de la liste déroulante sur le formulaire,
Comme vous le remarquez, tous les rendez-vous créés sont identifiés, repérés par leurs dates respectives. De plus, elles apparaissent dans l'
ordre croissant . C'est un
tri sur le tableau intermédiaire qui avait permis cette réorganisation.
Charger le contenu au choix dans une liste
Au choix de l'une de ces dates, nous devons charger son contenu dans la zone de texte multiligne, pour permettre les modifications notamment.
Revenir dans l'éditeur de code VBA et afficher le UserForm ,
Double cliquer sur la liste déroulante liste_dates ,
Nous basculons ainsi dans la feuille de code, entre les bornes de la
procédure liste_dates_Change . Elle se déclenchera à chaque fois qu'un changement est détecté dans la liste déroulante. En d'autres termes, l'événement est intercepté lorsque l'utilisateur sélectionne l'une de ses valeurs.
Le choix de l'utilisateur doit être mémorisé en
variable publique . Ainsi, lorsqu'il décidera de modifier ou supprimer le rendez-vous sélectionné, nous pourrons exploiter la variable ayant conservé la valeur, au-delà des bornes des procédures. Elle doit indiquer la ligne sur laquelle agir, dans le tableau des tâches de la
feuille Liste_rv .
Au-dessus de la procédure liste_dates_Change , déclarer la variable publique ligne_ref , comme suit :
Dim ligne_ref As Integer
Nous avons besoin de variables pour manipuler la date et le contenu de chaque tâche. De même, nous devons pouvoir parcourir les lignes du tableau, à la recherche du rendez-vous correspondant à la date sélectionnée.
Entre les bornes de la procédure liste_dates_Change , ajouter les déclarations et affectations suivantes :
Dim la_date As String: Dim le_contenu As String
Dim ligne As Integer: Dim colonne As Integer
ligne = 4: colonne = 2
Nous initialisons les variables ligne et colonne sur la cellule du premier rendez-vous potentiel, soit
B4 .
Nous devons désormais parcourir chaque ligne du tableau, tant qu'un rendez-vous est repéré. Il s'agit donc de réaliser un traitement récursif vérifiant que la cellule en cours n'est pas vide. Mais cette fois, nous allons exploiter une
boucle Do While à la place d'une
boucle While . La
boucle Do While propose une instruction d'échappement (Exit Do). Cette dernière permet de mettre fin à la boucle sur demande. Dans notre cas, une fois la date trouvée, nous pourrons réceptionner son contenu pour l'afficher sur le formulaire. Il ne sera donc plus nécessaire de scruter les tâches à la recherche de la correspondance.
A la suite du code de la procédure liste_dates_Change , ajouter la boucle Do While suivante :
Do While(Sheets('liste_rv').Cells(ligne, colonne).Value <> '')
ligne = ligne + 1
Loop
Il s'agit exactement du même traitement que celui que nous avons mis en place au chargement du formulaire. Seules les bornes de la boucle changent, pour les raisons d'optimisation de code, évoquées précédemment.
A chaque passage dans la boucle, nous devons vérifier la correspondance entre la date choisie et celle du rendez-vous en cours d'analyse. Une
instruction conditionnelle est donc de mise.
Dans les bornes de la boucle, avant l'incrémentation de la variable ligne, ajouter les instructions suivantes :
la_date = Sheets('liste_rv').Cells(ligne, 4).Value
If (la_date = liste_dates.Value) Then
Exit Do
End If
Nous commençons par prélever la date de la tâche en cours d'analyse (Sheets('liste_rv').Cells(ligne, 4).Value). Si elle concorde avec le choix de l'utilisateur depuis le formulaire (la_date = liste_dates.Value), nous choisissons de mettre fin à l'exécution de la boucle (Exit Do). En effet, la date a été trouvée. Mais avant de sortir de la boucle, nous devons prélever le contenu du rendez-vous, pour l'afficher dans la zone de texte du formulaire. Le nom d'objet de cette zone de saisie est
date_contenu .
Dans les bornes de l'instruction conditionnelle, avant le Exit Do , ajouter les lignes suivantes :
le_contenu = Sheets('liste_rv').Cells(ligne, 5).Value
date_contenu.Text = le_contenu
ligne_ref = ligne
En colonne E, nous récupérons la description du rendez-vous concordant (Sheets('liste_rv').Cells(ligne, 5).Value). Nous la stockons dans la
variable le_contenu . Nous l'exploitons pour l'inscrire dans la zone de saisie, grâce à l'affectation de sa
propriété Text (date_contenu.Text). Avant de sortir de la boucle, nous n'oublions pas de prélever l'indice de ligne de la tâche en cours (ligne_ref = ligne). A la modification ou à la suppression, nous pourrons questionner cette
variable publique pour directement atteindre la ligne à impacter, dans le tableau de la
feuille Liste_rv . Il s'agit maintenant de tester si nous parvenons bien à récupérer le contenu d'une tâche désignée, au choix dans la liste déroulante depuis le formulaire.
Enregistrer les modifications et basculer sur la feuille Calendrier,
Cliquer sur le bouton - situé dans la colonne N, en haut de la feuille,
Dans le formulaire gestion qui s'affiche, déployer l'affichage de la liste déroulante ,
Sélectionner l'une des dates récupérées,
Comme vous le remarquez et comme l'illustre la capture ci-dessous, le contenu du rendez-vous désigné par sa date, est parfaitement restitué dans la zone de texte du formulaire. Si vous consultez la
feuille Liste_rv , vous confirmez la cohérence. Si vous changez de date, le contenu s'adapte. Notre
code VBA pour récupérer le contenu d'un rendez-vous est donc parfaitement fonctionnel.
Fermer le formulaire en cliquant sur la croix de sa fenêtre,
Revenir dans l'éditeur de code VBA Excel ,
Modifier - Supprimer un Rendez-vous
Nous devons exploiter ces résultats pour permettre à l'utilisateur d'agir sur le rendez-vous ainsi désigné. S'il intervient dans la zone de saisie et qu'il clique sur le
bouton Modifier , la description de la tâche doit être mise à jour. S'il clique tout simplement sur le
bouton Supprimer , la tâche désignée doit disparaître du calendrier. La
variable publique ligne_ref va s'avérer précieuse. Souvenez-vous, elle a en mémoire l'indice de ligne du rendez-vous dans le tableau de la
feuille Liste_rv . Elle indique sur quelle ligne doit se produire la modification ou encore quelle est la ligne qui doit être supprimée.
Afficher le formulaire gestion grâce à l'explorateur de projet,
Double cliquer sur le bouton Modifier pour créer sa procédure événementielle ,
Nous basculons ainsi dans la
feuille de code VBA , entre les bornes de la
procédure Modifier_Click . Notre code s'exécutera donc au clic sur ce bouton. Il s'agit de mettre à jour le contenu du rendez-vous modifié. Dans la
feuille Liste_rv , il est situé en colonne E, soit à l'
indice 5 et en ligne :
ligne_ref .
Entre les bornes de la procédure Modifier_Click, ajouter les instructions suivantes :
Sheets('liste_rv').Cells(ligne_ref, 5).Value = date_contenu.Text
effacer_com
ajouter_com
Nous remplaçons la description du rendez-vous par le contenu de la zone de texte du formulaire (date_contenu.Text). Pour que les changements puissent être mis à jour dans le calendrier, nous appelons les deux
procédures effacer_com et
ajouter_com . La première permet de supprimer tous les commentaires du calendrier pour que la seconde puisse les recréer en tenant compte des modifications. Nous les avions développées dans la formation précédente afin de pouvoir insérer de nouveaux rendez-vous. Toutes deux appartiennent au
module code_rv .
Il est temps de tester cette fonctionnalité de modification des rendez-vous.
Enregistrer les modifications et basculer sur la feuille Calendrier ,
Cliquer sur le bouton - pour déclencher l'affichage du formulaire,
A l'aide de la liste déroulante, sélectionner le rendez-vous du 16/07 par exemple,
Dans la zone de texte, modifier sa description : 14h : Réunion de chantier , comme suit :
14h : Réunion de chantier
16h : Réunion de projet
Pour passer à la ligne dans la zone de texte, vous devez réaliser le
raccourci clavier MAJ + Entrée .
Cliquer alors sur le bouton Modifier et fermer le formulaire,
Dans le calendrier , pointer sur la case du 16 Juillet,
Comme en atteste le contenu du commentaire, la description du rendez-vous a parfaitement été mise à jour dans le
calendrier annuel . Notre
interface de gestion des tâches est donc de plus en plus fonctionnelle. Nous devons désormais permettre à l'utilisateur de supprimer un
rendez-vous qui est obsolète ou qui n'est plus d'actualité.
Revenir dans l'éditeur de code VBA Excel ,
Afficher le UserForm gestion ,
Double cliquer sur le bouton Supprimer_Click pour créer sa procédure événementielle ,
Nous basculons ainsi dans la feuille de code, entre les bornes de la
procédure Supprimer_Click . Elle s'exécutera donc au clic sur le
bouton Supprimer .
Entre les bornes de la procédure, ajouter les lignes suivantes :
Sheets('liste_rv').Cells(ligne_ref, 1).EntireRow.Delete
effacer_com
ajouter_com
Le
code VBA est trivial. Nous pointons sur une cellule de la ligne correspondant au rendez-vous, grâce à la
variable publique ligne_ref . Nous exploitons la
propriété EntireRow de l'
objets Cells pour désigner la ligne complète à partir de cette cellule. Dès lors, la
méthode Delete ordonne la suppression complète de la ligne ainsi désignée. De fait, le rendez-vous sélectionné est supprimé. Puis, comme précédemment, nous appelons les deux
procédures effacer_com et ajouter_com . Elles ont pour mission de reprendre l'analyse complète des tâches afin de produire la mise à jour de tous les rendez-vous et de leurs commentaires, dans le calendrier annuel.
Enregistrer les modifications et basculer sur la feuille Calendrier ,
Cliquer sur le bouton - pour afficher le UserForm ,
Avec la liste déroulante, choisir le rendez-vous du 16 Juillet,
Puis, cliquer sur le bouton Supprimer ,
Comme vous le constatez, le commentaire de la case correspondante disparaît du
calendrier annuel , attestant donc que le rendez-vous désigné est parfaitement supprimé. Nous en avons terminé avec ce deuxième volet même si des améliorations sont à entrevoir. Au clic sur le
bouton Supprimer , nous devrions réactualiser la liste déroulante des dates et réinitialiser la
variable ligne_ref . Un deuxième clic non maîtrisé sur le
bouton Supprimer occasionnerait la destruction d'une tâche située désormais à l'emplacement de la précédente. Mais comme les grandes lignes sont données et que le plus dur est fait, vous aurez tout le loisir d'adapter cette application de
gestion des rendez-vous à vos besoins. Concernant le premier volet, il serait intéressant d'empêcher l'ajout d'une tâche lorsque les dates et/ou le contenu ne sont pas définis.
Dans le prochain volet qui sera le dernier, nous améliorerons le rendu visuel du gestionnaire grâce à des règles dynamiques de
mise en forme conditionnelle . Un coup d'oeil suffira à déceler la présence des différentes tâches et de leur importance. Seules les
fonctionnalités Excel seront nécessaires. Nous laisserons donc de côté le
code VBA .
Le
code VBA complet associé au formulaire pour la gestion des rendez-vous est le suivant :
Dim ligne_ref As Integer
Private Sub liste_dates_Change()
Dim la_date As String: Dim le_contenu As String
Dim ligne As Integer: Dim colonne As Integer
ligne = 4: colonne = 2
Do While (Sheets('liste_rv').Cells(ligne, colonne).Value <> '')
la_date = Sheets('liste_rv').Cells(ligne, 4).Value
If (la_date = liste_dates.Value) Then
le_contenu = Sheets('liste_rv').Cells(ligne, 5).Value
date_contenu.Text = le_contenu
ligne_ref = ligne
Exit Do
End If
ligne = ligne + 1
Loop
End Sub
Private Sub Modifier_Click()
Sheets('liste_rv').Cells(ligne_ref, 5).Value = date_contenu.Text
effacer_com
ajouter_com
End Sub
Private Sub Supprimer_Click()
Sheets('liste_rv').Cells(ligne_ref, 1).EntireRow.Delete
effacer_com
ajouter_com
End Sub
Private Sub UserForm_Activate()
Dim la_date As String
Dim ligne As Integer: Dim colonne As Integer
ligne = 4: colonne = 2
While (Sheets('liste_rv').Cells(ligne, colonne).Value <> '')
la_date = Sheets('liste_rv').Cells(ligne, 4).Value
liste_dates.AddItem la_date
ligne = ligne + 1
Wend
End Sub