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 :

Comparer une plage à un tableau [XL-2007]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    apt
    apt est déconnecté
    Membre éclairé
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Par défaut Comparer une plage à un tableau
    Bonsoir à tous,

    J'aimerais comparer une plage à un tableau Tbl.

    Je voulais utiliser la fonction InArray, mais ça ne marche pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if cel.Value inarray(tbl) then range("F" & Cel.Row).Value="#" & Strdate & "#"
    Alors j'ai ajouté quelques lignes de codes pour remplacer le travail de cette fonction...

    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
    Sub Comparer()
        Dim WS1 As Worksheet, WS2 As Worksheet
        Dim i As Long, j As Long
        Dim Tbl() As String, Strg As String, Strdate As String
        Dim C As Range, Cel As Range
     
        Set WS1 = Sheets("feuil1")
        Set WS2 = Sheets("feuil2")
        Strdate = Format(Now, "dd/mm/yy")
     
     
        '-- Remplir le tableau Tbl par les valeurs de la colonne A correspondante
        i = 1
        For Each C In WS2.Range("F2:F" & WS2.[F65000].End(xlUp).Row)
            If C.Value = "Done" Then
                ReDim Preserve Tbl(i)
                Tbl(i) = WS2.Range("A" & C.Row)
                i = i + 1
            End If
        Next C
     
        '-- Regrouper les valeurs du Tbl dans la chaine Strg pour faciliter la comparaison avec InStr
        For j = 1 To UBound(Tbl)
            Strg = Strg & Tbl(j) & "|"
        Next j
     
        '-- S'il y a une valeur de la colonne A feuille 1 qui corresponde à une valeur de Tbl
        '-- On écrit la date d'aujourd'hui dans la colonne F
        For Each Cel In WS1.Range("A2:A" & [A65000].End(xlUp).Row)
     
            'if cel.Value inarray(tbl) then range("F" & Cel.Row).Value="#" & Strdate & "#"
            If InStr(Strg, Cel.Value) = 1 Then
                Range("F" & Cel.Row).Value = "#" & Strdate & "#"
            End If
        Next Cel
    End Sub
    1 - Existe-t-il une fonction similaire pour comparer une valeur à toutes les valeurs d'un tableau en une seule fois ?

    2 - Si mon tableau Tbl comporte 4 valeurs, la dernière boucle du code ne considère la comparaison juste avec Instr que pour la première valeur seulement !

    3 - Sinon comment réduire ces lignes de codes ?

    Merci d'avance.

  2. #2
    Membre Expert Avatar de ZebreLoup
    Homme Profil pro
    Ingénieur Financier
    Inscrit en
    Mars 2010
    Messages
    994
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Financier
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 994
    Par défaut
    Tu pourrais transformer ta plage en Dictionary et utiliser la fonction Exists...

  3. #3
    apt
    apt est déconnecté
    Membre éclairé
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Par défaut
    Bonjour Sébastien,

    J'ai utilisé ce code pour remplir mon dictionnaire dic :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    '--------------------------------------------------------
    For Each C In WS2.Range("F2:F" & LastLg)
                If C.Value = "Done" Then
                    If Not dic.Exists(C.Value) Then
                        dic.Add Key:=C.Value, Item:=C.Value
                        MsgBox dic.Items(i)
                        i = i + 1
                    End If
                End If
            Next C
    '--------------------------------------------------------
    et j'ai cette erreur sur la ligne :

    Erreur d'exécution '451'

    La procédure Property Let n'est pas définie et ma procédure Property Get n'a pas renvoyé d'objet

  4. #4
    Membre Expert Avatar de ZebreLoup
    Homme Profil pro
    Ingénieur Financier
    Inscrit en
    Mars 2010
    Messages
    994
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Financier
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 994
    Par défaut
    i vaut combien ?
    Le mieux est plutôt d'utiliser la propriété Item en donnant la clé en paramètre. Mais ça dépend de ce que tu veux faire de ton dictionnaire après. Si tu veux juste énumérer les éléments, ce sera plus simple de mettre dic.Items dans une variable et de travailler sur cette variable.

  5. #5
    Expert confirmé Avatar de casefayere
    Homme Profil pro
    RETRAITE
    Inscrit en
    Décembre 2006
    Messages
    5 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : RETRAITE
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5 138
    Par défaut
    Bonsoir,

    Je suis étonné par ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    '--------------------------------------------------------
    For Each C In WS2.Range("F2:F" & LastLg)
                If C.Value = "Done" Then
                    If Not dic.Exists(C.Value) Then
                        dic.Add Key:=C.Value, Item:=C.Value
                        MsgBox dic.Items(i)
                        i = i + 1
                    End If
                End If
            Next C
    '--------------------------------------------------------
    je le dissèque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each C In WS2.Range("F2:F" & LastLg)
    si tu as beaucoup de lignes, passes par un tableau, ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim tb, x As Long, LastLg'déclaré avant
      tb = WS2.Range("F2:F" & LastLg)
    ensuite cela donnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    For x = 1 To UBound(tb)
        If tb(x,1) = "Done" Then
          If Not dic.Exists(tb(x,1)) Then
            dic.Add tb(x,1), CStr(tb(x,1))
            MsgBox dic.Items(i)'ça ne fonctionne pas
            i = i + 1
          End If
        End If
      Next x
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If tb(x,1) = "Done" Then
    tu incrémentes ton dico d'un seul item car "Done" ne peux apparaitre qu'une fois, si j'ai compris
    le code complet sans tenir compte de ce que je viens de dire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Dim tb, x As Long
    With WS2
      LastLg = .Range("F" & .Rows.Count).End(xlUp).Row
      tb = .Range("F2:F" & LastLg)
      For x = 1 To UBound(tb)
        If tb(x, 1) = "Done" Then
          If Not dic.Exists(tb(x, 1)) Then
            dic.Add tb(x, 1), CStr(tb(x, 1))
            MsgBox dic.Item(tb(x, 1))
          End If
        End If
      Next x
    End With
    Cordialement,
    Dom
    _____________________________________________
    Vous êtes nouveau ? pour baliser votre code, cliquer sur cet exemple : Anomaly
    pensez à cliquer sur :resolu: si votre problème l'est
    Par contre, il est désagréable de voir une discussion résolue sans message final du demandeur (satisfaction, désarroi, remerciement, conclusion...)

  6. #6
    apt
    apt est déconnecté
    Membre éclairé
    Inscrit en
    Mai 2002
    Messages
    867
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 867
    Par défaut
    Bonsoir casefayere,

    Dans la colonne F, le nombre de la chaine "Done" peut-être 0 ou plus.

    Et voila le code que j'utilise :


    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
    Dim LastLg As Long, i As Long
    Dim dic As Object
    Dim C As Range, Cel As Range
    Dim StrDate As String
     
    StrDate = Format(Now, "dd/mm/yyyy")
     
        i = 1
        LastLg = WS2.[F65000].End(xlUp).Row
     
        '-- Si on a plus d'une ligne (hormis le titre)  dans la colonne F
        If LastLg > 1 Then
            Set dic = CreateObject("Scripting.Dictionary")
     
            '-- On remplit le dictionnaire dic par les valeurs de la colonne A de Feuil2 (IDs) correspondantes.
            For Each C In WS2.Range("F2:F" & LastLg)
                '-- Si une cellule contient la valeur "Done" on récupère le ID correspondant dans colonne A
                If C.Value = "Done" Then
                    If Not dic.Exists(C.Value) Then
                        dic.Add Key:=C.Offset(0, -5).Value, Item:=C.Offset(0, -5).Value
                        MsgBox dic.Items(i)
                        i = i + 1
                    End If
                End If
            Next C
     
            '-- On compare les valeurs du dic avec celles de la colonne A de Feuil1 (IDs)
            For Each Cel In WS1.Range("A2:A" & [A65000].End(xlUp).Row)
                If dic.Exists(Cel.Value) Then
                    MsgBox "Cel True: " & Cel
                    WS1.Range("F" & Cel.Row).Value = "#" & StrDate & "#"
                End If
            Next Cel
        End If

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

Discussions similaires

  1. Comparer deux colonnes adjacentes une à une sur mon tableau?
    Par drthodt dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 06/12/2007, 10h11
  2. Réponses: 3
    Dernier message: 24/07/2007, 21h27
  3. Remplir une plage à partir d'un tableau
    Par roudy78 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/05/2007, 10h56
  4. [VBA-E] Affecter un tableau à une plage de cellules, serait-ce possible ?
    Par ouskel'n'or dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 08/02/2007, 12h59
  5. Réponses: 2
    Dernier message: 17/12/2006, 18h17

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