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 :

Récupérer plusieurs lignes d'une table (array) [XL-2019]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Septembre 2019
    Messages : 19
    Par défaut Récupérer plusieurs lignes d'une table (array)
    Bonjour à tous,

    J'ai un problème que je n'arrive pas à résoudre.

    Mon objectif est trouver des lignes spécifiques dans un tableau de 10 colonne [A ->J] avec 15000 lignes. Ces lignes spécifiques doivent vérifier une condition en colonne B et une condition en colonne C.

    Le première étape que j'ai fait dans le sub est de ranger mes données dans une table : (tab1 est donc la table avec les données du tableau)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim tab1()
     
    Workbooks.("Fichier").Worksheets("Feuille").Activate
    Nb_ligne_tab1 = (Range("A" & Rows.Count).End(x1Up).Row)
    Nb_colonne_tab1 =Cells(1,Colums.Count).End(x1Left).Column
    tab1 = Range (Cells (1,1),Cells(Nb_ligne_tab1,NB_colonne_tab1))
    Ensuite je cherche les valeurs : (tab2 est la table de résultat à 2 lignes et 1 colonne, on pourra incrémenter d'autre colonne)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    For p = 1 to nb_ligne_tab1
    If Cstr("tartempion4") = Cstr(tab1(p,2)) And Cstr("bidule01") = Cstr(tab1(p,3)) Then
    tab2(1,1)=tab1(p,4)
    tab2(2,1)=tab1(p,5)
    End if
    Next
    Ce code marche mais mon soucis est enfaite qu'il y a plusieurs résultats et que mon code s'arrête au premier qu'il trouve.
    Pour trouver tous les résultats, j'ai essayé les méthodes avec For Each, Do Loop, Filter, Match mais rien ne fonctionne donc j'espère que vous allez pouvoir m'aider et j'espère avoir été clair pour expliquer mon problème

    Merci beaucoup !!

  2. #2
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 243
    Par défaut
    hello,
    Citation Envoyé par Jonhy7 Voir le message
    J'ai un problème que je n'arrive pas à résoudre.
    Mon objectif est trouver des lignes spécifiques dans un tableau de 10 colonne [A ->J] avec 15000 lignes. Ces lignes spécifiques doivent vérifier une condition en colonne B et une condition en colonne C.
    je ne connais le but final de ton code mais pourquoi n'utilises-tu pas un filtre pour ne récupérer que certaines lignes de ta feuille avec certaines conditions.
    Même sans utiliser de VBA on peut faire la manipulation que tu veux faire :
    Exemple :
    feuille de départ :
    Nom : FiltreTartempion1.PNG
Affichages : 845
Taille : 49,9 Ko

    1 - Sélectionner toutes les cellules que l'on veut filtrer (avec la ligne d'entête).
    2 - Dans l'onglet Données cliquer sur Filtrer. Des boutons avec flèches vers le bas apparaissent dans la ligne d'entête.
    3 - Dans les colonnes voulues , sélectionner le critère de filtre.
    4 - Et voilà on ne voit plus que les lignes avec les critères demandés :
    Nom : FiltreTartempion2.PNG
