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
DoCmd.Close acForm, "F_ModifReservation"
End Sub
|
On remarquera que cette procédure servira pour les deux modifications (salle ou formateur) et que la mise à jour porte
uniquement sur la modification du code (Formateur ou Salle de formation).
IV-C-3. Date (4)
Pour modifier la date, un simple objet calendrier facilitera la tâche de l'utilisateur. Il apparaitra également dans l'ardoise.
L'affichage de celui-ci est donc attaché au bouton btnModifDateS sur l'évènement "sur souris relâchée".
Private Sub btnModifDateS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
lblFormationModif1.Caption = "Choisir une nouvelle Date"
lblFormationModif2.Caption = "Choisir une nouvelle Date"
objCalendrier.Visible = True
lblMessage.Visible = False
lstElementDispo.Visible = False
boolModifDate = True
End Sub
|
Après avoir choisi une nouvelle date, un contrôle de validité est effectué et le planning est redessiné.
Voici le code associé à l'objet objCalendrier sur l'évènement "sur Clic".
Private Sub objCalendrier_Click()
varDateDebutFormation = objCalendrier.Value
boolModifPossible = ControleReservation(varDateDebutFormation, bytDureeFormation)
If boolModifPossible = True Then
If ControleDispoFormateur(varDateDebutFormation, bytDureeFormation) = True Then
DoCmd.SetWarnings False
strSQLMajStage = "UPDATE T_Stages SET DateStageDebut = #" & Format(varDateDebutFormation, "mm/dd/yy") & _
"# WHERE CodeStage = " & lngCodeStage
DoCmd.RunSQL strSQLMajStage
For intCompteur = 0 To bytDureeFormation - 1
varDateFinFormation = Format(DateAdd("d", intCompteur, varDateDebutFormation), "mm/dd/yy")
strSQLMajStage = "UPDATE T_Planning SET DateStage = #" & varDateFinFormation & _
"# WHERE CodeStage = " & lngCodeStage & " AND Quantieme = " & intCompteur + 1
DoCmd.RunSQL strSQLMajStage
Next
DoCmd.SetWarnings True
GenerationPlanningSalles
DoCmd.Close acForm, "F_ModifReservation"
End If
End If
End Sub
|
On remarquera dans la procédure, l'utilisation d'une fonction personnalisée dont voici le détail ci-dessous :
Public Function ControleReservation(varDateChoisie, lngDureeFormation) As Boolean
Dim varDateFinReservation, varDateDebutReservation, strSqlWhereReservation As String
If Weekday(varDateChoisie) = vbFriday And lngDureeFormation > 1 Or _
Weekday(varDateChoisie) = vbThursday And lngDureeFormation > 2 Then
MsgBox "La formation est tronquée par une fin de semaine" & vbCrLf & "Veuillez revoir votre choix", vbCritical, cstDVP
boolReservationPossible = False
Else
varDateDebutReservation = Format(varDateChoisie, "mm/dd/yy")
varDateFinReservation = Format(DateAdd("d", lngDureeFormation - 1, varDateChoisie), "mm/dd/yy")
strSqlWhereReservation = " WHERE T_Stages.CodeSalleFormation = " & lngCodeSalleFormation _
& " AND DateStage BETWEEN #" & varDateDebutReservation _
& "# AND #" & varDateFinReservation & "#"
Set rsSallesReservees = CurrentDb.OpenRecordset(cstSallesReservees & strSqlWhereReservation)
With rsSallesReservees
If .RecordCount > 0 Then
If boolModifDate = False Then
Do While Not .EOF
If CDate(varDateFinReservation) >= Format(.Fields(1), "mm/dd/yy") Then
MsgBox "la salle est déjà occupée par une autre formation", vbCritical, cstDVP
boolReservationPossible = False
Exit Do
Else
.MoveNext
End If
Loop
Else
boolModifDate = False
boolReservationPossible = True
End If
Else
boolReservationPossible = True
End If
End With
End If
If boolReservationPossible = False Then
ControleReservation = False
Else
ControleReservation = True
End If
End Function
|
IV-C-4. Formateur (5)
L'intérêt de cette modification est de pouvoir affecter un autre formateur à la formation sélectionnée. Cependant,
le formateur choisi devra avoir la compétence et être disponible durant toute la session de la formation. Comme pour
le changement de salle, deux procédures seront nécessaires pour terminer la tâche.
- Afficher les formateurs compétents et disponibles.
- Mettre à jour la formation en fonction du nouveau formateur.
Dans un premier temps, découvrons le code associé au bouton btnModifFormateurS sur l'évènement "sur souris relâchée" :
Private Sub btnModifFormateurS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim strSqlFormateursReserves As String, strFormateursIndispos As String
Dim rsFormateurReserves As DAO.Recordset
lblFormationModif1.Caption = "Choisir un Formateur"
lblFormationModif2.Caption = "Choisir un Formateur"
strSqlFormateursReserves = "SELECT T_Formateur.CodeFormateur, T_Catalogue.CodeNiveau, T_Catalogue.CodeProduit, " & _
"T_Stages.DateStageDebut, T_Catalogue.DureeStage " & _
"FROM T_Formateur INNER JOIN (T_Catalogue INNER JOIN T_Stages " & _
"ON T_Catalogue.CodeCatalogue = T_Stages.CodeCatalogue) " & _
"ON T_Formateur.CodeFormateur = T_Stages.CodeFormateur " & _
"WHERE T_Stages.DateStageDebut Between #" & Format(varDateDebutFormation, "mm/dd/yy") & _
"# And #" & Format(DateAdd("d", bytDureeFormation - 1, varDateDebutFormation), "mm/dd/yy") & "#"
Set rsFormateurReserves = CurrentDb.OpenRecordset(strSqlFormateursReserves)
With rsFormateurReserves
If .RecordCount > 0 Then
Do While Not .EOF
strFormateursIndispos = strFormateursIndispos & "," & .Fields(0)
.MoveNext
Loop
Else
MsgBox "Il n'y a pas de formateurs disponibles pour la date choisie" _
& vbCrLf & "Veuillez refaire votre choix", vbInformation, cstDVP
Exit Sub
End If
End With
strFormateursIndispos = Right(strFormateursIndispos, Len(strFormateursIndispos) - 1)
strSqlFormateursReserves = "SELECT T_Formateur.CodeFormateur, " _
& "[Civilite] & "" "" & [NomFormateur] & "" "" & [PrenomFormateur] AS Formateur " _
& "FROM T_Formateur INNER JOIN T_ProduitEnseigne " & _
"ON T_Formateur.CodeFormateur = T_ProduitEnseigne.CodeFormateur " & _
"WHERE T_ProduitEnseigne.CodeNiveau = " & lngNiveau _
& " AND T_ProduitEnseigne.CodeProduitEnseigne = " & lngCodeProduit & _
"AND T_Formateur.CodeFormateur NOT IN(" _
& strFormateursIndispos & ") ORDER BY NomFormateur"
Set rsFormateurReserves = CurrentDb.OpenRecordset(strSqlFormateursReserves)
If rsFormateurReserves.RecordCount = 0 Then
MsgBox "Il n'y a pas de formateurs disponibles pour cette formation à cette date", vbInformation, cstDVP
Exit Sub
End If
lblMessage.Visible = False
objCalendrier.Visible = False
With lstElementDispo
.RowSourceType = "Table/Query"
.RowSource = strSqlFormateursReserves
.Visible = True
End With
boolModifFormateur = True
End Sub
|
La seconde s'exécute sur l'évènement "Après MAJ" de la liste lstElementDispo. C'est la variable "boolModifFormateur" qui
permettra de modifier soit le CodeFormateur soit le CodeSalleFormation.
Voici donc, pour rappel, la procédure utilisée :
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
DoCmd.Close acForm, "F_ModifReservation"
End Sub
|
V. IMPRIMER LES DONNEES
V-A. Présentation
Pour respecter le Cahier des Charges, nous aurons deux impressions:
- L'impression globale en partant du bouton "Imprimer" en affichage "Salles".
- L'impression du planning d'un formateur en cliquant sur le nom du Formateur.
V-B. Principe du Planning
L'impression d'un planning se divise en deux parties. D'une part "SE_Planning" qui représente la partie graphique (les "petites cases colorées") et d'autre part,
"SE_DetailFormation" qui reprend le détail des différentes formations regroupées par salle.
Chaque partie fait l'objet d'un sous-état, les deux sous-états étant regroupés dans un état indépendant "E_Planning". A noter que les mêmes structures seront utilisées
aussi bien pour l'impression des salles que pour l'impression du planning du Formateur.
V-C. Le sous-état SE_DetailFormation
Cet état est un état classique avec un niveau de regroupement : La salle de Formation.
Comme cet état servira pour les deux impressions, la source lui sera affectée lors de l'ouverture de celui-ci en fonction de la valeur de la variable "boolAffichePlanningSalle".
Voyons la procédure VBA attachée à l'évènement "sur ouverture de l'état".
Private Sub Report_Open(Cancel As Integer)
Dim strSqlImpressionSousEtat As String, strSqlWhereSousEtat As String
strSqlImpressionSousEtat = "SELECT T_Catalogue.IntituleStage, T_NiveauFormation.LibelleNiveau, " & _
"IIf([DureeStage]>1,[DureeStage] & "" jours"",[DureeStage] & "" jour"") AS Duree, " & _
"[Civilite] & "" "" & [NomFormateur] & "" "" & [PrenomFormateur] AS Formateur, " & _
"T_Stages.DateStageDebut, T_SalleFormation.NomSalleFormation, " & _
"T_Produits.NomProduit, T_Formateur.CodeFormateur " & _
"FROM T_SalleFormation " & _
"INNER JOIN (T_Produits " & _
"INNER JOIN (T_NiveauFormation " & _
"INNER JOIN (T_Formateur " & _
"INNER JOIN (T_Catalogue " & _
"INNER JOIN T_Stages " & _
"ON T_Catalogue.CodeCatalogue=T_Stages.CodeCatalogue) " & _
"ON T_Formateur.CodeFormateur=T_Stages.CodeFormateur) " & _
"ON T_NiveauFormation.CodeNiveau=T_Catalogue.CodeNiveau) " & _
"ON T_Produits.CodeProduit=T_Catalogue.CodeProduit) " & _
"ON T_SalleFormation.CodeSalleFormation=T_Stages.CodeSalleFormation "
If boolAffichePlanningSalle = True Then
strSqlWhereSousEtat = "WHERE T_Stages.DateStageDebut Between #" _
& Format(varDateDebutPlanning, "mm/dd/yy") & _
"# And #" & Format(varDateFinPlanning, "mm/dd/yy") & "#"
Else
strSqlWhereSousEtat = "WHERE T_Stages.DateStageDebut Between #" _
& Format(varDateDebutPlanning, "mm/dd/yy") & _
"# And #" & Format(varDateFinPlanning, "mm/dd/yy") _
& "# AND T_Formateur.CodeFormateur = " & lngCodeFormateur
End If
Me.RecordSource = strSqlImpressionSousEtat & strSqlWhereSousEtat
End Sub
|
Enfin, afin d'assurer une meilleure lisibilité des lignes de l'état, j'affecte une couleur sur les lignes paires via
une procédure attachée à l'évènement "sur formatage" de la section Détail.
Voyons le détail ci-dessous :
Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
Static lngNumLigne As Long
If lngNumLigne Mod 2 = 0 Then
Détail.BackColor = 11206570
Else
Détail.BackColor = 16777215
End If
lngNumLigne = lngNumLigne + 1
End Sub
|
V-D. Le sous-état SE_Planning
A propos de ce sous-état, deux remarques importantes :
- Il faut représenter la partie graphique. Il nous fait donc récupérer la couleur des plages de réservation.
Je récupère donc les informations nécessaires à la représentation graphique dans une table. Cette table servira aussi bien pour la version "Salles"
que pour la version "Formateur". La génération de la table est lancée en cliquant soit sur le bouton "Imprimer" soit sur le nom du Formateur dont on souhaite
imprimer le planning.
- Tous les contrôles de l'état sont des contrôles indépendants dont la source sera affectée au formatage de l'état.
Découvrons ci-dessous le process de la création de la table :
Private Sub btnImprimerS_Click()
Dim rsImprimerPlanning As DAO.Recordset, rsTypeImprimer As DAO.Recordset
Dim strSqlImprimerPlanning As String, strSqlDeleteImpressionPlanning As String, strSqlFormateurImprime As String
Dim varDateBoucle
Dim lngCodeSalleEnCours As Long, lngCodeSallePrecedente As Long
Dim intCompteurColonnes As Integer, intCompteurLignes, strInfoBulle As String
Dim boolReservation As Boolean, boolEOFPlanning As Boolean
Const cstCouleurWeekEnd As Long = 8454143, cstCouleurVide As Long = 16777215
On Error Resume Next
strSqlImprimerPlanning = "SELECT * FROM T_ImpressionPlanning"
strSqlDeleteImpressionPlanning = "DELETE CodeSalleFormation FROM T_ImpressionPlanning " & _
"WHERE CodeSalleFormation Is Not Null"
If boolAffichePlanningSalle = True Then
strSqlPlanning = " Where DateStage BETWEEN #" & Format(CDate(varDateDebutPlanning), "mm/dd/yy") _
& "# AND #" & Format(varDateFinPlanning, "mm/dd/yy") _
& "# ORDER BY T_SalleFormation.CodeSalleFormation, T_Planning.DateStage"
Else
If lngCodeFormateur = 0 Then
MsgBox "L'impression d'un formateur se fait en cliquant sur le nom du formateur concerné", vbCritical, cstDVP
Exit Sub
End If
strSqlPlanning = " Where DateStage BETWEEN #" & Format(CDate(varDateDebutPlanning), "mm/dd/yy") _
& "# AND #" & Format(varDateFinPlanning, "mm/dd/yy") _
& "# AND T_Formateur.CodeFormateur = " & Controls("txtCode" & intNumLigne) _
& " ORDER BY T_Planning.DateStage"
lngCodeFormateur = Controls("txtCode" & intNumLigne)
strSqlFormateurImprime = " Where CodeFormateur = " & lngCodeFormateur
End If
DoCmd.SetWarnings False
DoCmd.RunSQL strSqlDeleteImpressionPlanning
Set rsImprimerPlanning = CurrentDb.OpenRecordset(strSqlImprimerPlanning)
If boolAffichePlanningSalle = True Then
Set rsTypeImprimer = CurrentDb.OpenRecordset(cstSalles)
Else
Set rsTypeImprimer = CurrentDb.OpenRecordset("SELECT * FROM T_Formateur " & strSqlFormateurImprime)
End If
If boolAffichePlanningSalle = True Then
Set rsPlanning = CurrentDb.OpenRecordset(cstPlanning & strSqlPlanning)
Else
Set rsPlanning = CurrentDb.OpenRecordset(cstPlanningFormateur & strSqlPlanning)
End If
Do While Not rsTypeImprimer.EOF
lngCodeSalleEnCours = rsTypeImprimer.Fields(0)
For varDateTraitee = CDate(varDateDebutPlanning) To varDateFinPlanning
If boolEOFPlanning = True Then
GoTo Reprise
Else
If rsPlanning.Fields(8) <> lngCodeSalleEnCours Then
GoTo Reprise
ElseIf rsPlanning.Fields(1) = varDateTraitee Then
rsImprimerPlanning.AddNew
rsImprimerPlanning.Fields(0) = lngCodeSalleEnCours
rsImprimerPlanning.Fields(1) = CDate(varDateTraitee)
rsImprimerPlanning.Fields(2) = rsPlanning.Fields(6)
rsImprimerPlanning.Update
If rsPlanning.EOF Then
boolEOFPlanning = True
Else
rsPlanning.MoveNext
End If
Else
Reprise:
If Weekday(varDateTraitee) = vbSaturday Or Weekday(varDateTraitee) = vbSunday Then
rsImprimerPlanning.AddNew
rsImprimerPlanning.Fields(0) = lngCodeSalleEnCours
rsImprimerPlanning.Fields(1) = CDate(varDateTraitee)
rsImprimerPlanning.Fields(2) = cstCouleurWeekEnd
rsImprimerPlanning.Update
Else
rsImprimerPlanning.AddNew
rsImprimerPlanning.Fields(0) = lngCodeSalleEnCours
rsImprimerPlanning.Fields(1) = CDate(varDateTraitee)
rsImprimerPlanning.Fields(2) = cstCouleurVide
rsImprimerPlanning.Update
End If
End If
End If
Next
rsTypeImprimer.MoveNext
Loop
DoCmd.SetWarnings True
DoCmd.OpenReport "E_Planning", acViewPreview
End Sub
|
On remarquera que la dernière instruction de la procédure ouvre l'état en mode aperçu, ce qui entraînera l'activation des diverses
procédures de mise en place des sous-états. Nous avons vu précédemment les procédures du sous-état SE_DetailFormation, voyons maintenant
celles concernant le sous-état SE_Planning.
Dans un premier temps voici la procédure affectée à l'ouverture du sous-état.
Private Sub Report_Open(Cancel As Integer)
If boolAffichePlanningSalle = True Then
Set rsImpression = CurrentDb.OpenRecordset("R_PrepaImpression")
Else
Set rsImpression = CurrentDb.OpenRecordset("R_PrepaImpressionFormateurs")
End If
End Sub
|
Cette procédure a pour objet d'affecter une requête source à notre état. Celle-ci pourra être une des deux requêtes "Analyse croisée" dont voici les structures :
 |
