Planning pour la gestion des présences et des absences

Objectif : créer un formulaire de planning pour gérer les heures de présence et les absences du personnel.

Niveau requis : intermédiaire.

Commentez cet article : 11 commentaires Donner une note  l'article (5)

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Sur le forum Access de nombreuses questions sont relatives à la planification.

L'objectif de cet article est de montrer comment réaliser un exemple simple de planning pour gérer les heures de présence et les absences des employés.

Pour ce faire, après avoir donné un aperçu du formulaire souhaité, on présentera dans l'ordre de leur création les différents objets de l'application :

  • tables nécessaires ;
  • requêtes ;
  • formulaires ;
  • module M_Planning.

Pour conclure, on proposera un exemple de paramétrage du planning.

II. Aperçu du formulaire de planning

Voici le rendu du planning avec les heures de présence et les absences du personnel pour le mois choisi :

Image non disponible
Planning mensuel

Il comporte, en tête des lignes, les noms des personnes et, en tête des colonnes, les jours du mois.

L'ajout ou la suppression d'une absence se faisant naturellement par un double clic dans la case correspondante.

III. Tables nécessaires

Nous allons tout d'abord détailler les tables permettant d'enregistrer les données.

III-A. Table T_Employe

Elle contient simplement la liste des nom et prénom des employés de l'entreprise accompagnés de leur identifiant.

Structure de la table :

Nom du champ

Type de données

Description

IdEmploye

Entier long

Identifiant de l'employé

NomEmploye

Texte

Nom de l'employé

PrenomEmploye

Texte

Prénom de l'employé

Exemple de données enregistrées dans la table :

IdEmploye

NomEmploye

PrenomEmploye

1

AUDINET

Noël

2

DE GIORGI

Aldo

Vous pouvez naturellement ajouter à cette table d'autres champs comme la date d'entrée et de sortie de l'employé.

III-B. Table T_PeriodeJour

Elle contient les deux périodes de la journée : matin ou après-midi.

Structure de la table :

Nom du champ

Type de données

Description

PeriodeJour

Texte

Période de la journée : matin ou après-midi

NumOrdre

Entier long

Numéro d'ordre de la période, pour ordonner les périodes

Exemple de données enregistrées dans la table :

PeriodeJour

NumOrdre

Matin

1

Après-midi

2

III-C. Table T_Planning

Elle sert à enregistrer les absences ou le nombre d'heures effectuées par l'employé à une date et à une période données.

Structure de la table :

Nom du champ

Type de données

Description

IdPlanning

Numéro-auto

Identifiant

IdEmploye

Entier long

Identifiant de l'employé

DateJour

Date

Date du jour de présence ou d'absence de l'employé

PeriodeJour

Texte

Période de la journée : matin ou après-midi

IdMotifAbsence

Texte

Code du motif d'absence de l'employé (MA : Maladie, MT : Materinité, F : Formation, P : Présence…)

NbHeures

Numérique

Nombre d'heures à effectuer si présent

Exemple de données enregistrées :

IdPlanning

IdEmploye

DateJour

PeriodeJour

IdMotifAbsence

NbHeures

59

20

14/10/2019

Matin

F

 

60

20

15/10/2019

Matin

F

 

61

20

16/10/2019

Matin

F

 

En plus de l'identifiant de l'employé, il nous faut donc sauvegarder la date et la période du jour (matin, après-midi).

III-D. Table T_MotifAbsence

Elle contient la liste des motifs d'absence que peut avoir un employé.

Structure de la table :

Nom du champ

Type de données

Description

IdMotifAbsence

Texte

Identifiant du motif d'absence (MA : Maladie, MT : Materinité, F : Formation…)

MotifAbsence

Texte

Intitulé du motif de l'employé (Maladie, Maternité, Formation, Personnel…)

Exemple de données enregistrées :

IdMotifAbsence

MotifAbsence

AC

Accident

C

Congé

F

Formation

IV. Requêtes

Pour pouvoir afficher le tableau des heures de présence et des absences, avec en lignes les employés et en colonnes les jours du mois, il nous faut créer une requête analyse croisée.

Pour cela, on va d'abord créer les requêtes R_Planning et R_PersonnelPeriodeJour, puis la requête R_PlanningEmploye basée sur les deux premières.

Détaillons donc ces différents objets.

IV-A. Requête R_Planning

Cette requête, basée sur la table T_Planning, affiche la liste des heures de présence et les absences des employés pour le mois et l'année sélectionnés sur le formulaire.

