Suppression, mises à jour, impression
des données d'un planning - Partie 2
Date de publication : 30/06/08
Par
Jean BALLAT (Espace perso de jeannot45)
Cet article continue la progression de la
gestion de planning (partie 1)
On y retrouvera la description des manipulations complémentaires à la gestion de nos données (suppression, mises à jour diverses, notification (envoi de mail),
impression et double affichage des données.
Il a été coécrit avec
Morgan Billy (Dolphy35) pour la partie Notification
I. INTRODUCTION
II. LE CAHIER DES CHARGES
II-A. Contenu du Cahier des Charges
II-B. Présentation des modifications
III. LE DOUBLE AFFICHAGE
III-A. Présentation
III-B. Le Code VBA associé
IV. LA MANIPULATION DES DONNEES
IV-A. Présentation
IV-B. Les contrôles dans le formulaire
IV-C. Les Boutons du Formulaire
IV-C-1. Supprimer (2)
IV-C-2. Salle (3)
IV-C-3. Date (4)
IV-C-4. Formateur (5)
V. IMPRIMER LES DONNEES
V-A. Présentation
V-B. Principe du Planning
V-C. Le sous-état SE_DetailFormation
V-D. Le sous-état SE_Planning
VI. LA NOTIFICATION
VI-A. Présentation
VI-A-1. Le Formulaire
VI-A-2. Fonctionnement du formulaire
VI-A-3. Structure du formulaire
VI-A-3-a. Description des contrôles
VI-A-3-b. Les propriétés des contrôles
VI-A-3-b-i. La zone de liste déroulante : lstSemaine
VI-A-3-b-ii. Zones de Texte : txtDu et txtAu
VI-A-3-b-iii. Zone de liste : lsFormateur
VI-B. Le Code VBA dans le formulaire
VII. CONCLUSION
VIII. TELECHARGEMENT
IX. REMERCIEMENTS
I. INTRODUCTION
Nous avions abordé lors de la partie 1, la génération du planning et la création de tous les formulaires nécessaires à la mise en place de celui-ci.
Dans cette seconde phase, nous allons manipuler nos données, c'est à dire les mettre à jour, les supprimer, les imprimer.
Comme dans la partie précédente, nous devrons bien sûr nous conformer aux exigences du Cahier des Charges.
Cet article se décomposera en plusieurs étapes :
- Le Cahier des Charges.
- Le Double affichage (Formateurs/Salles).
- La Manipulation des données.
- L'Impression.
- La Notification (envoi de mail).
On retrouvera la base exemple GestionPlanningV2 dans la Section "Téléchargement"
II. LE CAHIER DES CHARGES
II-A. Contenu du Cahier des Charges
Le double affichage :
Afin de rendre l'application plus conviviale, il sera possible d'afficher soit le planning des salles, soit le planning des formateurs.
Lorsque l'affichage sera du type "Formateur", une sécurité sera prévue en cas de clic sur une case du planning, empêchant tout utilisateur d'intervenir sur celui-ci.
Lorsque l'affichage sera de type "Salles", les cases du planning seront sensibles au clic et permettront alors de réserver (voir
Gestion planning partie 1) ou de modifier une session.
La manipulation des données :
On entendra par manipulation des données :
- Supprimer une formation.
- Changer de formateur.
- Changer de salle de formation.
- Changer la date de la formation.
L'impression :
Celle-ci imprimera la partie graphique du planning et le détail des formations. Elle dépendra du type d'affichage.
- Affichage Formateurs : Impression lancée en cliquant sur le nom du formateur.
- Affichage Salles : Impression globale de la période affichée. Impression lancée à partir du bouton "Imprimer".
La notification :
On pourra sélectionner une période libre ou une semaine particulière et envoyer un mail aux formateurs disposant d'une adresse mail.
Le mail s'affichera afin de donner la possibilité d'ajouter un texte particulier.
II-B. Présentation des modifications

Chaque nouveauté a été matérialisée par un numéro sur l'image.
1) Simulation des boutons "Bascule" avec l'animation décrite dans la gestion de planning (
partie 1).
2) Modification des données en cliquant sur une des cases occupées du planning.(Type d'affichage : Salles)
3) Impression globale du planning des salles.
4) La notification auprès des formateurs disposant d'une adresse mail.
III. LE DOUBLE AFFICHAGE
III-A. Présentation