On remarquera dans la requête R_PrepaImpressionFormateur, la concaténation du nom et du prénom du formateur.
|
Voyons maintenant la procédure qui est affectée à l'évènement "au formatage" de l'entête d'état :
Private Sub EntêteÉtat_Format(Cancel As Integer, FormatCount As Integer)
intCompteur = 2
With rsImpression
lblTitre1.Caption = "Planning du " & Format(varDateDebutPlanning, "dd mmm yy") & " au " & Format(varDateFinPlanning, "dd mmm yy")
lblTitre2.Caption = "Planning du " & Format(varDateDebutPlanning, "dd mmm yy") & " au " & Format(varDateFinPlanning, "dd mmm yy")
For Each ctlEtiquette In EntêteÉtat.Controls
If Left(ctlEtiquette.Name, 7) = "lblJour" Then
ctlEtiquette.Caption = Format(.Fields(intCompteur).Name, "dd mmm yy")
intCompteur = intCompteur + 1
End If
Next
End With
rsImpression.MoveFirst
End Sub
|
 |
Deux remarques :
Les étiquettes des dates sont implantées via une boucle sur le nom des champs du jeu d'enregistrements.
On peut voir deux contrôles "lblTitre". En fait, il s'agit là simplement de deux étiquettes légèrement décalées pour donner un effet de relief.
|
Enfin, abordons la dernière procédure, celle qui est attachée "au formatage" de la section Détail de l'état.
Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
txtNomSalle.Caption = rsImpression.Fields(1)
intCompteur = 2
With rsImpression
For Each ctlEtiquette In Détail.Controls
If Left(ctlEtiquette.Name, 10) = "lblIndispo" Then
ctlEtiquette.BackColor = Nz(.Fields(intCompteur), 16777215)
intCompteur = intCompteur + 1
End If
Next
.MoveNext
End With
End Sub
|
 |
