Eclater des données concaténées ligne par ligne

Bonjour,

Je suis face à une problématique assez complexe.

Je possède un fichier CSV (ci-joint) qui comporte des cellules avec des valeurs concaténées, ex :

DateAgentListe 1Liste 2Liste 3
27/04/2021Nicolas18155,5421,519787,6005454875461114,8731,244
28/04/2021Terry84514,321547,5544719987,2001
29/04/2021Marc1454,211
30/04/2021Bryan654841

Je souhaiterais que chacune de ces valeurs concaténées soient "éclatées" ligne par ligne tout en reprenant les valeurs des cellules qui ne sont pas concaténées, ex:

DateAgentListe 1Liste 2Liste 3
27/04/2021Nicolas1815554875461114
27/04/2021Nicolas54218731
27/04/2021Nicolas519787244
27/04/2021Nicolas60054
28/04/2021Terry8451419987
28/04/2021Terry3215472001
28/04/2021Terry55447
29/04/2021Marc1454
29/04/2021Marc211
30/04/2021Bryan654841

J'ai essayé en replaçant chaque "virgule" par un saut de ligne et des "points-virgules" sur le fichier CSV directement, mais je suis loin du résultat voulu.

Auriez-vous une idée SVP ?

Merci beaucoup.

Terry.

16resultat-voulu.xlsx (13.46 Ko)
11donnees-source.csv (206.00 Octets)

Bonjour à tous,

Tu ouvres ton csv avec wordpad, par exemple, et tu remplace les , par des ; tu enregistres

et apres tu ouvres ton fichier avec excel

Crdlmt

Bonjour,

J'ai déjà essayé cette méthode, voici le résultat obtenu :

DateAgentListe 1Liste 2Liste 3
27/04/2021Nicolas18155542151978760054548754611148731244
28/04/2021Terry8451432154755447199872001
29/04/2021Marc1454211
30/04/2021Bryan654841

Ce n'est pas ce que je recherche malheureusement.

Bonjour à tous,

Pour simplifier, il faut que tu boucles comme ceci :

    For i = 2 To UBound(a, 1)
            x = Split(a(i, 3), ",")
            y = Split(a(i, 4), ",")
            z = Split(a(i, 5), ",")
            For j = 0 To Application.Max(UBound(x), UBound(y),UBound(z))
                n = n + 1
                b(n, 1) = a(i, 1) : b(n, 2) = a(i, 2)
                b(n, 3) = Split(a(i, 3), ",")(j)
                b(n, 4) = Split(a(i, 4), ",")(j)
                b(n, 5) = Split(a(i, 5), ",")(j)
            Next
    Next
 

klin89

Merci pour ta réponse @Klin89.

Ta solution m'a l'air intéressante, mais il me semble qu'il manque la partie incluant la définition des fonctions a(..,..) et b(..,..) ?

Je ne suis pas très fort en VBA.

Bonjour,

Faut-il inclure le VBA dans une fonction ?

Re TerrryMarsault,

Vois ceci :

Option Explicit
Sub test()
    Dim a, b(), i As Long, j As Long, x, y, z, n As Long
    With Sheets("Liste numéros").Range("a3").CurrentRegion
        a = .Value
        'attention à la 1ère dimension
        ReDim b(1 To 100, 1 To 5): n = 1
        b(n, 1) = a(1, 1): b(n, 2) = a(1, 2)
        b(n, 3) = a(1, 3): b(n, 4) = a(1, 4)
        b(n, 5) = a(1, 5)
        For i = 2 To UBound(a, 1)
            x = Split(a(i, 3), ",")
            y = Split(a(i, 4), ",")
            z = Split(a(i, 5), ",")
            ReDim Preserve x(0 To Application.Max(UBound(x), UBound(y), UBound(z)))
            ReDim Preserve y(0 To Application.Max(UBound(x), UBound(y), UBound(z)))
            ReDim Preserve z(0 To Application.Max(UBound(x), UBound(y), UBound(z)))
            For j = 0 To Application.Max(UBound(x), UBound(y), UBound(z))
                n = n + 1
                b(n, 1) = a(i, 1): b(n, 2) = a(i, 2)
                b(n, 3) = x(j): b(n, 4) = y(j): b(n, 5) = z(j)
            Next
        Next
        .Offset(, .Columns.Count + 1).Resize(n).Value = b
    End With
End Sub

Ça bug au niveau de "Redim Preserve", si une ligne est complètement vide

klin89

Impressionnant... Merci beaucoup Klin89 !

Cela fonctionne très bien pour moi, les cellules vides seront remplies d'un "zéro" de toutes façons.

Bon WE.

Re,

J'ai réajusté le code et gommé le problème évoqué plus haut.