Par le jeu de boutons "Bascule" personnalisés, on affiche soit le planning des formateurs soit le planning des salles.
On remarquera en mode "Création" sur le formulaire F_Planning, l'ajout de zones texte ("txtCode1"..."txtCode10") qui recevront soit le CodeFormateur, soit le CodeSalleFormation.
La récupération de cette information sera importante pour l'impression du planning du formateur.
 |
On aurait pu utiliser cette méthode dans la version 1 du planning pour récupérer également le nom de la salle de formation sélectionnée.
|
III-B. Le Code VBA associé
Il nous faut donc savoir quel bouton a été cliqué par l'utilisateur. Pour cela, j'ai déclaré une variable boolAffichePlanningSalle de portée "Public"
et de type booléen. Par défaut, à l'ouverture du formulaire F_Planning, cette variable est positionnée sur "True".
En cliquant sur btnPlanningFormateurS et btnPlanningSalleS on affectera à celle-ci soit la valeur False soit la valeur True.
Voici le code associé au bouton btnPlanningSalleS sur l'évènement "sur souris relâchée":
Private Sub btnPlanningSalleS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call BasculerBouton("btnPlanningFormateurC", "btnPlanningFormateurR")
boolAffichePlanningSalle = True
lngRecordDepart = 0
lngCouleurfond = 8454016
lngCodeFormateur = 0
intDefilementSalle = 0
boolEOF = False
RecuperationEntetesLignes
GenerationPlanningSalles
End Sub
|
 |
On remarquera l'appel à deux routines :
- "RecuperationEntetesLignes" qui affiche soit les salles soit les formateurs.
- "GenerationPlanningSalles" qui est la routine déjà présentée dans la partie 1
|
Voici le code associé au bouton btnPlanningFormateurS sur l'évènement "sur souris relâchée":
Private Sub btnPlanningFormateurS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call BasculerBouton("btnPlanningSalleC", "btnPlanningSalleR")
boolAffichePlanningSalle = False
lngRecordDepart = 0
lngCouleurfond = 8454016
intDefilementSalle = 0
boolEOF = False
RecuperationEntetesLignes
GenerationPlanningFormateurs
End Sub
|
 |