Deux remarques :
On initialise la variable intCompteur à 2 puisque le premier champ contenant un code couleur est le troisième champ du jeu d'enregistrements.
On utilise ici la valeur du champ que l'on affecte à la propriété "BackColor" de chaque pavé du planning.
|
VI. LA NOTIFICATION
VI-A. Présentation
Nous allons maintenant développer la partie Notification.
Nous allons créer un formulaire permettant de sélectionner le formateur ainsi qu'une période (comprise entre deux dates).
A partir de ce formulaire, nous utiliserons la méthode SendObject,
méthode qui permet d'envoyer un objet par la messagerie , en l'occurrence ce sera un état filtré sur le formateur et la période.
VI-A-1. Le Formulaire
 |
Voici à quoi ressemblera le Formulaire de notification.
Par défaut les dates et la semaine correspondent à la semaine en cours lors de l'ouverture du formulaire. La liste des formateurs
est conditionnée, dans un premier temps par la période et dans un second temps par les formateurs possédant une adresse Mail.
Si rien ne s'affiche c'est qu'il n'y a aucune formation pour les formateurs possédant un E-mail.
|
VI-A-2. Fonctionnement du formulaire
 |
Pour envoyer le planning correspondant à un formateur, il vous suffit de sélectionner le formateur et de cliquer sur le bouton Valider.
L'état correspondant au planning du formateur de la période sélectionnée est placé en tant que pièce jointe dans un nouvel E-mail.
Dans la fenêtre Outlook l'expéditeur, le sujet ainsi que le corps du message seront déjà renseignés il vous sera alors possible de modifier ou d'ajouter d'autres informations.
|
VI-A-3. Structure du formulaire
VI-A-3-a. Description des contrôles
 |