Option Explicit
Sub test()
    Dim a, b(), i As Long, j As Long, n As Long, k, x, y, z
    With Sheets("Liste numéros").Range("a3").CurrentRegion
        a = .Value
        'attention à la 1ère dimension
        ReDim b(1 To 100, 1 To 5): n = 1
        b(n, 1) = a(1, 1): b(n, 2) = a(1, 2)
        b(n, 3) = a(1, 3): b(n, 4) = a(1, 4)
        b(n, 5) = a(1, 5)
        For i = 2 To UBound(a, 1)
            x = Split(a(i, 3), ",")
            y = Split(a(i, 4), ",")
            z = Split(a(i, 5), ",")
            k = Application.Max(UBound(x), UBound(y), UBound(z))
            If k = -1 Then k = 0
            ReDim Preserve x(0 To k)
            ReDim Preserve y(0 To k)
            ReDim Preserve z(0 To k)
            For j = 0 To k
                n = n + 1
                b(n, 1) = a(i, 1): b(n, 2) = a(i, 2)
                b(n, 3) = x(j): b(n, 4) = y(j): b(n, 5) = z(j)
            Next
        Next
        .Offset(, .Columns.Count + 1).Resize(n).Value = b
    End With
End Sub

klin89

Merci pour cette correction.

J'ai édité le code pour inclure une colonne en plus (Liste 4), ça a l'air de fonctionner, est-ce correct ?

Question subsidiaire: si j'ai bien compris le 1 To 100 dans la fonction b() sert à indiquer le nombre maximal de lignes, c'est bien cela ?

Option Explicit
Sub test()

    Dim a, b(), i As Long, j As Long, n As Long, k, x, y, z, zz

    With Sheets("Liste numéros").Range("a3").CurrentRegion

        a = .Value
        'attention à la 1ère dimension

        ReDim b(1 To 100, 1 To 6): n = 1

        b(n, 1) = a(1, 1)
        b(n, 2) = a(1, 2)
        b(n, 3) = a(1, 3)
        b(n, 4) = a(1, 4)
        b(n, 5) = a(1, 5)
        b(n, 6) = a(1, 6)

        For i = 2 To UBound(a, 1)
            x = Split(a(i, 3), ",")
            y = Split(a(i, 4), ",")
            z = Split(a(i, 5), ",")
            zz = Split(a(i, 6), ",")
            k = Application.Max(UBound(x), UBound(y), UBound(z), UBound(zz))

            If k = -1 Then k = 0
            ReDim Preserve x(0 To k)
            ReDim Preserve y(0 To k)
            ReDim Preserve z(0 To k)
            ReDim Preserve zz(0 To k)

            For j = 0 To k
                n = n + 1
                b(n, 1) = a(i, 1)
                b(n, 2) = a(i, 2)
                b(n, 3) = x(j)
                b(n, 4) = y(j)
                b(n, 5) = z(j)
                b(n, 6) = zz(j)
            Next

        Next

        .Offset(, .Columns.Count + 1).Resize(n).Value = b

    End With
End Sub

Terry.

Par ailleurs, le code plante lorsqu'il y a plus de 223 lignes dans la feuille, saurais-tu pourquoi ?

Malgré que dans b() j'ai indiqué 1 To 300

capture

Re,

Oui, si le tableau restitué doit dépassé 100 lignes, cela coincera.

La variable n s'incrémente de 1 à chaque nouvelle ligne créée pour au final te donner le nombre de lignes total du tableau qui sera restitué.

Regarde ce que vaut n et i au moment de l'erreur !

C'est plus de 223 lignes dans le tableau source ou dans le tableau qui sera restitué ?

klin89

Re,

J'ai regardé : au moment de l'erreur n et i valent respectivement 240 et 87.

n vaut systématiquement la valeur qui est saisie dans la fonction b(1 to xxx) -1.

capt

Ce que je ne comprends pas c'est que si mon tableau source fait 101 lignes ça fonctionne, s'il fait 150 lignes aussi, mais s'il dépasse 223 ça plante.

Bonjour à tous,

Pour clôturer le sujet :

- il faut faire attention au nombre de colonnes présentes dans le tableau source (ici 5 colonnes)

- Dans le script de Klin89, a correspond au tableau source et b au tableau restitué (tableau final après toutes les séparations)

- Ce n'est pas parce que vous avez 10 lignes que b contiendra 10 lignes : b contiendra autant de lignes qu'il y a de valeurs à séparer

- Dans mon cas, le script plantait car b était supérieur à l'argument donné au début du script : ReDim b(1 To xxx, .....), car j'avais plus de 100 lignes à stocker après séparation.

Merci.

Terry.

Rechercher des sujets similaires à "eclater donnees concatenees ligne"