Désolé l'image ne m'est pas accessible (sécurité de mon poste sans doute).
Tes données sont-elles déjà dans des champs séparés et typés ou tout d'un bloc dans un fichier texte ?
Pour le moment je vais supposer que c'est des champs séparés.
Voilà ce que je suggère.
Ta table de pointage devrait avoir une structure qui ressemble à :
Table tblPointage :
Clef (numero séquentiel automatique)
Matricule (entier long)
DatePointage (date/heure)
HeurePointage (date/heure)
SensPointage (texte, 255 caractères)
EstPointageValide (boolean, valeur par défaut : vrai).
Il te faut une requête qui "reconstitue" la date et l'heure.
Requete reqDateHeurePointage
select [tblPointage].[Clef], [tblPointage].[Matricule], DateSerial(year([tblPointage].[DatePointage]), month([tblPointage].[DatePointage]), day([tblPointage].[DatePointage])) + TimeSerial(Hour([tblPointage].[HeurePointage]), minute([tblPointage].[HeurePointage]),0) as DateHeurePointage, [tblPointage].[SensPointage], [EstPointageValide] from [tblPointage];
Enuite des requêtes qui te donnent les entrées et les sorties et le temps écoulé (en minutes)
Requête reqPointageEntree
select [reqDateHeurePointage].* where [reqDateHeurePointage].[SensPointage]="in" and [estPointageValide]
Requête reqPointageSortie
select [reqDateHeurePointage].* where [reqDateHeurePointage].[SensPointage]="out" and [estPointageValide]
Requête reqPointageTemps
1 2
| SELECT [reqPointageEntree].[Matricule], [reqPointageEntree].[DateHeurePointage] as [DateHeureEntree], [reqPointageSortie].[DateHeurePointage] as [DateHeureSortie], Datediif("n", [reqPointageEntree].[DateHeurePointage], [reqPointageSortie].[DateHeurePointage])
FROM [reqPointageEntree] INNER JOIN [reqPointageSortie] ON [reqPointageEntree].[Matricule] = [reqPointageSortie].[Matricule]; |
Attention ne marche correctement que si tu as une seule entrée et une seule sortie par "traitement". Si tu as plusieurs entrées et sorties, il va falloir associer les sorties avec les entrées en fonction de la date de sortie, pas seulement par le matricule. Et aussi il faut forcément que tu ais une entrée ET une sortie.
Pour trouver l'entrée correspondant à la sortie :
DMax("DateheuerPointage", "reqPointageEntree", "[DateHeurePointage]<=#" & format([DateHeurePointage], "yyyy\-mm\-dd hh:nn:ss" & "# and [Matricule]=" & [Matricule])
Le sql devrait sans doute être :
1 2
| SELECT [reqPointageSortie].[Matricule], DMax("DateHeurePointage", "reqPointageEntree", "[DateHeurePointage]<=#" & format([DateHeurePointage], "yyyy\-mm\-dd hh:nn:ss" & "# and [Matricule]=" & [Matricule]) as [DateHeureEntree], [reqPointageSortie].[DateHeurePointage] as [DateHeureSortie], Datediif("n", [DateHeureEntree], [DateHeureSortie])
FROM [reqPointageSortie]; |
Là si il manque l'entrée tu vas avoir une date Null, si il manque la sortie, l'entrée ne sera pas traitée.
Évidement ce sera plus long à éxécuter qu'une jointure.
Pour éviter les problèmes, il serait bon de vérifier que toutes les entrées ont des sorties et toutes les sorties des entrées et ceux dans un enchaînement logique.
À mon avis ce sera plus facile à faire en VBA, en parcourant un a un tous les enregistrements, qu'en SQL.
On pourra basculer estPointageValide à faux si il faut l'ignorer.
Il faut attraper des erreurs du type :
- Entrée1
- Entrée2
- Sortie1
- Sortie2
Sinon tu vas avoir Entrée2-Sortie1 et Entree2-Sortie2.
Par contre il sera difficile d'attraper des erreurs du type
Entree le 2015-01-01
Sortie le 2015-12-31
car l'association entre entrée et sortie sera correcte. Il y a bien une entrée et une sortie.
À mon avis il faudra une alerte sur les périodes de travail trop longues (ex : supérieures à 24h00).
A+
Partager