XL 2016 Trouver le premier nom d'une colonne en fonction du nom de la colonne

bennp

XLDnaute Occasionnel
Bonjour,

je souhaite retrouver les données précises d'un fichier xml, et les informations me sont données en décalé !

par exemple :

je cherche le premier nom qui est affiché dans ma colonne "Prénom"

L'idée est que je puisse trouver chaque premier résultat en tapant juste le nom de la colonne.


J'ai réussi à retrouver le 1er nom affiché : INDEX(Feuil2!1:1048576;EQUIV(VRAI;Feuil2!1:1048576<>"";0))

mais pas si je tape juste le nom de la colonne --> "Prénom"

Merci d'avance

Ben
 

Pièces jointes

  • Classeur1.xlsx
    9.4 KB · Affichages: 42

vgendron

XLDnaute Barbatruc
C'est moi ou le besoin n'a plus rien à voir avec la demande initiale qui était uniquement de récuperer le premier élement non vide d'une colonne définie par saisie?

il faudrait que tu définisses le vrai besoin final et global, plutot que d'ajouter des élements au fur et à mesure
ca permettrait de te proposer une solution complète qui te donne ce que tu veux au final

que ce soit formule ou vba, on a besoin de toutes les données d'entrée et du résultat final attendu

ici: données d'entrée = tableau feuille1 qui contient des lignes vides ou incomplètes
donnée de sortie = Lister TOUS les noms présents de la colonne A et mettre les élements de TOUTES les colonnes (FRUIT, épaisseur et Nombre) ,
les lister les uns en dessous des autres ? ou juste ceux que tu souhaites sélectionner quelque part?
 

bennp

XLDnaute Occasionnel
Bon effectivement ça n'a plus rien à voir, je pensais juste pouvoir m'en sortir tout seul !

Voici ma démarche : récupérer la liste complète de la colonne nom1, (ils seront placés en A1, A11 et A20 dans l'ordre d'apparition du tableau feuille1)

Maintenant pour chaque liste de nom, Dupont par exemple, y associer la liste des fruits sur chaque ligne en dessous avec leur épaisseur et nombre.

Le problème c'est que je ne saurais jamais combien de nom1 j'aurai, ni combien de fruits associés j'aurai ! Par contre, pour chaque fruit il y aura toujours l'épaisseur et le nombre (il me semble que le résultat sera toujours inscrit X lignes en dessous --> épaisseur 0.25 est 4 lignes en dessous de orange de DUPONT
De même, nombre 775 est 7 lignes en dessous de orange de DUPONT

Ce qui sera toujours identique c'est le nom des différentes colonnes (balises), je pense même que l'écart entre chaque fruit restera toujours de 14 lignes

bien sûr j'aurai d'autres informations à récolter de ce fichier et à placer à la suite de ces tableaux sous différentes formes. est ce qu'il sera possible plus tard de prévoir une macro qui fasse remonter les informations suivantes si les cases sont vides ? ou faut-il le prévoir maintenant ? Si j'ai 2 tableaux à afficher au lieu de 6, ça va créer un gros espace vide...

Merci vgendron !!
 

vgendron

XLDnaute Barbatruc
ok, donc voici un autre code que j'ai commenté ligne à ligne


VB:
Sub Recuperer()
Dim tablo() As Variant
Set mondico = CreateObject("Scripting.Dictionary")
tablo = Sheets("Feuil1").UsedRange.Value 'on récupère l'ensemble des data de la feuille1
Sheets("Feuil2").UsedRange.ClearContents 'on efface la feuille 2

'on récupère la liste des noms sans doublon de la colonne A que l'on met dans un dictionnaire
For i = LBound(tablo, 1) + 1 To UBound(tablo, 1) 'lbound+1 pour éviter la ligne d'entete
    If tablo(i, 1) <> "" Then mondico(tablo(i, 1)) = ""
Next i

For Each nom In mondico.keys 'pour chaque nom contenu dans le dictionnaire
    'MsgBox nom
    fin = Sheets("Feuil2").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Row 'on récupère la dernière ligne de la feuille2
    Range("A" & fin + 1) = UCase(nom) 'on place le Nom en majuscule
    Range("A" & fin + 1).Font.Bold = True 'et en gras
   
    For i = LBound(tablo, 2) + 1 To UBound(tablo, 2) 'on recopie la ligne de titre du tablo
        Sheets("Feuil2").Range("A" & fin).Offset(2, i - 2) = tablo(1, i)
    Next i
   
    For i = LBound(tablo, 1) To UBound(tablo, 1) 'pour chaque ligne du tablo
        If UCase(tablo(i, 1)) = UCase(nom) Then 'si on est sur le bon nom
            For j = LBound(tablo, 2) + 1 To UBound(tablo, 2) 'pour chaque colonne
                If tablo(i, j) <> "" Then 's'il y a quelque chose
                    Cells(Rows.Count, j - 1).End(xlUp).Offset(1, 0) = tablo(i, j) 'on le recopie à la bonnen place
                End If
            Next j
        End If
    Next i
Next nom
End Sub

1) j'ai changé le nom de la macro.. visiblement extraire était traduit automatiquement par VBA en Extract et ca ne lui plaisait pas....??....

