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 :

Extraction de données par sous ensemble [XL-2007]


Sujet :

Macros et VBA Excel

  1. #1
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut Extraction de données par sous ensemble
    Bonjour à tous,

    Dans la colonne A, j’ai des données sous forme S-x-y

    Dans la colonne B, j’ai des données sous forme de zRi, zBG, zUD.

    S-13-0
    S-16-0
    S-16-1
    S-1-14 4RI
    S-10-0 20RI
    S-10-2 24RI
    S-10-5 30BG
    S-10-1 31RI
    S-10-7 34UD
    S-12-11 39RI
    S-11-12 40RI

    J’aimerais comptabiliser dans un tableau les sous ensemble suivants :

    -Y dans la colonne A (Ex : Le S-10 contient 5 sous ensemble)

    -RI qui correspond à l’ensemble (S-x) dans la colonne A (Ex : il y a 3 RI dans l’ensemble S-10)

    -BG qui correspond à l’ensemble (S-x) dans la colonne A (Ex : il y a 1 BG dans l’ensemble S-10)

    -UD qui correspond à l’ensemble (S-x) dans la colonne A (Ex : il y a 1 UD dans l’ensemble S-10)

    Merci d’avance.

    EDIT :

    Pour un début, voila un code qui répond au premier point (comptabiliser le nombre des ensemble dans la colonne A)

    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
    Sub CompteOccuSP()
        Dim dl As Long    'déclare la variable dl (Dernière Ligne)
        Dim pl As Range    'déclare la variable pl (PLage)
        Dim dico As Object    'déclare la variable dico (DICtiOnnaire)
        Dim Cel As Range, Cel2    'déclare la variable cel (CELLule)
        Dim temp As Variant    'déclare la variable temp (tableau TEMPoraire)
        Dim x As Integer
        Application.ScreenUpdating = False
        Set dico = CreateObject("Scripting.Dictionary")    'définit le dictionnaire dico
        With Sheets("Feuil1")    'prend en compte l'onglet "Feuil1"
            '.Cells(3, 4).CurrentRegion.ClearContents    'efface les anciennes données
            dl = .Cells(Application.Rows.Count, 1).End(xlUp).Row    'définit la dernière ligne dl de la colonne B
            Set pl = .Range("A2:A" & dl)    'définit la plage pl
            For Each Cel In pl    'boucle sur toutes les cellules cel de la plage pl
                'Cel2 = Left(Cel, 3)
                Cel2 = Split(Cel, "-")(1)
                'MsgBox "Cel2 = " & Cel2 & vbCrLf & _
                 '       "dico = " & dico(Cel2) & ", dc+1 = " & dico(Cel2) + 1
     
                dico(Cel2) = dico(Cel2) + 1  'alimente le dictionnaire
            Next Cel    'prochaine cellule de la boucle
            temp = dico.keys    'récupère le dictionnaire sans doublons
            Call Tri(temp, LBound(temp), UBound(temp))    'lance la procédure de tri croissant du tableau temp
            [D1] = "S": [E1] = "P"
            For x = 0 To UBound(temp)    'boucle sur tous les éléments du tableau tri
     
                .Cells(x + 2, 4).Value = temp(x)     'place l'étiquette
                .Cells(x + 2, 5).Formula = dico.Item(temp(x))
                '.Cells(x + 2, 6).Value = ?
                '.Cells(x + 2, 7).Value = ?
                '.Cells(x + 2, 8).Value = ?
            Next x    'prochain élément de la boucle
        End With    'fin de la prise en compte de l'onglet "BDD"
        Application.ScreenUpdating = True
    End Sub
    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
    Sub Tri(a As Variant, gauc As Integer, droi As Integer)    'tiré du site de Jacques BOISGONTIER http://boisgontierjacques.free.fr/
        Dim ref As Variant
        Dim g As Integer, d As Integer
        Dim tmp As Variant
     
        ref = a((gauc + droi) \ 2)
        g = gauc: d = droi
        Do
            Do While a(g) < ref: g = g + 1: Loop
            Do While ref < a(d): d = d - 1: Loop
            If g <= d Then
                tmp = a(g): a(g) = a(d): a(d) = tmp
                g = g + 1: d = d - 1
            End If
        Loop While g <= d
        If g < droi Then Call Tri(a, g, droi)
        If gauc < d Then Call Tri(a, gauc, d)
    End Sub
    Fichiers attachés Fichiers attachés
    • Type de fichier : xls SP.xls (50,5 Ko, 78 affichages)

  2. #2
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Bonjour

    Une proposition (Active la référence Microsoft Scripting Runtime)
    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
    Option Explicit
    'Active la Référence Microsoft Scripting Runtime
    Sub Traiter()
    Const Cible As String = "K1"
    Dim Str As String, Code As String, Res()
    Dim LastLig As Long, i As Long, n As Long
    Dim j As Integer, m As Integer
    Dim MonDico As New Scripting.Dictionary
    Dim ItemDico As New Scripting.Dictionary
    Dim Tb
     
    Application.ScreenUpdating = False
    With Feuil1
        LastLig = .Cells(.Rows.Count, "A").End(xlUp).Row
        Tb = .Range("A2:B" & LastLig)
        For i = 1 To UBound(Tb, 1)
            Str = Tb(i, 1)
            Code = SupprNum(Tb(i, 2))
            If InStr(Str, "-") Then
                If Not ItemDico.Exists(Code) And Code <> "" Then ItemDico.Add Code, Code
                Str = Left(Str, InStrRev(Str, "-") - 1)
     
                If Not MonDico.Exists(Str) Then
                    MonDico.Add Str, Code
                Else
                    MonDico(Str) = MonDico(Str) & "," & Code
                End If
            End If
        Next i
     
        m = ItemDico.Count
        If m > 0 Then
            n = MonDico.Count
            If n > 0 Then
                ReDim Res(1 To n + 1, 1 To m + 2)
                Res(1, 1) = "S"
                Res(1, 2) = "P"
                For j = 0 To m - 1
                    Res(1, j + 3) = ItemDico.Items(j)
                Next j
                For i = 0 To n - 1
                    Res(i + 2, 1) = Mid(MonDico.Keys(i), 3)
                    Res(i + 2, 2) = UBound(Split(MonDico.Items(i), ",")) + 1
                    For j = 0 To m - 1
                        Res(i + 2, j + 3) = CompteItems(MonDico.Items(i), ItemDico.Items(j))
                    Next j
                Next i
                Set MonDico = Nothing
                .Range(Cible).Resize(n + 1, m + 2) = Res
                .Range(Cible).Resize(n + 1, m + 2).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlYes
            End If
        End If
    End With
    End Sub
     
    Private Function SupprNum(ByVal Str As String) As String
    Dim Rg As Object
     
    Set Rg = CreateObject("vbscript.Regexp")
    With Rg
        .Pattern = "\d"
        .Global = True
        SupprNum = .Replace(Str, "")
    End With
    Set Rg = Nothing
    End Function
     
    Private Function CompteItems(ByVal Str As String, ByVal Txt As String) As Integer
    Dim i As Integer, n As Integer
    Dim Tb
     
    If Len(Str) > 0 Then
        Str = Mid(Str, 2)
        If InStr(Str, ",") Then
            Tb = Split(Str, ",")
            For i = LBound(Tb) To UBound(Tb)
                If UCase(Tb(i)) = UCase(Txt) Then n = n + 1
            Next i
        End If
    End If
    CompteItems = n
    End Function

  3. #3
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Bonjour mercatog,

    Tout d'abord, merci pour le code qui fonctionne très bien.

    En essayant de l'adapter sur mes données, j'ai modifié le masque regex en :

    Pour éliminer tout chiffre au début de chaque chaine de caractères.

    Parce que en colonne B, j'ai des données de la sorte de :

    122R3I, 95B5G1, 103UDI6 et 24UNI6

    Par ce masque j'aurais : R3I, B5G1, UDI6 et UNI6

    S-13-0
    S-16-0
    S-16-1
    S-1-14 4R3I
    S-10-0 20R3I
    S-10-2 122R3I
    S-10-5 95B5G1
    S-10-1 31RI
    S-10-7 103UDI6
    S-12-11 39R3I
    S-11-12 24UNI6

    Maintenant, je souhaiterais comptabiliser le nombre des UDI6 et UNI6 dans une seule cellule, parce que c'est une appellation pour la même donnée.

    Merci.

  4. #4
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    je souhaiterais comptabiliser le nombre des UDI6 et UNI6 dans une seule cellule, parce que c'est une appellation pour la même donnée.
    Ajoute cette ligne juste après la ligne 18 du code Traiter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            If Code = "UNI6" Then Code = "UDI6"
    Ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Code = "UNI6" Or Code = "UDI6" Then Code = "UDI6/UNI6"

  5. #5
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Bonsoir mercatog,

    Merci pour la solution.Ca marche.

    Entre temps, j'ai essayé d'ajouter une colonne en dernier pour calculer le nombre les positions libre dans les ensembles en colonne A.

    J'ai ainsi modifié le code :

    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
        m = ItemDico.Count
        If m > 0 Then
            n = MonDico.Count
            If n > 0 Then
                ReDim Res(1 To n + 1, 1 To m + 2 + 1)
                Res(1, 1) = "S"
                Res(1, 2) = "P"
                For j = 0 To m - 1
                    Res(1, j + 3) = ItemDico.Items(j)
                Next j
                For i = 0 To n - 1
                    Res(i + 2, 1) = Mid(MonDico.Keys(i), 5)
                    Res(i + 2, 2) = UBound(Split(MonDico.Items(i), ",")) + 1
                    For j = 0 To m - 1
                        Res(i + 2, j + 3) = CompteItems(MonDico.Items(i), ItemDico.Items(j))
                    Next j
                    Res(i + 2, j + 3) = CInt(16 - Range("I" & i + 2).Value)
                Next i
                Set MonDico = Nothing
                .Range(Cible).Resize(n + 1, m + 2 + 1) = Res
                .Range(Cible).Resize(n + 1, m + 2 + 1).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlYes
            End If
        End If
    Comme un ensemble devra contenir au maximum 16 positions, alors j'ai écrits la formule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Res(i + 2, j + 3) = CInt(16 - Range("I" & i + 2).Value)
    Mais voila après, je ne trouve pas dans la dernière colonne des différences homogènes au calcul demandé !

    Une solution ?

    Merci.

  6. #6
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    j'ai essayé d'ajouter une colonne en dernier pour calculer le nombre les positions libre dans les ensembles en colonne A
    Ce n'est pas du tout compréhensible

  7. #7
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Salut mercatog,

    Prenons l'exemple suivant :

    S-0-1
    S-0-0
    S-0-11 12B5G1
    S-0-8 25B5G1
    S-0-6 27B5G1
    S-0-2
    S-0-3
    S-0-4
    S-0-5
    S-0-7 45UNI6
    S-0-15 99UNI6
    S-0-10 104UNI6
    S-0-9 108UNI6

    On peut compter dans l'ensemble S-0 :

    (13) P : (0) RI3 : (3) B5G1 : (4) UNI/UDI : (3) Positions Libres

    Comme l'ensemble S-0 va de S-0-0 à S-0-15 (16 positions), on peut remarquer que les sous-ensembles manquants sont bien : S-0-12, S-0-13, S-0-14, d'ou le nombre (3) des positions libres.

    J'espère avoir un peu clair

  8. #8
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Bonjour
    Beaucoup de gymnastique à tester
    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
    Option Explicit
     
    'Active la Référence Microsoft Scripting Runtime
    Sub Traiter()
    Const Cible As String = "E1"
    Dim Str As String, Code As String, Res()
    Dim LastLig As Long, i As Long, n As Long
    Dim j As Integer, m As Integer, Nb As Integer
    Dim MonDico As New Scripting.Dictionary
    Dim ItemDico As New Scripting.Dictionary
    Dim Tb
     
    Application.ScreenUpdating = False
    With Feuil1
        LastLig = .Cells(.Rows.Count, "A").End(xlUp).Row
        Tb = .Range("A2:B" & LastLig)
        For i = 1 To UBound(Tb, 1)
            Str = Tb(i, 1)
            Code = SupprNum(Tb(i, 2))
            If Code = "UNI6" Or Code = "UDI6" Then Code = "UDI6/UNI6"
            If InStr(Str, "-") Then
                If Not ItemDico.Exists(Code) And Code <> "" Then ItemDico.Add Code, Code
                Str = Left(Str, InStrRev(Str, "-") - 1)
     
                If Not MonDico.Exists(Str) Then
                    MonDico.Add Str, "," & Code
                Else
                    MonDico(Str) = MonDico(Str) & "," & Code
                End If
            End If
        Next i
     
        m = ItemDico.Count
        If m > 0 Then
            n = MonDico.Count
            If n > 0 Then
                ReDim Res(1 To n + 1, 1 To m + 3)
                Res(1, 1) = "S"
                Res(1, 2) = "P"
                Res(1, m + 3) = "Positions Libres"
                For j = 0 To m - 1
                    Res(1, j + 3) = ItemDico.Items(j)
                Next j
                For i = 0 To n - 1
                    Str = MonDico.Keys(i)
                    Nb = Indx(Tb, Str)
                    Res(i + 2, 1) = Mid(Str, 3)
                    Res(i + 2, 2) = UBound(Split(MonDico.Items(i), ","))
                    For j = 0 To m - 1
                        Res(i + 2, j + 3) = CompteItems(MonDico.Items(i), ItemDico.Items(j))
                    Next j
                    Res(i + 2, m + 3) = Nb
                Next i
                Set MonDico = Nothing
                .Range(Cible).Resize(n + 1, m + 3) = Res
                .Range(Cible).Resize(n + 1, m + 3).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlYes
            End If
        End If
    End With
    End Sub
     
    Private Function SupprNum(ByVal Str As String) As String
    Dim Rg As Object
     
    Set Rg = CreateObject("vbscript.Regexp")
    With Rg
        .Pattern = "^\d{0,3}"
        .Global = True
        SupprNum = .Replace(Str, "")
    End With
    Set Rg = Nothing
    End Function
     
    Private Function CompteItems(ByVal Str As String, ByVal Txt As String) As Integer
    Dim i As Integer, n As Integer
    Dim Tb
     
    If Len(Str) > 0 Then
        Str = Mid(Str, 2)
        If InStr(Str, ",") Then
            Tb = Split(Str, ",")
            For i = LBound(Tb) To UBound(Tb)
                If UCase(Tb(i)) = UCase(Txt) Then n = n + 1
            Next i
        End If
    End If
    CompteItems = n
    End Function
     
    Private Function Indx(ByVal Tb, ByVal Str As String) As Integer
    Dim i As Long
    Dim j As Integer, Mx As Integer, S As Integer
    Dim Trouve As Boolean
     
    For i = 1 To UBound(Tb, 1)
        If Left(Tb(i, 1), InStrRev(Tb(i, 1), "-") - 1) Like Str Then
            Mx = Application.Max(Mx, Val(Mid(Tb(i, 1), InStrRev(Tb(i, 1), "-") + 1)))
        End If
    Next i
    For j = 0 To Mx
        For i = 1 To UBound(Tb, 1)
            If Tb(i, 1) = Str & "-" & j Then
                Trouve = True
                Exit For
            End If
        Next i
        If Not Trouve Then
            S = S + 1
        Else
            Trouve = False
        End If
    Next j
    Indx = S
    End Function

  9. #9
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Bonjour mercatog,

    Je m'excuse pour le retard.

    J'ai essayé ton nouveau code, mais il ne marche pas à tous les coups.

    Dans le fichier joint, j'ai ajouté un en-tête "Confirmation" dans la colonne K.

    Et tu peux voir que le compte n'est pas toujours bon

    Merci.
    Fichiers attachés Fichiers attachés

  10. #10
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Pourquoi en Kx tu as mis toujours =16-Fx?

    Pour S-10 par exemple,
    S-10-12
    S-10-0
    S-10-2
    S-10-5
    S-10-1
    S-10-7
    S-10-13
    S-10-14
    Entre 0 et 14, tu as 15 possibilités et non 16.

    Ou je n'ai pas compris

  11. #11
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Salut,

    Citation Envoyé par mercatog Voir le message
    Pourquoi en Kx tu as mis toujours =16-Fx?

    Pour S-10 par exemple,
    Entre 0 et 14, tu as 15 possibilités et non 16.

    Ou je n'ai pas compris
    On a 16 possibilités pour définir un S, a savoir de S-10-0 à S-10-15

    Voila !

  12. #12
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Comme l'ensemble S-0 va de S-0-0 à S-0-15 (16 positions)
    C'était ton premier post concernant le comptage des sous ensembles manquants

    Tu n'as jamais parlé de 16 comme étant toujours le nombre maximum de tous les groupes.

    Le code calcule l'index le plus grand! pour ton S-10, tu as le maximum à 14 donc 15 possibilités.
    Voilà à mon tour.

    Par contre si tu as toujours 16, il fallait le préciser et comme tu as fais, c'était dans ce cas trop facile d'ajouter une colonne en fin et de retrancher à 16 le valeur trouvée en colonne 2 du tableau correspondant à P.

    Et dire que je suis parti sur une gymnastique...

  13. #13
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Re,

    J'ai déja écrit :

    Citation Envoyé par apt Voir le message
    Entre temps, j'ai essayé d'ajouter une colonne en dernier pour calculer le nombre les positions libre dans les ensembles en colonne A.

    ...

    Comme un ensemble devra contenir au maximum 16 positions, alors j'ai écrits la formule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Res(i + 2, j + 3) = CInt(16 - Range("I" & i + 2).Value)
    Mais voila après, je ne trouve pas dans la dernière colonne des différences homogènes au calcul demandé !

    Une solution ?

    Merci.

  14. #14
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    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
    Option Explicit
     
    'Active la Référence Microsoft Scripting Runtime
    Sub Traiter()
    Const Cible As String = "M1"
    Dim Str As String, Code As String, Res()
    Dim LastLig As Long, i As Long, n As Long
    Dim j As Integer, m As Integer, Nb As Integer
    Dim MonDico As New Scripting.Dictionary
    Dim ItemDico As New Scripting.Dictionary
    Dim Tb
     
    Application.ScreenUpdating = False
    With Feuil1
        LastLig = .Cells(.Rows.Count, "A").End(xlUp).Row
        Tb = .Range("A2:B" & LastLig)
        For i = 1 To UBound(Tb, 1)
            Str = Tb(i, 1)
            Code = Tb(i, 2)
            If Code <> "" Then Code = SupprNum(Tb(i, 2))
            If InStr(Str, "-") Then
                If Not ItemDico.Exists(Code) And Code <> "" Then ItemDico.Add Code, Code
                Str = Left(Str, InStrRev(Str, "-") - 1)
     
                If Not MonDico.Exists(Str) Then
                    MonDico.Add Str, "," & Code
                Else
                    MonDico(Str) = MonDico(Str) & "," & Code
                End If
            End If
        Next i
     
        m = ItemDico.Count
        If m > 0 Then
            n = MonDico.Count
            If n > 0 Then
                ReDim Res(1 To n + 1, 1 To m + 3)
                Res(1, 1) = "S"
                Res(1, 2) = "P"
                Res(1, m + 3) = "Positions Libres"
                For j = 0 To m - 1
                    Res(1, j + 3) = ItemDico.Items(j)
                Next j
                For i = 0 To n - 1
                    Str = MonDico.Keys(i)
                    Res(i + 2, 1) = Mid(Str, 3)
                    Res(i + 2, 2) = UBound(Split(MonDico.Items(i), ","))
                    For j = 0 To m - 1
                        Res(i + 2, j + 3) = CompteItems(MonDico.Items(i), ItemDico.Items(j))
                    Next j
                    Res(i + 2, m + 3) = 16 - Res(i + 2, 2)
                Next i
                Set MonDico = Nothing
                .Range(Cible).Resize(n + 1, m + 3) = Res
                .Range(Cible).Resize(n + 1, m + 3).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlYes
            End If
        End If
    End With
    End Sub
     
    Private Function SupprNum(ByVal Str As String) As String
    Dim Rg As Object
    Dim Txt As String
     
    Set Rg = CreateObject("vbscript.Regexp")
    With Rg
        .Pattern = "^\d*"
        .Global = True
        Txt = .Replace(Str, "")
    End With
    Set Rg = Nothing
    If Txt = "UNI6" Or Txt = "UDI6" Then Txt = "UDI6/UNI6"
    SupprNum = Txt
    End Function
     
    Private Function CompteItems(ByVal Str As String, ByVal Txt As String) As Integer
    Dim i As Integer, n As Integer
    Dim Tb
     
    If Len(Str) > 0 Then
        Str = Mid(Str, 2)
        If InStr(Str, ",") Then
            Tb = Split(Str, ",")
            For i = LBound(Tb) To UBound(Tb)
                If UCase(Tb(i)) = UCase(Txt) Then n = n + 1
            Next i
        End If
    End If
    CompteItems = n
    End Function

  15. #15
    apt
    apt est déconnecté
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Points : 118
    Points
    118
    Par défaut
    Bonjour mercatog,

    Ca marche maintenant. Merci.

    Voila le code final utilisé :

    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
    Option Explicit
     
    'Active la Référence Microsoft Scripting Runtime
    Sub Traiter()
    Const Cible As String = "E1"
    Dim Str As String, Code As String, Res()
    Dim LastLig As Long, i As Long, n As Long
    Dim j As Integer, m As Integer, Nb As Integer
    Dim MonDico As New Scripting.Dictionary
    Dim ItemDico As New Scripting.Dictionary
    Dim Tb
     
    Application.ScreenUpdating = False
    With Feuil1
        LastLig = .Cells(.Rows.Count, "A").End(xlUp).Row
        Tb = .Range("A2:B" & LastLig)
        For i = 1 To UBound(Tb, 1)
            Str = Tb(i, 1)
            Code = SupprNum(Tb(i, 2))
            If Code = "UNI6" Or Code = "UDI6" Then Code = "UDI6/UNI6"
            If InStr(Str, "-") Then
                If Not ItemDico.Exists(Code) And Code <> "" Then ItemDico.Add Code, Code
                Str = Left(Str, InStrRev(Str, "-") - 1)
     
                If Not MonDico.Exists(Str) Then
                    MonDico.Add Str, "," & Code
                Else
                    MonDico(Str) = MonDico(Str) & "," & Code
                End If
            End If
        Next i
     
        m = ItemDico.Count
        If m > 0 Then
            n = MonDico.Count
            If n > 0 Then
                ReDim Res(1 To n + 1, 1 To m + 3)
                Res(1, 1) = "S"
                Res(1, 2) = "P"
                Res(1, m + 3) = "Positions Libres"
                For j = 0 To m - 1
                    Res(1, j + 3) = ItemDico.Items(j)
                Next j
                For i = 0 To n - 1
                    Str = MonDico.Keys(i)
                    Res(i + 2, 1) = Mid(Str, 3)
                    Res(i + 2, 2) = UBound(Split(MonDico.Items(i), ","))
                    For j = 0 To m - 1
                        Res(i + 2, j + 3) = CompteItems(MonDico.Items(i), ItemDico.Items(j))
                    Next j
                    Res(i + 2, m + 3) = 16 - Res(i + 2, 2)
                Next i
                Set MonDico = Nothing
                .Range(Cible).Resize(n + 1, m + 3) = Res
                .Range(Cible).Resize(n + 1, m + 3).Sort Key1:=.Range(Cible), Order1:=xlAscending, Header:=xlYes
            End If
        End If
    End With
    End Sub
     
    Private Function SupprNum(ByVal Str As String) As String
    Dim Rg As Object
     
    Set Rg = CreateObject("vbscript.Regexp")
    With Rg
        .Pattern = "^\d{0,3}"
        .Global = True
        SupprNum = .Replace(Str, "")
    End With
    Set Rg = Nothing
    End Function
     
    Private Function CompteItems(ByVal Str As String, ByVal Txt As String) As Integer
    Dim i As Integer, n As Integer
    Dim Tb
     
    If Len(Str) > 0 Then
        Str = Mid(Str, 2)
        If InStr(Str, ",") Then
            Tb = Split(Str, ",")
            For i = LBound(Tb) To UBound(Tb)
                If UCase(Tb(i)) = UCase(Txt) Then n = n + 1
            Next i
        End If
    End If
    CompteItems = n
    End Function

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/10/2013, 15h02
  2. Réponses: 5
    Dernier message: 31/08/2011, 03h37
  3. Extraction de donnée par ADO ACCESS vers Excel
    Par roidurif dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 12/05/2009, 19h29
  4. Extraction de données par dates
    Par fancho dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 11/03/2009, 19h47
  5. [DBGrid] Affichage d'un sous-ensemble de données
    Par Jean-Jacques Engels dans le forum Bases de données
    Réponses: 3
    Dernier message: 02/09/2004, 17h31

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