Elle a donc comme paramètres les listes déroulantes cmbMois et cmbAnnee du formulaire F_Planning.

Structure de la requête :

Image non disponible
Requête R_Planning en mode création.

Formule utilisant la fonction vraifaux(condition; sivrai; sifaux) pour afficher les motifs d'absence ou le nombre d'heures effectuées par l'employé :

 
Sélectionnez
AbsPres: VraiFaux(EstNull([IdMotifAbsence]);[NbHeures];[IdMotifAbsence])

S'il n'y a pas de motif d'absence, elle renvoie le nombre d'heures, sinon le résultat de la fonction est simplement le motif d'absence.

Exemple d'affichage de la requête pour le mois d'octobre de l'année 2019 :

IdEmploye

DateJour

PeriodeJour

AbsPres

20

15/10/2019

Matin

F

20

16/10/2019

Matin

F

20

17/10/2019

Matin

F

20

18/10/2019

Matin

F

Ici, on a enregistré comme motif d'absence « F » pour « Formation ».

IV-B. Requête R_EmployePeriodeJour

Cette requête effectue le produit cartésien entre les tables T_Employe et T_PeriodeJour, elle affiche donc pour chaque employé, les deux périodes de la journée (matin, après-midi).

Structure de la requête :

Image non disponible
Requête R_EmployePeriodeJour en mode création.

Exemple d'affichage de la requête :

Employe

IdEmploye

PeriodeJour

NumOrdre

BOLLANI Marc

10

Matin

1

BOLLANI Marc

10

Après-midi

2

CAILLE Michel

25

Matin

1

CAILLE Michel

25

Après-midi

2

Les données sont classées par employé et numéro d'ordre de la période.

IV-C. Requête R_PlanningEmploye

Cette requête réalise une jointure gauche entre les requêtes R_PersonnelPeriodeJour et R_Planning. Elle permet d'afficher tous les employés, ainsi que leurs nombres d'heures ou leurs absences enregistrés dans le mois.

Structure de la requête :

Image non disponible
Requête R_PlanningEmploye en mode création.

On effectue une jointure gauche entre les deux requêtes pour pouvoir afficher tous les employés et leurs périodes.

Exemple d'affichage de la requête pour le mois d'octobre de l'année 2019 :

Employe

IdEmploye

PeriodeJour

NumOrdre

JourMois

AbsPres

BOLLANI Marc

10

Matin

1

15

F

BOLLANI Marc

10

Après-midi

2

16

F

CAILLE Michel

25

Matin

1

17

F

CAILLE Michel

25

Après-midi

2

18

F

Ici, on a enregistré comme motif d'absence « F » pour « Formation ».

IV-D. Requête R_Planning_Analyse_Croisee

Elle se base sur la requête R_PlanningEmploye, et affiche un tableau avec en tête des lignes les noms des employés et les périodes du jour, en tête des colonnes les jours du mois choisi (1,2,3…31), et à l'intersection des lignes et des colonnes le motif de l'absence ou le nombre d'heures réalisées par l'employé.

Structure de la requête :

Image non disponible
Requête R_Planning_Analyse_Croisee en mode création.

Exemple d'affichage de la requête pour le mois d'octobre de l'année 2019 :

Image non disponible
Affichage de la requête R_Planning_Analyse_Croisee

V. Formulaires

La troisième étape consiste à créer les formulaires.

V-A. Sous-formulaire SF_Planning

Ce formulaire, en mode continu, est relié à la requête analyse croisée. Il contient les zones de texte Employe, IdEmploye et PeriodeJour, pour les en-têtes de lignes, et les 31 zones de texte reliées aux jours du mois (1,231) :

Image non disponible
Sous-formulaire SF_Planning en mode création

V-A-1. Zones de texte « Jour.. »

Les 31 zones de texte (Jour1..Jour31) reliées aux champs 1..31, correspondant aux 31 colonnes de la requête analyse croisée.

V-A-1-a. Mise en forme conditionnelle

En mode création du sous-formulaire, on sélectionne une zone de texte associé à un jour, puis dans le menu Format, on choisit mise en forme conditionnellemise en forme conditionnelle, enfin, on définit les différentes couleurs en fonction des motifs d'absence (MA : Maladie, MT : Materinité, F : Formation, P : Personnel) :

Image non disponible
Définition de la mise en forme conditionnelle des zones de texte.

V-A-1-b. Procédure évènementielle sur Double clic

Cette procédure permet d'ouvrir le formulaire F_SaisiePlanning sur l'employé, la période et le jour correspondant à la case double cliquée sur le planning.

Le code sur l'événement ouverture du sous-formulaire et permettant d'affecter la fonction d'ouverture du formulaire de saisie à la propriété double clic des zones de texte Jour1..31 :

 
Sélectionnez
Private Sub Form_Open(Cancel As Integer)
    Dim j As Long
    ...
    For j = 1 To 31 ' parcours des 31 zones de texte liées aux jours
        ' affectation de la fonction à la propriété OnDblClick des zones de texte liées aux jours
        Me("Jour" & j).OnDblClick = "=OuvrirFormSaisie(" & j & ")"
    Next j
End Sub

V-A-2. Fonction OuvrirFormSaisie

Cette fonction publique fait partie du module M_Planning et permet d'ouvrir le formulaire F_SaisiePlanning sur l'employé et le jour correspondant à la case double cliquée sur le planning :

 
Cacher/Afficher le codeSélectionnez

V-B. Formulaire F_Planning

Il contient les zones de listes déroulantes cmbMois et cmbAnnee, les boutons de commande pour avancer ou reculer d'un mois, et le sous-formulaire SF_Planning.

Image non disponible
Formulaire F_Planning en mode création

V-B-1. Liste déroulante cmbMois

Ce contrôle est utilisé pour permettre à l'utilisateur de sélectionner un mois, et ainsi d'afficher le planning du mois choisi.

V-B-1-a. Procédure évènementielle sur AfterUpdate

Cette procédure s'exécute quand on choisit un mois dans la liste déroulante : elle permet d'afficher le planning du mois choisi.

 
Sélectionnez
Private Sub cmbMois_AfterUpdate()
    ' Mise à jour du planning.
    MajPlanning
End Sub

V-B-2. Liste déroulante cmbAnnee

Ce contrôle est utilisé pour permettre à l'utilisateur de sélectionner une année, et ainsi d'afficher le planning du mois et de l'année choisis.

V-B-2-a. Procédure évènementielle sur AfterUpdate

Cette procédure s'exécute quand on choisit une année dans la liste déroulante : elle permet d'afficher le planning du mois et de l'année choisis.

 
Sélectionnez
Private Sub An_AfterUpdate()
    ' Mise à jour du planning.
    MajPlanning
End Sub

V-B-3. Boutons de commande CmdPrecedent et CmdSuivant

Ces boutons de commande situés en haut à droite permettent d'avancer ou de reculer d'un mois sur le planning.

V-B-3-a. Procédure évènementielle sur clic du bouton CmdPrecedent

Ce code permet de reculer d'un mois et de mettre à jour le planning sur le formulaire.

 
Sélectionnez
Private Sub CmdPrecedent_Click()

    If (Me.cmbMois.value > 1) Then ' Si le mois est supérieur à 1 (janvier),
        Me.cmbMois = Me.cmbMois.value- 1 ' affiche le mois précédent.
    Else ' sinon si le mois affiché est janvier (1er mois de l'année)
        Me.cmbMois = 12 ' affiche le dernier mois
        Me.cmbAnnee = Me.cmbAnnee - 1 ' et l'année précédente.
    End If
    MajPlanning ' actualise le planning
End Sub

Si la liste cmbMois affiche le mois de janvier, on recule d'une année et on passe au mois de décembre, sinon, on passe simplement au mois précédent.

V-B-3-b. Procédure évènementielle sur clic du bouton CmdSuivant

Ce code permet d'avancer d'un mois et de mettre à jour le planning sur le formulaire.

 
Sélectionnez
Private Sub CmdSuivant_Click()
    If (Me.cmbMois.value < 12) Then ' Si le mois est inférieur à 12 (décembre),
        Me.cmbMois = Me.cmbMois.value + 1 ' affiche le mois suivant.
    Else ' sinon si le mois affiché est décembre (dernier mois de l'année)
        Me.cmbMois = 1 ' affiche le premier mois
        Me.cmbAnnee = Me.cmbAnnee + 1 ' et l'année suivante.
    End If
    MajPlanning ' actualise le planning
End Sub

Si la liste cmbMois affiche le mois de décembre, on avance d'une année et on passe au mois de janvier, sinon, on passe simplement au mois suivant.

V-C. Formulaire F_SaisiePlanning

Formulaire de saisie d'un nombre d'heures ou d'une absence d'un employé pour un jour et une période donnés.

Image non disponible
Formulaire F_SaisiePlanning en mode création