Voici donc la description des différents objets contenus dans le formulaire F_Notification.
|
| Nom du Contrôle |
Type de Contrôle |
Fonction |
| btnFermerR |
image |
L'effet relâché : Visible par défaut, sera la première image |
| btnFermerS |
image |
L'effet survolé : Placée sous l'image 1, sera visible lors du passage de la souris sur le "bouton relâché". |
| btnFermerC |
image |
L'effet cliqué : Placée sous l'image 2, sera rendu visible lorsque l'on appuie sur le bouton de la souris. |
| btnValiderR |
image |
L'effet relâché : Visible par défaut, sera la première image de la pile. |
| btnValiderS |
image |
L'effet survolé : Placée sous l'image 1, sera visible lors du passage de la souris sur le "bouton relâché". |
| btnValiderC |
image |
L'effet cliqué : Placée sous l'image 2, sera rendu visible lorsque l'on appuie sur le bouton de la souris. |
| txtCacheFormateur |
Champ Texte |
Ce champ est non visible, il permet de stocker la valeur du formateur pour l'exportation de l'état afin de réaliser l'envoi de l'E-mail. |
| lstSemaine |
Zone de liste déroulante |
Stocke les semaines de l'année de 1 à 53. |
| txtDu |
Champ Texte |
Stocke la date correspondant au lundi de la semaine en cours. |
| txtAu |
Champ Texte |
Stocke la date correspondant au vendredi de la semaine en cours. |
| lstFormateur |
Zone de liste |
Permet d'afficher le nom des formateurs ayant une adresse mail. |
VI-A-3-b. Les propriétés des contrôles
VI-A-3-b-i. La zone de liste déroulante : lstSemaine
 |
