Moteur de recherche VBA | Extraire des données sans prendre toute la ligne
Hello tout le monde,
Je reviens vers vous en bon débutant VBA que je suis. J'essaie de créer un moteur de recherche sur base de mots clés via excel et j'ai (notamment grâce à ce forum) réussi à mettre en place les premières étapes de mon petit projet. Toutefois je cale à un moment bien précis...
J'ai suivi un tuto sur youtube afin de mettre en place une forme d'extraction d'une base de données (faite sur excel également) mais la recherche ne donne pas exactement ce que je veux. Je souhaite uniquement prendre les informations d'une sheet et les retranscrire sur une autre sheet en commençant sur une cellule précise "B34" sheet "SKILLS". Le hic c'est que le code proposé crée automatiquement une sheet avec toutes les données au lieux de prendre les données et les mettre dans la sheet "SKILLS" à l'endroit que je veux. Aussi, le code prend en compte toute la ligne, alors que je ne souhaite prendre qu'une partie des informations (Je souhaite prendre les informations à partir de la colonne "AD20" de la sheet "DATABASE". Après avoir bidouiller le code, je n'ai pas vraiment réussi à obtenir ce que je voulais, je sais que la modification se fait sur la ligne :
Sheets.Add
Feuil6.Range("B20").EntireRow.Copy ActiveCell
Range("B21").SelectEt j'ai tenté ça mais ça bug, l'appel n'est certainement pas le bon
Sheets ("SKILLS")
Feuil6.Range("B20").EntireRow.Copy ActiveCell
Range("B21").SelectAprès relecture, mon formulaire n'extrait que la première ligne à chaque fois (en créant une nouvelle feuille), le but c'est que ce dernier (le formulaire ne propose que les joueurs afficher dans la recherche dans un premier temps et qu'après la sélection, le formulaire extrait le joueur choisi et non le premier x).
Voici le code vanilla
Sub btnExtraction_Click()
'Déclaration des variables
Dim MyName As Range
Dim ListName As Range
Dim NbRow As Long
Dim ActiveRow As Long
'Affectation des variables
Set ListName = Feuil2.Range("B21", Feuil2.Range("B20").End(xlDown))
NbRow = ListName.Rows.Count
ActiveRow = 0
'On déplace l'extraction dans la feuille Skills
Sheets.Add
Feuil6.Range("B20").EntireRow.Copy ActiveCell
Range("B21").Select
'On boucle chaque nom se trouvant dans la liste
For Each MyName In ListName
'On décale d'une ligne à chaque fois
ActiveRow = ActiveRow + 1
'On recherche le nom qui a été sélectionné dans la liste déroulante
If MyName.Offset(0, 2).Value = Me.cboName.Value Then
'Si le nom est trouvé, on va récupérer les compétences du consultants
MyName.EntireRow.Copy ActiveCell
ActiveCell.Offset(1, 0).Select
End If
Next MyName
End SubNB : Je donne un fichier avec des données un peu "bullshit" pour que vous ayez un meilleur visuel... (Dans ce fichier il y a le code vanilla pour que vous voyez ce que ça fait)
Un grand merci
Bonsoir,
je ne sais pas si j'ai tout compris mais voici un fichier :
Le code :
Sub btnExtraction_Click()
'Déclaration des variables
Dim MyName As Range
Dim ListName As Range
'Affectation des variables
Set ListName = Feuil6.Range("B20:B" & Feuil6.Range("B" & Rows.Count).End(xlUp).Row)
'On déplace l'extraction dans la feuille Skills
With Sheets("SKILLS ")
'On boucle chaque nom se trouvant dans la liste
For Each MyName In ListName
'On recherche le nom qui a été sélectionné dans la liste déroulante
If MyName.Value = Me.cboName.Value Then
'Si le nom est trouvé, on va récupérer les compétences du consultants
MyName.Offset(, 28).Resize(1, 27).Copy Destination:=.Cells(.Cells(Rows.Count, 2).End(xlUp).Row + 1, 2)
.Cells(.Cells(Rows.Count, 2).End(xlUp).Row, 1) = Me.cboName.Value
End If
Next MyName
End With
End SubAu fait pour info votre feuille SKILLS a un espace en fin de nom ce qui peut provoquer des erreurs si vous l'oubliez sous VBA, personnellement je l'ai ajouté au code, si vous corrigez le nom de la feuille il faudra corriger le nom également sous VBA.
@ bientôt
LouReeD
Hello LouReeD,
Déjà, un grand merci ! Tu (je me permet de te tutoyer sauf si ça dérange ^^ ?) as déjà bien cerné ce que je cherchais à faire et ça marche plutôt bien. J'ai enlevé les "espaces" présents sur le naming des sheets (c'est vrai que ça causait certains bug). J'ai également trouvé comment permettre au formulaire d'extraction de n'afficher que les joueurs qui ressortent de l'output (exemple : si l'on cherche un milieu et que la recherche nous propose 3 joueurs, le formulaire va proposer uniquement ces 3 joueurs là et non tous les noms présents dans la BDD). J'aurais juste une dernière requête :
Quand j'exécute l'extraction, contrairement à la dernière fois, appuyer sur le bouton effectue la recherche mais on reste sur la même feuille... Est-ce possible de faire en sorte que l'extraction (appuyer sur le bouton) nous projette immédiatement sur la feuille "SKILLS" ? Aussi, tu as fait en sorte de fixer l'output ? Je veux dire, ce n'est pas possible de faire en sorte que la recherche nous donne un output à partir de la ligne 34 de la feuille "SKILLS". L'objectif étant d'afficher les résultats dans le tableau.
Par la suite, je m'occuperais personnellement de créer un bouton afin de supprimer les résultats obtenu dans la feuille "SKILLS" si l'on veut faire une autre extraction (on ne peut extraire qu'un joueur à la fois). J'essaierais également de mettre en place un pop up dans le cas ou les mots clés entrés dans la barre de recherche ne donnent aucun résultats, si jamais je galère, je redemanderais ici.
Hello encore,
Vraiment désolé pour le double post (mais je ne trouve pas de fonction "edit"), je voulais juste signaler que j'ai réglé mes problèmes énoncés dans mon second post (à 80% lol). Juste, je te demanderais si tu peux m'expliquer le fonctionnement de cette portion de code LouReeD, j'aimerais bien la cerner (surtout pour savoir comment elle influence le positionnement sur ma sheet des extractions de ma recherche... Aussitôt que j'ai ma réponse, je mettre ce post en résolu :) (libre à quelqu'un d'autres d'apporter une explication s'il comprend bien cette portion)
If MyName.Value = Me.cbName.Value Then
'Si le nom est trouvé, on va récupérer les compétences du consultants
MyName.Offset(, 28).Resize(1, 27).Copy Destination:=.Cells(.Cells(Rows.Count, 2).End(xlUp).Row + 1, 2)
.Cells(.Cells(Rows.Count, 2).End(xlUp).Row, 1) = Me.cbName.Value
End IfBonsoir,
il y a surement plus simple, mais comme je suis parti de votre code...
MyName représente un objet Range (cellule) de la variable ListName.
ListName est un objet Range (cellule) qui correspond à une plage qui est récupérée par SET avec cette ligne de code :
Set ListName = Feuil6.Range("B20:B" & Feuil6.Range("B" & Rows.Count).End(xlUp).Row), donc ListName correspond en "Excel" à la plage de cellule B20:B "dernière ligne utilisée de la colonne B"
For Each permet de "scanner" une collection, ici c'est la collection des cellules de la plage ListName, à chaque tour du scan, la nouvelle cellule est attribuée à MyName. Si la valeur de la cellule MyName est égale au nom sélectionné dans le combobox alors on veut récupérer les données de ce nom qui se trouve sur la feuille 6 (feuille où se trouve la cellule Myname) mais ces données sont 28 colonnes plus loin que la cellule MyName, du coup on "décalle" avec OffSet(ligne,colonne) comme on reste sur la même ligne on n'indique rien puis virgule puis le nombre de colonne de décallage = MyName.OffSet(,28), "virtuellement on se retrouve en colonne AD puisque MyName se trouve en colonne B : 2 + 28 = 30 => Z=26, AA=27 AB=28 AC=29 et AD=30, mais on a une taille de une cellule, hors les données sont sur 27 colonnes ! on va donc redimentionner cette cellule unique en plage de cellule avec Resize(nbligne,nbcolonne) ce qui donne .Resize(1,27) et tout ceci on le copie à destination de la cellule cible qui se trouve sur la feuille SKILLS à partir de la colonne B et à la première ligne vide de la colonne B :
.Cells(Rows.Count, 2).End(xlUp).Row ici on cherche la dernière ligne "non vide" de la colonne B en partant d'en bas et en remontant sur la colonne B : rows.count donne le numéro de ligne le plus bas de la feuille,2 donne la colonne B. en remontant xlup et on récupère le numéro de cette dernière cellule non vide de la colonne .row, donc pour avoir la première cellule vide pour inscrire les données on ajoute +1, au finale on a :
.Cells(Ligne "première cellule vide après les données pleines de la colonne B", Colonne B) => .Cells(.Cells(Rows.Count, 2).End(xlUp).Row + 1, 2)
Maintenant on veut recopier le nom du combobox en colonne 1 sur la même ligne on cible la colonne 1 et on recherche le numéro de la ligne de la dernière donnée de la colonne B mais cette fois ci on n'ajoute pas le plus 1.
Pas facile hein ? Mais pas facile de se faire comprendre non plus !
@ bientôt
LouReeD
Hello,
Pas facile certes, mais c'est toujours enrichissant... En tout cas, un grand merci !
Bonsoir,
pas de soucis si ça peut servir ! Merci encore pour vos remerciements !
@ bientôt
LouReeD