2) Ce code est à lancer à partir de la feuille2 active
3) si tu ajoutes des colonnes dans la feuille1, elles seront prises en compte automatiquement
 

bennp

XLDnaute Occasionnel
Génial, ça fonctionne !!!
au lieu de récupérer l'ensemble du tableau, c'est possible de récupérer les colonnes ayant le nom "Nom" , "Fruit" , "épaisseur" et "Nombre" parce que j'ai pleins d'autres balises entre celles-ci, avant et après..

merci Vgendron
 

vgendron

XLDnaute Barbatruc
Hello

Modif de code pour te permettre de choisir les colonnes à récupérér..
dans la feuille de résultat, en ligne 1, sélectionner les intitulés de colonnes à récupérer
et lancer la macro
 

Pièces jointes

  • traitement donnée xml (1) (1).xlsm
    28.7 KB · Affichages: 34

bennp

XLDnaute Occasionnel
J'ai réussi à effacer juste une partie de la feuille 2 en macro (pour mon propre projet)
Par contre si j'insère une nouvelle colonne en A, le code ne fonctionne plus,
J'ai essayé de modifier le bout de code :

'on récupère la liste des noms sans doublon de la colonne A que l'on met dans un dictionnaire
For i = LBound(tablo, 1) + 1 To UBound(tablo, 1) 'lbound+1 pour éviter la ligne d'entete
If tablo(i, 1) <> "" Then mondico(tablo(i, 1)) = ""
Next i

Mais bon...de toute évidence c'est trop compliqué pour moi !!

Au lieu d'aller chercher les noms des colonnes dans les listes déroulantes (ligne 1) ne pourrait-on pas nommer le nom de chaque colonne qui nous intéresse ? et intégrer ces nom dans la macro... ça serait plus simple pour moi pour la suite.

Merci encore
 

Pièces jointes

  • traitement donnée xml (1) (1) (1).xlsm
    30.5 KB · Affichages: 27

bennp

XLDnaute Occasionnel
J'ai réussi à modifier une partie du code pour effacer que la partie qui nous intéresse (dans mon fichier j'ai des résultats à afficher au dessus et en dessous). Par contre j'ai une colonne en A et le code ne fonctionne plus. Dans mon fichier xml, il y a énormément de colonne et que quelque une me servent...
J'ai essayé de modifier cette colonne pour qu'il récupére les noms de la colonne B cette fois-ci mais pas réussi :
'on récupère la liste des noms sans doublon de la colonne A que l'on met dans un dictionnaire
For i = LBound(tablo, 1) + 1 To UBound(tablo, 1) 'lbound+1 pour éviter la ligne d'entete
If tablo(i, 1) <> "" Then mondico(tablo(i, 1)) = ""
Next i

D'ailleurs, ne pourrait-on pas aller chercher les colonnes en fonction de leurs nom, mais dans la macro ?
Par exemple, dans la macro --> récupérer la colonne ayant le nom "Nom" et ajouter dans le dictionnaire tous les noms sans doublon...

ça me permettrait de récupérer tous ces bouts de code plus facilement et de les insérer dans d'autres tableaux plus tard.

Merci encore

Ben
 

Pièces jointes

  • traitement donnée xml (1) (1) (1).xlsm
    30.5 KB · Affichages: 31

vgendron

XLDnaute Barbatruc
Hello
Il va falloir te décider à un moment à figer ta structure de fichier, sinon tu ne t'en sortira jamais
evidemment, si les colonnes changent de place, le code tel quel ne fonctionne pas puisqu'il ne cherche pas au bon endroit

voir le code ci dessous avec des explications:
VB:
Sub Recuperer()
Application.ScreenUpdating = False

Dim tablo() As Variant
Dim NomsColonnes() As Variant
Set mondico = CreateObject("Scripting.Dictionary")
Sheets("Feuil2").Range("A2:C34").ClearContents
'Sheets("Feuil2").UsedRange.Offset(1, 0).ClearContents 'on efface la feuille 2 Sauf la ligne 1

col = 2 'numéro de la colonne de laquelle on va extraire les éléments SANS doublon --> ici Col B = Col Noms
'si la colonne Noms se déplace:
'   soit tu connais sa place et tu remplaces manuellement la valeur de col
'   soit tu cherches sa position dans la feuille1

'NomColonneCherchée = "Nom"
'With Sheets("Feuil1").Rows(1) 'on cherche dans la ligne 1 de la feuile 1
'    Set c = .Find(NomColonneCherchée)
'    If Not c Is Nothing Then
'        col = c.Column
'    End If
'End With

tablo = Sheets("Feuil1").UsedRange.Value 'on récupère l'ensemble des data de la feuille1
'on récupère la liste des noms sans doublon de la colonne "col" que l'on met dans un dictionnaire
For i = LBound(tablo, 1) + 1 To UBound(tablo, 1) 'lbound+1 pour éviter la ligne d'entete
    If tablo(i, col) <> "" Then mondico(tablo(i, col)) = ""