Nous mettrons comme origine Source : Liste Valeurs.
Nous alimenterons cette liste lors de l'ouverture du Formulaire par VBA
|
VI-A-3-b-ii. Zones de Texte : txtDu et txtAu
 |
Nous mettrons comme masque de saisie : 00/00/0000;0;_
Ceci permet de définir la forme de la date.
|
VI-A-3-b-iii. Zone de liste : lsFormateur
Voici ci-dessous la structure de la requête source de la liste :
SELECT T_Formateur.CodeFormateur, [Civilite] & " " & [NomFormateur] & " " & [PrenomFormateur] AS Formateur
FROM T_Formateur INNER JOIN T_Stages ON T_Formateur.CodeFormateur = T_Stages.CodeFormateur
WHERE (((T_Stages.DateStageDebut) Between [Formulaires]![F_Notification]![txtDu] And [Formulaires]![F_Notification]![txtAu])
AND ((T_Stages.CodeFormateur) Is Not Null))
GROUP BY T_Formateur.CodeFormateur, [Civilite] & " " & [NomFormateur] & " " & [PrenomFormateur], T_Formateur.Email
HAVING (((T_Formateur.Email) Is Not Null));
|
VI-B. Le Code VBA dans le formulaire
Dans un premier temps nous allons exécuter un code permettant d'initialiser :
- les images servant de boutons.
- la liste pour les semaines ainsi que les dates.
Ce code s'exécutera à l'ouverture du Formulaire
Private Sub Form_Open(Cancel As Integer)
Dim i As Long
Set frmActif = Me
Me.btnFermerR.Picture = CurrentProject.Path & "\Image\btnFermerR.jpg"
Me.btnFermerS.Picture = CurrentProject.Path & "\Image\btnFermerS.jpg"
Me.btnFermerC.Picture = CurrentProject.Path & "\Image\btnFermerC.jpg"
Me.objArdoise.Picture = CurrentProject.Path & "\Image\Ardoise.jpg"
Me.btnValiderR.Picture = CurrentProject.Path & "\Image\btnValiderR.jpg"
Me.btnValiderS.Picture = CurrentProject.Path & "\Image\btnValiderS.jpg"
Me.btnValiderC.Picture = CurrentProject.Path & "\Image\btnValiderC.jpg"
Me.txtCacheFormateur.Visible = False
For i = 0 To 53
lstSemaine.AddItem i
Next i
lstSemaine = DatePart("ww", Date, vbMonday, vbFirstFourDays)
txtDu = CDate(calculDate(Format(Now, "ww")))
txtAu = txtDu + 4
lstFormateur.Requery
End Sub
|
Dans le code précédent nous initialisons les images qui nous servent de bouton,
ensuite nous réalisons une boucle pour alimenter la liste de choix utilisée pour les semaines.
En dernier lieu nous récupérons la date du lundi de la semaine en cours.
Pour cela nous appellerons une fonction située en fin du module du Formulaire.
Nous réalisons en fin de code une régénération de la source de la liste des formateurs, la source est conditionnée par la date de début et de fin,
par l'existence de formations entre ces dates et enfin par l'existence d'une adresse mail pour le formateur.
Si rien n'est affiché dans la liste c'est qu'aucune formation n'est prévue entre ces dates.
Voici le code de la fonction qui calcule la date du lundi de la semaine en cours.
Function calculDate(sem As String) As Date
Dim calcultemp As Date
Dim calculjour As Long
calculsem = (sem - (DatePart("ww", Date, vbMonday, vbFirstFourDays))) * 7 + Date
calculjour = 1 - DatePart("w", calculsem, vbMonday, vbFirstFourDays)
calculDate = calculsem + calculjour
End Function
|
Nous allons mettre à jour les zones de texte txtDu et txtAu sur l'évènement "Après MAJ" de liste déroulante lstSemaine.
Ici nous appellerons également la fonction calculDate
Private Sub lstSemaine_AfterUpdate()
txtDu = CDate(calculDate(lstSemaine))
txtAu = txtDu + 4
lstFormateur.Requery
End Sub
|
Nous allons également mettre du code après la mise à jour des zones de texte txtDu et txtAu.
Celui-ci permettra de régénérer la source de liste lstFormateur en fonction des nouvelles dates.
Private Sub txtAu_AfterUpdate()
lstFormateur.Requery
End Sub
Private Sub txtDu_AfterUpdate()
lstFormateur.Requery
End Sub
|
Maintenant nous allons mettre le code concernant le bouton Valider. Celui-ci sera placé sur l'évènement "Sur Souris relâchée"
de l'image btnValiderS
Private Sub btnValiderS_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim varSelection As Variant
Dim strMail As String
On Error GoTo errValider
Call BasculerBouton("btnValiderC", "btnValiderS")
For Each varSelection In lstFormateur.ItemsSelected
strMail = DLookup("[Email]", "T_Formateur", "[CodeFormateur]=" & lstFormateur.ItemData(varSelection))
txtCacheFormateur.Value = lstFormateur.ItemData(varSelection)
DoCmd.SendObject acSendReport, "E_Notification", acFormatPDF, strMail, , , _
"Votre planning du " & txtDu & " au " & txtAu, _
"Ci-joint votre planning pour la période du " & txtDu & " au " & txtAu
Next varSelection
Exit Sub
errValider:
Select Case Err.Number
Case "2501"
MsgBox "L'E-mail n'a pas été envoyé," & vbCr & _
"Veuillez recommencer ou contacter l'administrateur de la base", _
vbCritical, cstDVP
Case Else
MsgBox "Erreur N° " & Err.Number & vbCr & "Description : " _
& Err.Description, vbCritical, cstDVP
End Select
End Sub
|
Expliquons un peu ce code :
- Déclarations des variables.
- Appel de la routine d'erreur si le code suivant soulève une erreur, l'appel permet d'intercepter cette erreur.
- Appel de la routine de gestion d'affichage des boutons pour remettre la visualisation nickel.
- Ensuite nous entrons dans une boucle qui liste toutes les sélections de la zone de liste lstFormateur.
Ceci permet de récupérer chaque Formateur sélectionné afin de lui envoyer son planning par E-mail.
Dans un premier temps nous récupérons l'adresse Mail du formateur par la méthode DLookup pour plus d'information sur les fonctions de domaine lire
ici.
Ensuite nous chargeons la valeur du code formateur dans la zone de texte cachée, ceci permet à la requête construisant l'état de venir piocher dans la zone pour filtrer.
Puis, nous envoyons via la messagerie l'état par la méthode SendObject. Si aucune erreur n'est levée par Access nous sortons de la procédure, dans le cas contraire nous passons par la routine d'erreur.
Si l'erreur correspond à l'erreur 2501 nous affichons un message personnalisé dans le cas contraire nous affichons le code d'erreur ainsi que la description et nous sortons de la procédure.
Sur le bouton Fermer nous mettrons simplement la fermeture du formulaire :
VII. CONCLUSION
Nous disposons maintenant d'un outil beaucoup plus complet. L'idée générale de ce tutoriel étant de donner une piste, un moyen de représenter graphiquement un planning,
à chacun maintenant de personnaliser ou de s'inspirer de cet exemple pour se lancer dans sa propre gestion.
VIII. TELECHARGEMENT
IX. REMERCIEMENTS
Mes premiers remerciements iront à
Dolphy35 (Morgan Billy) qui a développé la partie "Notification" de cet article.
Ensuite à
Fring pour son temps passé à une relecture attentive.
Enfin à toute l'équipe de DVP, toujours présente pour conseiller et soutenir.


Copyright © 2008 Jean BALLAT. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts. Droits de diffusion permanents accordés à developpez LLC.
Cette page est déposée à la
SACD.