Affichages : 526
Taille : 31,8 Ko

    Ami calmant, J.P

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Septembre 2019
    Messages : 19
    Par défaut
    Bonjour jurassic pork et je te remercie pour la réponse.

    Cependant, cette méthode je la connais et ne peux pas être applicable dans mon cas car je dois automatiser le processus. J'ai simplifier le problème pour que ce soit compréhensible mais le problème est bien de trouver différentes lignes dans la table avec deux conditions spécifiques.

    Je ne peux pas passer par la feuille Excel car il faut répéter l'opération pour des milliers de couples et retourner des valeurs et je suis obliger de passer par des tables (array) pour stocker la data car mes fichiers excels sont très grands (50000 lignes).

  4. #4
    Expert confirmé Avatar de hyperion13
    Homme Profil pro
    Webplanneur
    Inscrit en
    Octobre 2007
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Réunion

    Informations professionnelles :
    Activité : Webplanneur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 288
    Par défaut
    Salut
    Une piste en VBA
    L'idée est de parcourir chaque cellule (c) dans ton tableau de données (rng), d'y trouver les 2 valeurs chercher et ensuite, je suppose, recopier la liste des valeurs trouvées dans la même feuille de calculs. Pour ma part, à partir de la cellule A40
    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
    Sub CopieDynamique()
    Dim xlwbk As Workbook, xlwbs As Worksheet
    Dim c As Range, rng As Range
    Dim myArray() As Variant
    Dim i As Long
     
    Set xlwbk = ThisWorkbook
    Set xlwbs = Worksheets("Feuille")
    Set rng = xlwbs.Range(Cells(2, 1), Cells(Range("A" & Rows.Count).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column))
     
    xlwbs.Range("A40:A" & Range("A" & Rows.Count).End(xlUp).Row).ClearContents
     
    For Each c In rng
        If c.Value = "tartempion4" Or c.Value = "bidule01" Then
            ReDim Preserve myArray(i)
            myArray(i) = c.Value
            i = i + 1
        End If
    Next c
    For i = LBound(myArray) To UBound(myArray)
        Cells(40 + i, 1) = myArray(i)
    Next i
    End Sub

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Septembre 2019
    Messages : 19
    Par défaut
    Bonjour hyperion13, merci pour ta réponse.

    L'idée est pas mal et j'avais essayé quelque chose comme ça mais ça n'avait pas marché. D'ailleurs tu n'as pas mis la plage dans une table, moi j'avais mis dans une table et j'avais faie un For Each, peut être pour ça que ça n'avait pas fonctionnée..

    Je vous montre ce que j'ai fait :

    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
    Sub CopieDynamique()
     
    'la première étape est de mettre les données dans une table
     
    Dim tab_info()
     
    Workbooks("Source").Worksheets("Infos").Activate
    Nb_Ligne_Infos = (Range("A" & Rows.Count).End(xlUp).Row)
    Nb_Colonne_Infos = Cells(1, Columns.Count).End(xlToLeft).Column
    tab_infos = Range(Cells(1, 1), Cells(Nb_Ligne_so1, Nb_Colonne_so1))
     
    Dim b As Variant
    Dim v as Integer
    Dim tab_intern(2,1)
     
    v = 1
     
    'on parcourt chaque ligne de la table
     
    For Each b In tab_infos
     
        'on vérifie si on trouve des correspondances dans les colonnes 5 et 1
     
        If CStr(tab_infos(b, 5)) = CStr("1234") And CStr(tab_infos(b, 1)) = CStr("6547")  Then
     
            'si oui, on stocke le résultat des colonnes 2 et 3 dans la table tab_intern (j'utiles une table pour stocker mes résultats car donc mon cas réel c'est 
            plus pratique)
     
            ReDim tab_intern(2, v)
     
            tab_intern(1, v) = tab_infos(b, 2)
            tab_intern(2, v) = tab_infos(b, 3)
     
     
            ' Je copie les données sur une feuille excel pour vérifier
     
            Workbooks("Source").Worksheets("TEST").Cells(v, 1).Value = tab_intern(1, v)
            Workbooks("Source").Worksheets("TEST").Cells(v, 2).Value = tab_intern(2, v)
     
            'on incrémente tab_intern s'il y a plusieurs lignes dans tab_infos qui correspond à notre requête
     
            v = v + 1
     
        End If
     
    Next b
     
    End Sub
    Voilà j'ai fais ça mais ca ne fonctionne pas, ca me mets une erreur de incompatibilité pour ma ligne avec le If.

    L'erreur est que le For Each ne parcourt pas la table, la variable b prend la première valeur du tableau et donc le reste du programme ne marche plus.
    Est-ce qu'il y a une solution pour parcourir une table ?

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2013
    Messages : 122
    Par défaut
    Bonjour Johny7

    Tu n'étais pas loin, voilà qui marche

    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
    Sub CopieDynamique()
     
    'la première étape est de mettre les données dans une table
     
    Dim tab_infos()
    Dim nb_ligne_Infos, Nb_Colonne_Infos, Lig
    Dim wshSrc As Worksheet
    Dim wshDst As Worksheet
     
    Set wshDst = thisWorkbook.Worksheets("TEST")
     
    Set wshSrc = thisWorkbook.Worksheets("Infos")  '.Activate
    nb_ligne_Infos = wshSrc.Range("A" & wshSrc.Rows.count).End(xlUp).row
    Nb_Colonne_Infos = wshSrc.Cells(1, wshSrc.Columns.count).End(xlToLeft).Column
    tab_infos = wshSrc.Range(wshSrc.Cells(1, 1), wshSrc.Cells(nb_ligne_Infos, Nb_Colonne_Infos))
     
    Dim b As Variant
    Dim v As Integer
    Dim tab_intern()
     
    v = 1
     
    'on parcourt chaque ligne de la table
     
    For Lig = 1 To nb_ligne_Infos
     
        'on vérifie si on trouve des correspondances dans les colonnes 5 et 1
     
        If CStr(tab_infos(Lig, 5)) = CStr("1234") And CStr(tab_infos(Lig, 1)) = CStr("6547") Then
     
            'si oui, on stocke le résultat des colonnes 2 et 3 dans la table tab_intern (j'utilise une table pour stocker mes résultats car donc mon cas réel c'est plus pratique)
     
            ReDim Preserve tab_intern(2, v)
     
            tab_intern(1, v) = tab_infos(Lig, 2)
            tab_intern(2, v) = tab_infos(Lig, 3)
     
            ' Je copie les données sur une feuille excel pour vérifier
     
            wshDst.Cells(v, 1).value = tab_intern(1, v)
            wshDst.Cells(v, 2).value = tab_intern(2, v)
     
            'on incrémente tab_intern s'il y a plusieurs lignes dans tab_infos qui correspond à notre requête
            v = v + 1
        End If
    Next 'Lig
    End Sub

  7. #7
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 243
    Par défaut
    hello,
    voici une autre version du code à fraflt69 où j'ai fait quelques modifications :
    1 - Dans le tableau tab_intern il y avait une colonne en trop (0) qui ne servait pas. Nouveau code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ReDim Preserve tab_intern(1 To 2, 1 To v)
    2 - On commençait le balayage à partir de la ligne 1 qui est la ligne d'entête -> On commence à la ligne 2
    3 - Les données et les colonnes ne correspondaient pas aux données à Jonhy7 -> Mise en concordance.
    4 - La recopie du tableau tab_intern dans la feuille de vérification se faisait ligne par ligne -> Utilisation de la fonction
    Array2Range pour remplir la feuille en une seule fois.
    5 - Ajout d'une mesure du temps d'exécution de la macro par Timer.
    Voici le code modifié :
    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
    Sub CopieDynamique()
    'la première étape est de mettre les données dans une table
    Dim tab_infos()
    Dim nb_ligne_Infos, Nb_Colonne_Infos, Lig
    Dim wshSrc As Worksheet
    Dim wshDst As Worksheet
    Dim t1, t2 As Double
    t1 = Timer
    Set wshDst = ThisWorkbook.Worksheets("Test")
     
    Set wshSrc = ThisWorkbook.Worksheets("Feuille")  '.Activate
    nb_ligne_Infos = wshSrc.Range("A" & wshSrc.Rows.Count).End(xlUp).Row
    Nb_Colonne_Infos = wshSrc.Cells(1, wshSrc.Columns.Count).End(xlToLeft).Column
    tab_infos = wshSrc.Range(wshSrc.Cells(2, 1), wshSrc.Cells(nb_ligne_Infos, Nb_Colonne_Infos))
     
    Dim b As Variant
    Dim v As Integer
    Dim tab_intern()
     
    v = 1
     
    'on parcourt chaque ligne de la table
     
    For Lig = 1 To nb_ligne_Infos - 1
     
        'on vérifie si on trouve des correspondances dans les colonnes 5 et 1
     
        If CStr(tab_infos(Lig, 2)) = "tartempion4" And CStr(tab_infos(Lig, 3)) = "bidule01" Then
            'si oui, on stocke le résultat des colonnes 4 et 5 dans la table tab_intern (j'utilise une table pour stocker mes résultats car donc mon cas réel c'est plus pratique)
     
            ReDim Preserve tab_intern(1 To 2, 1 To v)
     
            tab_intern(1, v) = tab_infos(Lig, 4)
            tab_intern(2, v) = tab_infos(Lig, 5)
     
            ' Je copie les données sur une feuille excel pour vérifier
     
            'wshDst.Cells(v, 1).Value = tab_intern(1, v)
            'wshDst.Cells(v, 2).Value = tab_intern(2, v)
     
            'on incrémente tab_intern s'il y a plusieurs lignes dans tab_infos qui correspond à notre requête
            v = v + 1
        End If
    Next 'Lig
     ' Je copie les données sur une feuille excel pour vérifier
    Array2Range tab_intern, wshDst.Range("A1"), True
    t2 = Timer
    Debug.Print "Temps écoulé :", CStr(t2 - t1) + " s"
    End Sub
     
    Sub Array2Range(arr, destTL As Range, transpose As Boolean)
        If transpose Then arr = Application.WorksheetFunction.transpose(arr)
        'dumps  (1D/2D) onto a sheet where [destTL] is the top-left output cell.
        destTL.Resize(UBound(arr, 1) - LBound(arr, 1) + 1, _
            UBound(arr, 2) - LBound(arr, 2) + 1) = arr
    End Sub

    6 - Ajout d'une procédure de remplissage alétoire des colonnes B et C dont voici le code :
    Voici la procédure de remplissage :
    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
    Sub RemplissageAlea()
    Dim tab_infos()
    Dim nb_ligne_Infos, Nb_Colonne_Infos, Lig
    Dim wshSrc As Worksheet
    Dim wshDst As Worksheet
    Dim Tartempion, Bidule
    Dim randArrIndex As Integer
    Set wshDst = ThisWorkbook.Worksheets("Test")
    Set wshSrc = ThisWorkbook.Worksheets("Feuille")  '.Activate
    nb_ligne_Infos = wshSrc.Range("A" & wshSrc.Rows.Count).End(xlUp).Row
    Nb_Colonne_Infos = wshSrc.Cells(1, wshSrc.Columns.Count).End(xlToLeft).Column
    tab_infos = wshSrc.Range(wshSrc.Cells(2, 1), wshSrc.Cells(nb_ligne_Infos, Nb_Colonne_Infos))
    v = 1
    Tartempion = Array("", "tartempion1", "tartempion3", "tartempion4")
    Bidule = Array("", "bidule01", "bidule02", "bidule03")
    'on parcourt chaque ligne de la table
    For Lig = 1 To nb_ligne_Infos - 1
        randArrIndex = Int(4 * Rnd)
        tab_infos(v, 2) = Tartempion(randArrIndex)
        randArrIndex = Int(4 * Rnd)
        tab_infos(v, 3) = Bidule(randArrIndex)
        v = v + 1
    Next 'Lig
    End Sub
    Voici les dernières lignes des feuilles Feuille et Test :

    Nom : JonHy1.PNG
Affichages : 443
Taille : 66,8 Ko--------->Nom : JonHy2.PNG
Affichages : 452
Taille : 23,7 Ko


    Voici les résultats sur mon ordinateur pour une feuille de 16000 lignes avec 1056 lignes qui correspondent au critère.
    temps écoulé : 110 ms en utilisant la copie ligne par ligne dans la feuille de destination.
    temps écoulé : 47 ms en utilisant la fonction Array2Range
    temps écoulé : 31 ms sans utiliser la feuille de destination.


    Ami calmant, J.P

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

Discussions similaires

  1. [MySQL] Récupérer plusieurs lignes d'une BDD
    Par orbitalxp dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 12/01/2007, 18h44
  2. Réponses: 2
    Dernier message: 15/09/2006, 12h18
  3. MAJ de plusieurs lignes d'une table
    Par bencheikh dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 05/08/2006, 10h47
  4. Mettre a jour plusieurs lignes d'une table
    Par Tartenpion dans le forum Langage SQL
    Réponses: 4
    Dernier message: 17/12/2005, 18h50
  5. Procédure stockée - Retourner plusieurs ligne d'une table
    Par ronando dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 02/11/2005, 13h19

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