Next i

'cas ou les Intitulés sont saisis dans la feuille --> NomsColonnes est ici un tablo de valeurs
'NbColonnes = Cells(1, Sheets("Feuil2").Columns.Count).End(xlToLeft).Column
'NomsColonnes = Range("A1").Resize(1, Cells(1, Sheets("Feuil2").Columns.Count).End(xlToLeft).Column).Value

'cas ou tu saisis les intitulés directement dans la macro.. (pas le meilleur à mon avis..) NomsColonnes est ici un ARRAY
NomsColonnes = Array("Fruit", "Nombre", "épaisseur")

For Each nom In mondico.keys 'pour chaque nom contenu dans le dictionnaire
    fin = Sheets("Feuil2").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Row 'on récupère la dernière ligne de la feuille2
    Range("A" & fin + 1) = UCase(nom) 'on place le Nom en majuscule
    Range("A" & fin + 1).Font.Bold = True 'et en gras
   
'    For i = LBound(tablo, 2) + 1 To UBound(tablo, 2) 'on recopie la ligne de titre du tablo
'        Sheets("Feuil2").Range("A" & fin).Offset(2, i - 2) = tablo(1, i)
'    Next i

'dans le cas d'une range, on la parcourt avec un for i..
'    For i = LBound(NomsColonnes, 2) To UBound(NomsColonnes, 2)  'on recopie la ligne de titre du tablo
'        Sheets("Feuil2").Range("A" & fin).Offset(2, i - 1) = NomsColonnes(1, i)
'    Next i

'dans le cas d'un Array, on parcourt avec un for each..
    i = 1
    For Each intitulé In NomsColonnes
        Sheets("Feuil2").Range("A" & fin).Offset(2, i - 1) = intitulé
        i = i + 1
    Next intitulé

    For i = LBound(tablo, 1) To UBound(tablo, 1) 'pour chaque ligne du tablo
        If UCase(tablo(i, col)) = UCase(nom) Then 'si on est sur le bon nom
            For j = LBound(tablo, 2) + 1 To UBound(tablo, 2) 'pour chaque colonne
                If tablo(i, j) <> "" Then 's'il y a quelque chose
                   
'cas du tablo de valeurs
'                    For k = LBound(NomsColonnes, 2) To UBound(NomsColonnes, 2)
'                        If tablo(1, j) = NomsColonnes(1, k) Then
'                            Cells(Rows.Count, k).End(xlUp).Offset(1, 0) = tablo(i, j) 'on le recopie à la bonnen place
'                        End If
'                    Next k
                   
'cas du array
                    For Each intitulé In NomsColonnes
                        If tablo(1, j) = intitulé Then
                            k = Application.WorksheetFunction.Match(intitulé, NomsColonnes, 0)
                            Cells(Rows.Count, k).End(xlUp).Offset(1, 0) = tablo(i, j)
                        End If
                    Next intitulé
                End If
            Next j
        End If
    Next i
Next nom
Application.ScreenUpdating = True
End Sub
 

bennp

XLDnaute Occasionnel
Bon je reviens du coup... J'ai essayé de l'adapter mais toujours pas réussi.

j'ai rajouté des colonnes entre chaque colonne qui nous intéresse et ça à l'air de fonctionner. Par contre maintenant je souhaite aller chercher mes noms de base dans une autre feuille (feuille4) --> nom de la colonne : Nomchoisi
au lieu d'aller soit dans la colonne 2 ou colonne (Nom)

Par contre, je dois maintenant récupérer la liste des noms "Nomchoisi" sans doublon, etc et y associer chaque nom aux résultats, sauf que la colonne qui contient les noms personnel n'a pas le même nom que la colonne en Feuil1

Nomchoisi Feuil4--> Nom Feuil1

J'espère avoir été clair...

Merci pour ton soutien !!

Ben
 

Pièces jointes

  • Forum-excel.xlsm
    33 KB · Affichages: 27

bennp

XLDnaute Occasionnel
peux tu aussi rajouter qqc ?

imaginons que l'on a déjà du texte au dessus dans la feuille2, par exemple les cases entre A1 et D12 sont remplies, est-il possible de supprimer que les informations qui sont à la suite et d'y intégrer notre tableau 7 lignes en dessous

Merci
 

bennp

XLDnaute Occasionnel
Ah oui une dernière chose et tout devrait être parfait :

les noms des colonnes où on récupère les informations (Fruit, Nombre, épaisseur) sont en réalité des noms de balise bizarre, est-il possible de modifier les noms dans le tableau que l'on veut créer ? par exemple :

Fruit --> Fruits
Nombre--> Chiffre
épaisseur--> Taille

Merci encore pour ton aide précieuse !!
 

Discussions similaires

Statistiques des forums

Discussions
312 194
Messages
2 086 069
Membres
103 110
dernier inscrit
Privé