On remarquera l'appel à deux routines :
- "RecuperationEntetesLignes" qui affiche soit les salles soit les formateurs.
- "GenerationPlanningFormateurs". J'ai préféré pour plus de clarté, réécrire la routine plutôt que de combiner les
instructions dans la routine "GenerationPlanningSalles"
|
L'objet de cette routine est triple :
- Récupérer les infos pour renseigner les étiquettes sur le côté gauche du planning.
- Récupérer les codes Formateurs pour renseigner les contrôles invisibles dans le formulaire (Ceux-ci seront nécessaires pour l'impression du planning du formateur).
- Créer la chaîne de critères utilisée dans l'extraction des données du planning.
Voyons cette routine.
Sub RecuperationEntetesLignes()
If boolAffichePlanningSalle = True Then
intCompteur = 1
strSallesConcernees = ""
Set rsSalles = CurrentDb.OpenRecordset(cstSalles)
With rsSalles
.MoveFirst
.Move lngRecordDepart
Do While Not .EOF
Me.Controls("lblNomSalle" & intCompteur).Caption = .Fields(1)
Me.Controls("txtCode" & intCompteur) = .Fields(0)
strSallesConcernees = strSallesConcernees & "," & Chr(34) & .Fields(1) & Chr(34)
intCompteur = intCompteur + 1
If intCompteur > 10 Then
Exit Do
Else
.MoveNext
End If
Loop
If .EOF Then
boolEOF = True
End If
End With
strSallesConcernees = Right(strSallesConcernees, Len(strSallesConcernees) - 1)
Else
intCompteur = 1
strFormateursConcernes = ""
Set rsFormateurs = CurrentDb.OpenRecordset(cstFormateurs)
With rsFormateurs
.MoveFirst
.Move lngRecordDepart
For intCompteur = 1 To 10
If .EOF Then
boolEOF = True
Me.Controls("lblNomSalle" & intCompteur).Caption = " "
Me.Controls("txtCode" & intCompteur) = 0
Else
Me.Controls("lblNomSalle" & intCompteur).Caption = .Fields(1)
Me.Controls("txtCode" & intCompteur) = .Fields(0)
strFormateursConcernes = strFormateursConcernes & "," & .Fields(0)
.MoveNext
End If
Next
End With
strFormateursConcernes = Right(strFormateursConcernes, Len(strFormateursConcernes) - 1)
End If
End Sub
|
 |
On remarque que dans la boucle, on renseigne les champs "lblNomSalle" avec les noms des salles ou des formateurs et "txtCode"
avec le CodeFormateur ou le CodeSalleFormation. Le codeFormateur servira lors de l'impression du planning du formateur.
Rien d'autre de particulier dans cette procédure, si ce n'est que le test de la variable boolAffichePlanningSalle dirige tout.
|
IV. LA MANIPULATION DES DONNEES
IV-A. Présentation
La manipulation des données n'est accessible qu'à partir du mode d'affichage "Salles".
Ainsi en cliquant sur une plage colorée, l'utilisateur se verra avertir par une boite de dialogue que la zone est déjà occupée
et que s'il le souhaite, il pourra intervenir sur la session en cours.
 |
Cependant, si l'utilisateur clique sur une zone du planning en mode "Formateurs", une boite de dialogue proposera de basculer en mode "Salles"
afin de pouvoir faire des modifications ou une réservation.
Ci-dessous le code VBA associé.
|
Sub Reservation()
If boolAffichePlanningSalle = False Then
intReponse = MsgBox("La réservation ou la modification n'est possible qu'en mode affichage ""Planning Salles""" & vbCrLf & _
"Souhaitez vous basculer dans ce mode d'affichage", vbQuestion + vbYesNo, cstDVP)
If intReponse = vbYes Then
Call BasculerBouton("btnPlanningFormateurC", "btnPlanningFormateurR")
If btnPlanningSalleS.Visible = True Then
Call BasculerBouton("btnPlanningSalleS", "btnPlanningSalleC")
Else
Call BasculerBouton("btnPlanningSalleR", "btnPlanningSalleC")
End If
boolAffichePlanningSalle = True
RecuperationEntetesLignes
GenerationPlanningSalles
End If
Else
RecuperationSalle
ControleDispoSalle
If boolReservationPossible = True Then
GenerationPlanningSalles
End If
End If
End Sub
|
L'affichage est donc repositionné en mode "Salles". Un clic sur une plage blanche génère alors la création d'une nouvelle réservation.
C'est en cliquant sur une des cases réservées d'une salle que le process de modification se met en route. Ce clic entraîne l'affichage du formulaire ci dessous.
Ce formulaire se décompose en deux parties :
- à gauche : les commandes.
- dans l'ardoise, les infos disponibles.
Par infos disponibles, j'entends les infos affichées en fonction du bouton choisi :
- bouton "Salle" : Liste les salles disponibles pour la période réservée de la formation.
- bouton "Date" : Affiche un calendrier afin de choisir le début de la nouvelle période.
- bouton "Formateur" : Liste les formateurs compétents et disponibles pour la période de la formation.
Lors de l'ouverture du formulaire, une procédure est lancée afin de reconnaître la formation concernée par la modification.
Private Sub Form_Open(Cancel As Integer)
Dim rsFormationConcernee As DAO.Recordset
Dim strSqlFormationConcernee As String
Set frmActif = Me
btnFermerR.Picture = CurrentProject.Path & "\image\btnFermerR.jpg"
btnFermerS.Picture = CurrentProject.Path & "\image\btnFermerS.jpg"
btnFermerC.Picture = CurrentProject.Path & "\image\btnFermerC.jpg"
btnSupprimerR.Picture = CurrentProject.Path & "\image\btnSupprimerR.jpg"
btnSupprimerS.Picture = CurrentProject.Path & "\image\btnSupprimerS.jpg"
btnSupprimerC.Picture = CurrentProject.Path & "\image\btnSupprimerC.jpg"
btnModifSalleR.Picture = CurrentProject.Path & "\image\btnModifSalleR.jpg"
btnModifSalleS.Picture = CurrentProject.Path & "\image\btnModifSalleS.jpg"
btnModifSalleC.Picture = CurrentProject.Path & "\image\btnModifSalleC.jpg"
btnModifDateR.Picture = CurrentProject.Path & "\image\btnModifDateR.jpg"
btnModifDateS.Picture = CurrentProject.Path & "\image\btnModifDateS.jpg"
btnModifDateC.Picture = CurrentProject.Path & "\image\btnModifDateC.jpg"
btnModifFormateurR.Picture = CurrentProject.Path & "\image\btnModifFormateurR.jpg"
btnModifFormateurS.Picture = CurrentProject.Path & "\image\btnModifFormateurS.jpg"
btnModifFormateurC.Picture = CurrentProject.Path & "\image\btnModifFormateurC.jpg"
strSqlFormationConcernee = "SELECT T_Stages.CodeStage, T_Stages.DateStageDebut, T_Catalogue.DureeStage, " _
& "T_NiveauFormation.LibelleNiveau, T_Catalogue.IntituleStage, " _
& "[NomFormateur] & "" "" & [PrenomFormateur] AS Formateur, T_Produits.CodeProduit, " _
& "T_NiveauFormation.CodeNiveau " _
& "FROM T_NiveauFormation " _
& "INNER JOIN (T_Produits " _
& "INNER JOIN (T_Catalogue " _
& "INNER JOIN (T_Formateur " _
& "INNER JOIN (T_SalleFormation " _
& "INNER JOIN T_Stages " _
& "ON T_SalleFormation.CodeSalleFormation = T_Stages.CodeSalleFormation) " _
& "ON T_Formateur.CodeFormateur = T_Stages.CodeFormateur) " _
& "ON T_Catalogue.CodeCatalogue = T_Stages.CodeCatalogue) " _
& "ON T_Produits.CodeProduit = T_Catalogue.CodeProduit) " _
& "ON T_NiveauFormation.CodeNiveau = T_Catalogue.CodeNiveau " _
& "WHERE T_Stages.CodeStage = " & lngCodeStage
Set rsFormationConcernee = CurrentDb.OpenRecordset(strSqlFormationConcernee)
With rsFormationConcernee
bytDureeFormation = .Fields(2)
lngCodeProduit = .Fields(6)
lngNiveau = .Fields(7)
lblMessage.Caption = "Formation n° : " & lngCodeStage & vbCrLf _
& "Intitule : " & .Fields(4) & vbCrLf _
& "Durée : " & IIf(bytDureeFormation = 1, bytDureeFormation _
& " jour", bytDureeFormation & " jours") & vbCrLf _
& "Début le : " & .Fields(1) & vbCrLf _
& "Formateur : " & .Fields(5)
varDateDebutFormation = .Fields(1)
varDateFinFormation = DateAdd("d", bytDureeFormation - 1, varDateDebutFormation)
End With
End Sub
|
Etant donné que les boutons "Salle", "Date", "Formateur" sont encadrés, il faut également envisager une procédure pour l'animation des boutons.
Celle-ci est affectée à l'évènement "sur souris déplacée" du contrôle "objEncadrementBoutons". On remarquera que cette procédure fait appel
à la procédure évènementielle "sur souris déplacée" de la zone Détail.
Private Sub objEncadrementBoutons_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call Détail_MouseMove(Button, Shift, X, Y)
End Sub
|
Private Sub Détail_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
btnFermerR.Visible = True
btnFermerS.Visible = False
btnFermerC.Visible = False
btnSupprimerR.Visible = True
btnSupprimerS.Visible = False
btnSupprimerC.Visible = False
btnModifSalleR.Visible = True
btnModifSalleS.Visible = False
btnModifSalleC.Visible = False
btnModifDateR.Visible = True
btnModifDateS.Visible = False
btnModifDateC.Visible = False
btnModifFormateurR.Visible = True
btnModifFormateurS.Visible = False
btnModifFormateurC.Visible = False
End Sub
|
IV-B. Les contrôles dans le formulaire
Hormis les boutons donc l'explication sur l'animation peut-être consultée dans la
partie 1 de l'article, ce formulaire contient dans l'ardoise, 3 autres
contrôles superposés (1).
- Une étiquette (lblMessage) qui affiche les infos sur la formation en cours de modification.
- Un contrôle calendrier (objCalendrier) qui permettra de sélectionner une nouvelle date (4).
- Une zone de liste (lstElementDispo) qui permettra d'afficher soit les salles (3) disponibles soit les formateurs (5) compétents et disponibles.
 |
Les numéros entre parenthèses indiquent le bouton utilisé (cf image du formulaire)
|
IV-C. Les Boutons du Formulaire
IV-C-1. Supprimer (2)
Le rôle de ce bouton est de supprimer la formation sélectionnée. Lors de la suppression de la formation, tous les enregistrements attachés de la table T_Planning seront
également supprimés.
(propriété de l'intégrité référentielle : Effacer en cascade les enregistrements correspondants).
Private Sub btnSupprimerS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim strDeleteStage As String
strDeleteStage = "DELETE CodeStage FROM T_Stages WHERE CodeStage = " & lngCodeStage
DoCmd.SetWarnings False
intReponse = MsgBox("Vous allez supprimer définitivement une formation !" _
& vbCrLf & "Souhaitez-vous continuer ?", vbQuestion + vbYesNo, cstDVP)
If intReponse = vbYes Then
DoCmd.RunSQL strDeleteStage
Else
MsgBox "La demande de suppression de la formation a été annulée !", vbInformation, cstDVP
End If
DoCmd.SetWarnings True
Set frmActif = Forms("F_Planning").Form
DoCmd.Close
GenerationPlanningSalles
End Sub
|
IV-C-2. Salle (3)
Le changement de salle nous amène à proposer à l'utilisateur une nouvelle salle à la condition qu'elle soit disponible pour la période demandée.
La procédure affiche alors toutes les salles disponibles pour la période de la formation concernée par la modification.
Pour faire une modification de salle, deux procédures seront nécessaires. Une première pour récupérer les salles disponibles qui se lance dès que je relâche le bouton
et une seconde qui relance le planning après avoir choisi une salle dans la liste (sur l'évènement "Après MAJ" de la liste lstElementDispo).
Ci dessous le code de la procédure du bouton btnModifSalleS sur l'évènement "sur souris relâchée".
Private Sub btnModifSalleS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim strSqlSallesReservees As String, strSallesOccupees As String
strSqlSallesReservees = "SELECT T_Stages.CodeStage, T_SalleFormation.CodeSalleFormation, T_Stages.DateStageDebut " _
& "FROM T_SalleFormation INNER JOIN T_Stages " _
& "ON T_SalleFormation.CodeSalleFormation = T_Stages.CodeSalleFormation " _
& "WHERE T_Stages.DateStageDebut Between #" & Format(varDateDebutFormation, "mm/dd/yy") _
& "# And #" & Format(varDateFinFormation, "mm/dd/yy") & "#"
Set rsSallesReservees = CurrentDb.OpenRecordset(strSqlSallesReservees)
With rsSallesReservees
Do While Not .EOF
strSallesOccupees = strSallesOccupees & "," & .Fields(1)
.MoveNext
Loop
End With
strSallesOccupees = Right(strSallesOccupees, Len(strSallesOccupees) - 1)
strSqlSallesReservees = "SELECT * FROM T_SalleFormation WHERE CodeSalleFormation NOT IN (" & strSallesOccupees & ")"
With lstElementDispo
.RowSourceType = "Table/Query"
.RowSource = strSqlSallesReservees
End With
lblFormationModif1.Caption = "Choisir une Salle"
lblFormationModif2.Caption = "Choisir une Salle"
lblMessage.Visible = False
objCalendrier.Visible = False
lstElementDispo.Visible = True
boolModifFormateur = False
End Sub
|
Voici le code associé à l'évènement "Après MAJ" de la liste lstElementDispo :
Private Sub lstElementDispo_AfterUpdate()
Dim strElementMAJ As String
DoCmd.SetWarnings False
If boolModifFormateur = False Then
strElementMAJ = "CodeSalleFormation"
Else
strElementMAJ = "CodeFormateur"
End If
strSQLMajStage = "UPDATE T_Stages SET " & strElementMAJ & " = " & lstElementDispo & _
" WHERE CodeStage = " & lngCodeStage
DoCmd.RunSQL strSQLMajStage
DoCmd.SetWarnings True
GenerationPlanningSalles
|