V-C-1. Bouton de commande CmdValider

Permet de valider la saisie.

V-C-1-a. Procédure évènementielle sur Clic

Déroulé de la procédure :

  • on teste si un motif d'absence ou un nombre d'heures a été saisi ;
  • si c'est le cas, on vérifie si une absence a déjà été enregistrée dans la période ;
  • si la période est libre, on enregistre l'absence pour chacun des jours compris dans la période ;
  • enfin, on actualise le planning et on ferme le formulaire de saisie.
Procédure évènementielle CmdValider_Click
Cacher/Afficher le codeSélectionnez

V-C-2. Bouton de commande CmdAnnuler

Permet d'annuler la saisie en cas d'erreur.

V-C-2-a. Procédure évènementielle sur Clic

 
Sélectionnez
Private Sub CmdAnnuler_Click()
    Me.Undo ' annule la saisie
    DoCmd.Close acForm, "F_Saisie" ' ferme le formulaire
End Sub

V-C-3. Bouton de commande CmdSupprimer

Permet de supprimer les présences ou les absences de l'employé comprises dans la période affichée sur le formulaire de saisie.

V-C-3-a. Procédure évènementielle sur Clic

Procédure évènementielle CmdSupprimer_Click
Cacher/Afficher le codeSélectionnez

La période de suppression est comprise entre le jour de début et le jour de fin affichés sur le formulaire.

VI. Module M_Planning

Enfin, nous présentons un condensé du module de l'application.

VI-A. Quelques fonctions importantes

Elles utilisent les fonctions Date et Heurefonctions Date et Heure :

 
Sélectionnez
Option Compare Database
Option Explicit

' Les fonctions du module.

Public Function FormatDateUs(ByVal vDate As Date) As String
    ' transforme la date passée en argument en date au format US
    FormatDateUs = "#" & Format(vDate, "mm-dd-yyyy") & "#"
End Function
Public Function EstWeekEnd(ByVal dt As Date) As Boolean
    ' teste si la date passée en argument est sur un week-end ou non
    EstWeekEnd = (Weekday(dt) = 1) Or (Weekday(dt) = 7)
End Function
Private Function nbJoursMois(ByVal mois As Long, ByVal annee As Long) As Long
    ' renvoie le nombre de jours du mois et de l'année passés en argument
    nbJoursMois = Day(DateSerial(annee, mois + 1, 0))
End Function
'...

Le module contient aussi la fonction EstFerie permettant de savoir si une date est un jour férié ou pas. Elle est disponible dans la faqfonction estferie.

VI-B. Procédure MajPlanning

La routine permet d'actualiser le sous-formulaire SF_Planning après avoir modifié le mois sur le formulaire de planning, ou les présences et absences des employés.

Déroulé de la procédure :

  • parcourt les jours du mois sélectionné sur le formulaire de planning ;
  • colorie chaque colonne en fonction du jour lui correspondant et l'affiche sur l'en-tête ;
  • masque les colonnes en trop si le nombre de jours est inférieur à 31 ;
  • rafraîchit le planning.
Procédure MajPlanning
Cacher/Afficher le codeSélectionnez

La procédure est déclarée publique afin de pouvoir l'appeler depuis n'importe quel formulaire.

VII. Paramétrage du planning

L'application permet de gérer les heures de présence ou les absences sur la journée complète ou sur plusieurs tranches horaires.

Pour une gestion des présences sur la journée complète, il suffit de l'indiquer dans la table T_PeriodeJour.

Par exemple, pour un horaire collectif de travail de 8 heures à 18 heures, on enregistre dans la table :

PeriodeJour

NumOrdre

08h-18h

1

L'affichage du formulaire de planning donne :

Image non disponible
Planning mensuel

Dans ce cas, vous pouvez masquer la colonne « Période Jour » en mettant la propriété Visible de la zone de texte PeriodeJour et de l'en-tête à faux.

VIII. Application à télécharger

La base exemplegestion-planning.zip est au format accdb.

Pour faciliter son développement et assurer sa portabilité, l'application n'utilisera pas de composants externes à Access (ActiveX ou autres).

IX. Remerciements

Un grand Merci à toute l'équipe de Dvp et plus particulièrement à :

Pour leurs remarques et conseils avisés :
. Gayot
. Philippe JOCHMANS
. Domi2
. Jeannot45
. Arkham46

Pour leurs relectures :
. Pierre Fauconnier
. Jeannot45

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2009 Denis Hulo. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.