IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Regrouper des lignes en fonction de la date [XL-2007]


Sujet :

Macros et VBA Excel

  1. #1
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut Regrouper des lignes en fonction de la date
    Bonjour,

    Mon fichier se compose de la façon suivante :

    Colonne A : Date de départ (sous la forme 01.01.2013)
    Colonne B : Date de fin (sous la forme 01.01.2013)
    Colonne F : Matricule de la personne (Alpha numérique : X11111XX)
    Colonne K : Un nombre d'heures

    Toutes les colonnes non citées (< K) contiennent des informations qui ne varient qu'en fonction d'un matricule et qui sont donc toujours identiques pour une même personne.

    Le fichier contient en fait les dates et durées d'absences d'une personne. Seulement, la saisie des absences étant réalisées par la personne elle-même, le logiciel peut nous ressortir plusieurs lignes pour le même arrêt.
    Exemple : Absence sur une journée : 1 ligne pour le matin + 1 pour l'après-midi
    Exemple : Absence sur plusieurs jours : 1 ligne par jour

    Ce que je voudrais, c'est une macro permettant de regrouper, pour un matricule, les absences sur le même jour et les jours qui se suivent de façon à n'obtenir qu'une seule ligne par arrêt et la somme du nombre d'heures totales d'absence sur cette période.

    J'ai été voir cette discussion mais ça ne correspont pas totalement à ce que je veux et étant débutant je n'arrive pas à reprendre et adapter les éléments à mon problème.

    Je me tourne donc vers vous pour savoir si vous avez une solution ?

    Merci d'avance,
    Chtik

  2. #2
    Membre actif Avatar de pastis.vi
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Novembre 2008
    Messages
    251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2008
    Messages : 251
    Points : 209
    Points
    209
    Par défaut
    Salut Chtik,

    Tu peux nous faire parvenir ton fichier?

  3. #3
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Bonjour pastis.vi,

    Voici le fichier en pièce jointe.

    J'y ai mis deux feuilles :
    - La première contenant les données d'origines
    - La deuxième avec le résultat attendu

    J'ai surligné en rouge, les lignes à regrouper et le résultat du regroupement souhaité en vert sur l'autre feuille.

    En espérant être clair.
    Fichiers attachés Fichiers attachés

  4. #4
    Inactif  
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    1 733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2012
    Messages : 1 733
    Points : 2 553
    Points
    2 553
    Par défaut
    Et si l'arrêt est entrecoupé d'un weekend ? Une fête ?

  5. #5
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Il faudrait en effet que le regroupement prennet en compte les week-end et jours fériés si possibles.

    Je n'étais pas aller plus loin ne sachant pas si ce que je souhaitais été possible.

    Mais l'objectif étant de regrouper les arrêts maladie en une seule période, les week-end et jours fériés devraient, dans le meilleur des cas, être compris dans cette période de façon à ne pas avoir découpage par semaine (1 lignes/semaine) dans le fichier final mais bien 1 ligne par arrêt.

  6. #6
    Membre actif Avatar de pastis.vi
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Novembre 2008
    Messages
    251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2008
    Messages : 251
    Points : 209
    Points
    209
    Par défaut
    De toute façon, we et jours fériés il y aura 0h heures de comptées donc ça ne change rien lorsqu'on réduit à 1 ligne...vu que les salariés ne vont pas remplir une ligne pour un dimanche.

  7. #7
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Non, en effet.

    Mais par exemple dans mon fichier :

    La première ligne verte (résultat souhaité) correspond à la période du 18.03 au 22.03 et la ligne suivante correspond à la date du 25.03 pour la même personne.

    Il faudrait que dans ce cas, la ligne du 25.03 soit comprise dans l'arrêt précédent avec comme résultat la période du 18.03 jusqu'au 25.03 et le cumul des heures de cette période.

    De cette façon, les week end et jours fériés seraient pris en compte.

  8. #8
    Membre éprouvé
    Homme Profil pro
    Ingénieur Pilotage
    Inscrit en
    Avril 2009
    Messages
    405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur Pilotage
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 405
    Points : 1 063
    Points
    1 063
    Par défaut
    Tiens Tiens une vieille connaissance du SID

    Ce qui me gène c'est la formulation de votre question :

    On regroupe les jours qui se suivent OK ==> d'ou le fait qu'on regroupe la ligne du 18/03 au 22/03. Le groupement se fait par paire de 2

    Ensuite, le regroupement du 11/04 au 14/04 me géne car le regroupement ne se fait pas par paire. mais la logique est là car la somme horaire dépasse 8h.

    En suivant cette logique, pourquoi ne pas regrouper la paire 25/03/2013 ?

    Pour le problème des jours ouvrés ==> créer une colonne 'Jour de la semaine' + une nouvelle colonne sur les jours fériés.

    Personnellement, le truc serait de créer un ID qui caractérise les groupes. ensuite un sql (via msquery) et group by ferait l'affaire.

  9. #9
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    La paire du 25.03 doit être regroupée également dans la période du 18.03 au 22.03.
    C'est une erreur de ma part car je n'avais pas intégré les week-end dans le fichier transmis.

    Personnellement, le truc serait de créer un ID qui caractérise les groupes. ensuite un sql (via msquery) et group by ferait l'affaire.
    Pourriez-vous m'aider sur les démarches à suivre ?
    Je n'ai jamais manipulé ces éléments.

  10. #10
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut cumul
    Bonjour,

    Une première approche en considérant le classeur joint.

    L'idée :
    - Une procédure argumentée par collaborateur (sur laquelle on pourrait boucler pour tous les collaborateurs, méthode dictionnaire)
    - Pour ce matricule, créer une variable virtuelle (j'ai pris un dictionnaire) dont on calculerait le minimum sur la 1ère colonne. Ce minimum serait la date de début d'absence.
    - Idem pour la 2ème colonne dont on calculerait le maximum.
    Ce maximum serait la date de fin d'absence.
    - le cumul s'effectuerait par collaborateur lors du calcul (par exemple) du minimum.

    Dans le code suivant, la procédure ESSAI retourne un exemple de ces 3 données pour un matricule précis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    Option Explicit
     
    Public Sub ESSAI()
    Call sommecollab("X33333XX")
    End Sub
     
    Public Sub sommecollab(matricule As String)
     
    Dim ws_donnor As Worksheet
    Dim dico, ListeCle, ListeElement, Tempo1, Tempo2
    Dim plage As Range, c As Range
    Dim cumul As Long
    Dim i As Byte, j As Byte
     
    Application.ScreenUpdating = False
     
    '--------------------------------------------------------------------------------CALCUL DU DEBUT D'ABSENCE ET DU CUMUL DES HEURES----------------------------------------------------------------------------
    Set ws_donnor = ThisWorkbook.Sheets("Données d'origine")
     
    With ws_donnor
            If .FilterMode = True Then .ShowAllData
            Set plage = .Range("F2", .Cells(.Rows.Count, 6).End(xlUp))
    End With
     
            cumul = 0
            Set dico = CreateObject("Scripting.Dictionary")
            For Each c In plage
                    If c = matricule Then
                            cumul = cumul + c.Offset(0, 5)
                            If Not dico.Exists(c.Offset(0, -5).Value) Then dico.Add c.Offset(0, -5).Value, c.Value
                    End If
            Next c
     
        ListeCle = dico.Keys
        ListeElement = dico.Items
     
        'tri moulinette
        For i = 0 To dico.Count - 2
            For j = i + 1 To dico.Count - 1
                If ListeCle(i) > ListeCle(j) Then
                    Tempo1 = ListeCle(j)
                    Tempo2 = ListeCle(j)
                    ListeElement(j) = ListeElement(i)
                    ListeElement(j) = ListeElement(i)
                    ListeElement(i) = Tempo1
                    ListeCle(i) = Tempo2
                End If
            Next j
        Next i
     
                    'Minimum
                    MsgBox "Date début d'absence pour le matricule " & matricule & " : " & ListeCle(0)
     
    Set dico = Nothing
     
     '--------------------------------------------------------------------------------CALCUL FIN D'ABSENCE----------------------------------------------------------------------------
     
            Set dico = CreateObject("Scripting.Dictionary")
            For Each c In plage
                    If c = "X33333XX" Then _
                    If Not dico.Exists(c.Offset(0, -4).Value) Then dico.Add c.Offset(0, -4).Value, c.Value
            Next c
     
        'tri moulinette
        For i = 0 To dico.Count - 2
            For j = i + 1 To dico.Count - 1
                If ListeCle(i) > ListeCle(j) Then
                    Tempo1 = ListeCle(j)
                    Tempo2 = ListeCle(j)
                    ListeElement(j) = ListeElement(i)
                    ListeElement(j) = ListeElement(i)
                    ListeElement(i) = Tempo1
                    ListeCle(i) = Tempo2
                End If
            Next j
        Next i
     
                    'Maximum
                    MsgBox "Date début d'absence pour le matricule " & matricule & " : " & ListeCle(dico.Count - 1)
     
                    'Cumul
                    MsgBox "Cumul d'heures d'absence pour le matricule " & matricule & " : " & cumul & " heures."
     
    End Sub

    Ne resterait plus qu'à boucler sur tous les matricules et reporter les résultats.

    Je livre cette approche pour commentaires.

  11. #11
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Après avoir essayé ta proposition MarcelG, je suis heureux de dire que c'est presque ce que je désire.

    Le principe de ta macro est le bon mais j'ai quelques remarques :

    - La détermination du minimum (jour de début d'absence) et du maximum (jour de fin d'absence) prend en compte l'ensemble des absences du salarié pour établir le cumul d'heure.
    Or, un salarié peut être absent par exemple la 1ère semaine du mois et la dernière et donc avoir 2 arrêts distincts.
    Je voudrais que la macro fasse le total pour chacune des 2 périodes et non pas un total général.

    - Je pense que c'est un détail à ce niveau mais pourrait-on inscrire le résultat de la macro pour chaque salarié et période sur une ligne plutôt que dans une msgbox.


    J'ai mis un nouveau classeur actualisé en pièce jointe en fonction des réponses que j'ai eu ce matin.
    Fichiers attachés Fichiers attachés

  12. #12
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut
    Salut,

    Dans ce cas, il faut intégrer une fonction semaine dans ta base de données (possible par VBA, la fonction semaine étant connue) et comptabiliser par matricule/semaine, tout en tenant compte du jour de début et de fin de période.

    C'est beaucoup plus compliqué.
    Mais possible.
    (Je pense découper la base de données par semaines, puis faire un traitement propre à chaque semaine, et enfin compiler tous les résultats avant de les trier).

    Quant à l'écriture, aucun problème. La MsgBox n'est là que pour illustrer les résultats.

    Je te reviens...dès que possible.

  13. #13
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Merci beaucoup.
    J'attends ton retour avec impatience.

    Et en attendant, je vais tenter de mieux comprendre ton premier code. ;-)

  14. #14
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut
    Bonjour Chtik, Bonjour le Forum,

    Une confirmation, s'il te plaît.
    Il faut bien regrouper les absences par matricule / semaine calendaire.
    Exemple pour le matricule X33333XX: 2 regroupements
    Semaine 12 du 18 au 24 Mars 2013 (en ce qui le concerne du 18 au 22 Mars)
    Semaine 13 du 25 au 31 Mars 2013 (en ce qui le concerne du 25 au 25 Mars)

    Pour moi, c'est la seule méthode envisageable.

  15. #15
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Bonjour MarcelG,
    Bonjour le Forum,

    L'objectif premier était de regrouper les absences continues ensemble qu'elles soient sur 1 semaines ou plusieurs.

    Après, le regroupement par semaine me convient également à partir du moment où il est possible de voir que l'absence commence à jour différent du 1er jour de la semaine et un jour différent du dernier jour de la semaine si c'est le cas.

    Il me semble qu'on est sur la même longueur d'ondes.

    Par exemple : Pour le matricule X33333XX: 2 regroupements
    Semaine 12 du 18 au 24 Mars 2013 (en ce qui le concerne du 18 au 22 Mars)
    Semaine 13 du 25 au 31 Mars 2013 (en ce qui le concerne du 25 au 25 Mars)

    Tant que l'absence de la semaine 13 est bien indiquée juste pour le 25 Mars sur cette semaine et non pas sur la période totale de la semaine, ça me va.



    Dans le cas d'une identification sur la période totale de la semaine (X heures du 25 au 31 Mars 2013 pour Y salarié), il faudrait que je puisse déterminer le premier jour d'absence de la personne.

    Par exemple :
    Semaine 13 du 25 au 31 Mars 2013 -> cumul d'heures d'absences + 1er jour d'absence (soit le jour du 25 mars = lundi)

    Un objectif secondaire étant de pouvoir identifier les absences autour des week-end (vendredi et lundi).


    Mais dans un premier temps, si tu peux regrouper les absences par semaine comme tu le propose, sans répondre à toutes mes attentes, je veux bien voir le résultat que tu peux m'apporter et te faire un retour sur ta solution.

    Merci beaucoup,
    Chtik

  16. #16
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut
    Salut,

    On est d'accord.

    Si je reprends mon exemple pour le matricule X33333XX: 2 regroupements

    18 au 22 Mars 2013 : 35 h
    25 au 25 Mars 2013 : 7 h

  17. #17
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Oui, c'est tout à fait ça.

  18. #18
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut
    Salut Chtik,

    La méthode

    - Intégrer le n° de semaine en fin de table par la fonction du même nom
    - Dictionnaire des matricules
    - Pour chaque matricule, dictionnaire des semaines
    - Pour chaque regroupement matricule \ semaine, calculs de la date de début d'absence dans cette semaine, de la date de fin d'absence dans cette semaine, et du cumul des heures.Ce calcul s'effectue par une fonction à 3 arguments : matricule, semaine, résultat souhaité parmi les 3 ci-dessus.
    - Information de la feuille "Résultat attendu" via une variable Tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    Option Explicit
    Dim plage As Range
     
    Public Sub ESSAI2()
     
    Dim re As Integer
    Dim ws_donnor As Worksheet
    Dim latable As Range
    Dim l As Range, u As Range
    Dim dicollab, ListeCollab, dicosem, ListeSem
    Dim k As Byte, t As Byte, z As Byte, p As Byte, v As Variant
    Dim tablo()
    Dim dest As Range
    Dim dernrow As Integer, r As Integer
     
    With Sheets("Résultat Attendu")
            re = .Cells(.Rows.Count, 11).End(xlUp).Row
            If re = 1 Then re = 2
            .Range("A2", .Cells(re, 11)).ClearContents
    End With
     
    Set ws_donnor = ThisWorkbook.Sheets("Données d'origine")
    With ws_donnor
            If .FilterMode = True Then .ShowAllData
            Set plage = .Range("F2", .Cells(.Rows.Count, 6).End(xlUp))
            Set latable = .Range("A2", .Cells(.Rows.Count, 11).End(xlUp))
    End With
     
    Set dicollab = CreateObject("Scripting.Dictionary")
    For Each l In plage
           If Not dicollab.Exists(l.Value) Then dicollab.Add l.Value, l.Value
    Next l
     
    ListeCollab = dicollab.Keys
     
    With plage.Offset(0, 6)
            .FormulaR1C1 = "=semaine(SUBSTITUTE(RC[-11],""."",""/""))"
            .Value = .Value
    End With
     
    For k = 0 To dicollab.Count - 1
     
            Set dicosem = CreateObject("Scripting.Dictionary")
            For Each u In plage.Offset(0, 6)
                    If u.Offset(0, -6).Value = ListeCollab(k) And Not dicosem.Exists(u.Value) Then dicosem.Add u.Value, u.Value
            Next u
            ListeSem = dicosem.Keys
     
            For v = 0 To dicosem.Count - 1
     
                    p = k + 1
                    ReDim Preserve tablo(1 To 11, 1 To p)
                    tablo(1, p) = sommecollab(ListeCollab(k), ListeSem(v), 1)
                    tablo(2, p) = sommecollab(ListeCollab(k), ListeSem(v), 2)
                    For t = 3 To 10
                        tablo(t, p) = WorksheetFunction.Index(latable, WorksheetFunction.Match(ListeCollab(k), plage, 0), t)
                    Next t
                    tablo(11, p) = sommecollab(ListeCollab(k), ListeSem(v), 3)
                    With Sheets("Résultat Attendu")
                            Set dest = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0)
                            dest.Resize(UBound(tablo(), 2), 11).Value = WorksheetFunction.Transpose(tablo)
                    End With
     
                    Set dest = Nothing
                    Erase tablo
     
            Next v
     
            Set dicosem = Nothing
     
    Next k
     
    Set latable = Nothing
    Set dicollab = Nothing
     
    With Sheets("Résultat Attendu")
            dernrow = .Cells(.Rows.Count, 11).End(xlUp).Offset(-1, 0).Row
            For r = dernrow To 2 Step -1
                    With .Cells(r, 1)
                            If Len(.Value) = 0 Then .EntireRow.Delete
                    End With
            Next r
    End With
     
    plage.Offset(0, 6).ClearContents
    Set plage = Nothing
     
     
    End Sub
     
    Public Function sommecollab(matricule As Variant, sem As Variant, choix As Byte) As Variant
     
    Dim dico, ListeCle, ListeElement, Tempo1, Tempo2
    Dim c As Range
    Dim cumul As Double
    Dim datedéb, datefin
    Dim i As Byte, j As Byte
    Application.ScreenUpdating = False
     
    '--------------------------------------------------------------------------------CALCUL DU DEBUT D'ABSENCE ET DU CUMUL DES HEURES----------------------------------------------------------------------------
     
            cumul = 0
            Set dico = CreateObject("Scripting.Dictionary")
            For Each c In plage
                    If c = matricule And c.Offset(0, 6) = sem Then
                            cumul = cumul + c.Offset(0, 5)
                            If Not dico.Exists(c.Offset(0, -5).Value) Then dico.Add c.Offset(0, -5).Value, c.Value
                    End If
            Next c
     
        ListeCle = dico.Keys
        ListeElement = dico.Items
     
        If dico.Count >= 2 Then
                'tri  dico
                For i = 0 To dico.Count - 2
                    For j = i + 1 To dico.Count - 1
                        If ListeCle(i) > ListeCle(j) Then
                            Tempo1 = ListeCle(j)
                            Tempo2 = ListeCle(j)
                            ListeElement(j) = ListeElement(i)
                            ListeElement(j) = ListeElement(i)
                            ListeElement(i) = Tempo1
                            ListeCle(i) = Tempo2
                        End If
                    Next j
                Next i
        End If
     
    datedéb = ListeCle(0)
     
    Set dico = Nothing
     
     '--------------------------------------------------------------------------------CALCUL FIN D'ABSENCE----------------------------------------------------------------------------
     
            Set dico = CreateObject("Scripting.Dictionary")
            For Each c In plage
                    If c = matricule And c.Offset(0, 6) = sem Then _
                            If Not dico.Exists(c.Offset(0, -4).Value) Then dico.Add c.Offset(0, -4).Value, c.Value
            Next c
     
        ListeCle = dico.Keys
        ListeElement = dico.Items
     
        If dico.Count >= 2 Then
                'tri dico
                For i = 0 To dico.Count - 2
                    For j = i + 1 To dico.Count - 1
                        If ListeCle(i) > ListeCle(j) Then
                            Tempo1 = ListeCle(j)
                            Tempo2 = ListeCle(j)
                            ListeElement(j) = ListeElement(i)
                            ListeElement(j) = ListeElement(i)
                            ListeElement(i) = Tempo1
                            ListeCle(i) = Tempo2
                        End If
                    Next j
                Next i
        End If
     
        datefin = ListeCle(dico.Count - 1)
     
        Select Case choix
            Case 1
                sommecollab = datedéb
            Case 2
                sommecollab = datefin
            Case 3
                sommecollab = cumul
        End Select
     
    End Function
     
    Public Function Semaine(dat As Date) As Byte
    Dim a As Integer
     
    a = Int((dat - DateSerial(Year(dat), 1, 1) + ((Weekday(DateSerial(Year(dat), 1, 1)) + 1) Mod 7) - 3) / 7) + 1
     
    If a = 0 Then
     
            a = Semaine(DateSerial(Year(dat) - 1, 12, 31))
     
    ElseIf a = 53 And (Weekday(DateSerial(Year(dat), 12, 31)) - 1) Mod 7 <= 3 Then
     
            a = 1
     
    End If
     
    Semaine = a
     
    End Function
    Voilà.

  19. #19
    Membre habitué
    Homme Profil pro
    Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Inscrit en
    Novembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chargé d'Ingénierie et d'Analyses en Ressources Humaines
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 63
    Points : 169
    Points
    169
    Par défaut
    Après un test, c'est génial mais pas tout à fait ce que je souhaite.

    Le résultat obtenu est le cumul de la durée d'absence sur l'ensemble de la période (date minimum à date maximum). -> Voir image jointe

    Du coup, par exemple nous n'obtenons plus :

    Pour le matricule X33333XX : 2 regroupements
    18 au 22 Mars 2013 : 35 h
    25 au 25 Mars 2013 : 7 h

    Mais 1 seul regroupement :
    Du 18.03.2013 au 25.03.2013 : 42h

    Y aurait-il une fonction à activer pour la prise en compte des semaines ?

    Je pars du principe que ça doit venir de mon côté vu le travail que tu viens de me fournir.

    En tout cas, merci. Nous y sommes presque.
    Images attachées Images attachées  

  20. #20
    Expert éminent
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Points : 7 149
    Points
    7 149
    Billets dans le blog
    7
    Par défaut
    J'ai repris ton dernier fichier et le cumul se calcule bien sur le couple matricule \ semaine.

    - Reprends le dernier fichier que tu as joint à cette discussion
    - Insère un nouveau module
    - Copie le code de mon dernier post dans son intégralité
    - Lance, dans le VBE, la macro ESSAI2

    Je viens d'effectuer le test avec succès.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. cmt lister des lignes en fonction du mois de la date
    Par Mihalis dans le forum Bases de données
    Réponses: 3
    Dernier message: 09/04/2007, 12h29
  2. incrémenter des lignes en fonction d'un champ "nombre"
    Par bookaro92 dans le forum Access
    Réponses: 2
    Dernier message: 01/12/2006, 15h05
  3. Recherche une ligne en fonction d'une date
    Par c+cool dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 20/09/2006, 15h30
  4. [VBA-E] Créer des lignes en fonction d'un champ
    Par antakini dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 18/04/2006, 20h23
  5. [vbexcel]tri ou regroupement de ligne en fonction de valeur.
    Par Mugette dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 12/12/2005, 18h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo