XL 2010 Besoin aide sur Array(Array(a,b),Array(c,d)) de TextToColumns

TooFatBoy

XLDnaute Barbatruc
Bonjour,

J'ai récupéré un fichier Excel dans lequel il y a une macro dont j'ai bien compris le but (séparer nom et prénom d'une colonne en deux colonnes), mais dont je ne pige pas exactement le fonctionnement.

J'ai une plage F13:F38 dont chaque cellule contient, soit rien, soit du texte au format "NOM Prénom".
La macro me permet d'obtenir les noms en colonne F et les prénoms en colonne G.
Pour cela elle utilise l'instruction TextToColumns :
VB:
.Range("F13:F38").TextToColumns Destination:=.Range("F13:F38"), DataType:=xlDelimited, _
    TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
    Semicolon:=False, Comma:=False, Space:=True, Other:=False, _
    FieldInfo:=Array(Array(1, 2), Array(2, 2)), TrailingMinusNumbers:=True

Même si ça fonctionne parfaitement, je ne suis pas certain que les valeurs dans les Array du FieldInfo soient correctes.

Si j'ai bien compris, Array(x,2) veut dire que le champ en question, une fois extrait de la chaîne originelle, sera traité comme étant du simple texte.
Mais que représente la première valeur de l'Array (ici la valeur "x", dans "Array(x,2)") ???

Je crois comprendre que, si je travaille sur des champs de longueurs fixes (par exemple 5 caractères pour le champ n°1, 3 caractères pour le champ n°2, etc.), alors le "x" est le numéro du caractère de la chaîne originelle à partir duquel ledit champ doit être extrait (et est aussi la limite de fin du champ précédent).
Avec MARTIN Gilbert et SCHMITT Helmut,
Array(Array(0,2),Array(6,2)) doit me donner respectivement
"MARTI" "N Gilbert" et "SCHMI" "TT Helmut".

Or ici je ne travaille pas sur des champs de longueurs fixes, mais sur des champs séparés par une espace (donc de longueurs potentiellement variables).
Le "x" représente-t-il toujours le n° du caractère de la chaîne originelle à partir duquel une espace est cherchée ? (visiblement non...)
Quelle valeurs faudrait-il mettre dans les Array ?

Et question subsidiaire : le FieldInfo est-il ici nécessaire, vu qu'on utilise l'espace comme séparateur et qu'il n'y a qu'une seule et unique espace dans chaque chaîne ?
 
Solution
Re

Voici une petite macro illustrative
(avec en bonus une écriture simplifiée -> macro2b)
VB:
Sub Macro2()
With Range("A1")
    .Value = "Staple 1600 Tableur 01/01/2020"
    .TextToColumns Destination:=Range("A2"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
        Semicolon:=False, Comma:=False, Space:=True, Other:=False, FieldInfo _
        :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1))
    .TextToColumns Destination:=Range("A3"), DataType:=xlDelimited, _
        TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
        Semicolon:=False, Comma:=False, Space:=True, Other:=False, FieldInfo _
        :=Array(Array(1, 1), Array(2, 2)...

sylvanu

XLDnaute Barbatruc
Supporter XLD
Bonjour Marcel,
Rien à voir avec votre post. Mais pourquoi passer par des arrays pour faire une séparation Nom Prénom ? Y a t-il une raison particulière ?
Sinon :
VB:
Sub Separe()
For i = 13 To 38
    Chaine = Range("F" & i)
    Range("F" & i) = Mid(Chaine, 1, InStr(1, Chaine, " "))
    Range("G" & i) = Mid(Chaine, InStr(1, Chaine, " ") + 1)
Next i
End Sub
 

TooFatBoy

XLDnaute Barbatruc
Déjà, merci pour la réponse. ;-)

C'est un classeur que j'ai récupéré et qui contient déjà une macro qui sépare le nom du prénom.
Du coup j'essaye de comprendre le fonctionnement exact de TextToColumns en général et de son FieldInfo en particluier.

Perso, j'aurais fait exactement comme dans la macro que tu proposes, à ceci près que j'aurais utilisé un Left et un Right à la place des deux Mid. ;)

Ceci dit, même si vu le peu de lignes à traiter la durée est négligeable, je pense qu'en général les boucles sont beaucoup plus lentes que les instructions spécifiques à Excel.


[edit]
Je viens de faire un test : j'ai bouclé 10 fois sur ta macro et 10 fois sur celle trouvée dans mon classeur.
Résultat :
2,383 secondes pour ta macro,​
0,047 seconde pour celle de mon classeur.​
L'utilisation du TextToColumns me semble donc préférable dans ce cas.
[/edit]
 
Dernière édition:

laurent950

XLDnaute Barbatruc
Bonsoir
VB:
Sub test()
Dim Plg As Variant
Plg = Range(Cells(13, 6), Cells(38, 6))
ReDim Preserve Plg(LBound(Plg, 1) To UBound(Plg, 1), LBound(Plg, 2) To UBound(Plg, 2) + 1)

For i = LBound(Plg, 1) To UBound(Plg, 1)
    Chaine = Split(Plg(i, 1), " ")
    Plg(i, 1) = Chaine(0)
    Plg(i, 2) = Chaine(1)
Next i
    Cells(13, 6).Resize(UBound(Plg, 1), UBound(Plg, 2)) = Plg
End Sub
 

TooFatBoy

XLDnaute Barbatruc
Merci pour ta réponse qui, même si elle semble vraiment trop compliquée pour moi, fonctionne sûrement très bien.

Mais je répète que le but de ma question n'est pas de séparer le nom du prénom, mais bien de comprendre à quoi correspondent les valeurs dans les Array de la ligne d'instruction que j'ai donnée au départ. ;)
 

laurent950

XLDnaute Barbatruc
Re,
En supprimant chaine,
VB:
Sub test()
Dim Plg As Variant
Plg = Range(Cells(13, 6), Cells(38, 6))
ReDim Preserve Plg(LBound(Plg, 1) To UBound(Plg, 1), LBound(Plg, 2) To UBound(Plg, 2) + 1)

For i = LBound(Plg, 1) To UBound(Plg, 1)
    Plg(i, 2) = Split(Plg(i, 1), " ")(1)
    Plg(i, 1) = Split(Plg(i, 1), " ")(0)
Next i
    Cells(13, 6).Resize(UBound(Plg, 1), UBound(Plg, 2)) = Plg
End Sub
le temps de traitement sera encore augmenté
 

TooFatBoy

XLDnaute Barbatruc

TooFatBoy

XLDnaute Barbatruc
Bonsoir le fil

Marcel32
Pour éclairer ta lanterne, une source de lumière en direct de la maison mère

EDITION: Houps, Bing!, je vois que laurent950 achète ses ampoules dans le même magasin que le mien
Désolé pour la collision ;)
Merci mais la lumière n'éclaire hélas rien du tout, ou du moins pas dans la bonne direction. :(
 

Staple1600

XLDnaute Barbatruc
Re

Pourtant cela explique beaucoup, non ?
Tableau contenant des informations redistribuées pour des colonnes individuelles de données.
L’interprétation dépend de la valeur de DataType

Lorsque les données sont délimitées, cet argument est un tableau de tableaux à deux éléments, spécifiant les options de conversion pour une colonne particulière. Le premier élément est le numéro de colonne (basé sur 1) et le deuxième élément est une des constantes XlColumnDataType spécifiant comment la colonne est analysée.
 

Staple1600

XLDnaute Barbatruc
Re

Alors je rajoute ceci ;)
Indique la manière dont une colonne doit être analysée.
Nom Valeur Description
xlDMYFormat 4 Format de date JMA.
xlDYMFormat 7j/7 Format de date JAM.
xlEMDFormat 10 Format de date AMJ.
xlGeneralFormat 0,1 Général.
xlMDYFormat 3 Format de date MJA.
xlMYDFormat 6.x Format de date MAJ.
xlSkipColumn 4,9 La colonne n'est pas analysée.
xlTextFormat n°2 Texte.
xlYDMFormat 8bits Format de date AJM.
xlYMDFormat disque Format de date AMD
Bref selon les options que tu coches dans l'Assistant de conversion
Le deuxième élément change de valeur (voir ci-dessus) dans FieldInfo
Fais l'essai en laissant tourner l'enregisteur de macros
(en faisant plusieurs conversions consécutives) mais en cochant à chaque fois une option différente.
Puis compare les valeurs obtenues dans ton FieldInfo.
 

Discussions similaires

Statistiques des forums

Discussions
315 084
Messages
2 116 061
Membres
112 645
dernier inscrit
Acid Burn