Réinitialiser une variable objet pour boucle
Bonjour à tous,
Premier post pour moi, peut-être pas le dernier
Tout d'abord, je suis novice en VBA. Normalement, j'arrive toujours à trouver une solution à mes problèmes en bidouillant des codes récupérés dans le forum et en l'adaptant, mais j'ai une connaissance très limitée pour créer moi-même des codes. Donc je sais que le code n'est pas "propre", je pense que certains vont bondir de leur chaises en voyant le code, mais l'important pour moi est que cela fonctionne
Mon problème est le suivant :
J'ai une feuille (fichier_source) de base de données avec quelques dizaines de colonnes, et plusieurs centaines de lignes.
Je veux copier chaque ligne répondant à une condition (valeur de la colonne AH = VRAI) sur une autre feuille (personne a contacter)
Je veux aussi que chaque copie se fasse en dessous de l'autre, pour ne pas écraser la première ligne copiée
Et enfin je veux ajouter une condition pour qu'il y ait une vérification que la ligne n'est pas déjà copiée avant de la copier sur (personne à contacter)
J'ai réussi à 95 % ce que je voulais, les lignes se copient bien comme je veux, mais il faut relancer la macro à chaque ligne.
Je pense avoir identifié le problème : à la première itération la variable Trouve est vide, et donc la copie est effectué, mais ensuite elle n'est plus vide et donc il n'y a plus de copie. Mais je ne trouve pas le moyen de la "vider/réinitialiser" avec is nothing/ is empty ou autre.
Il y surement un moyen de faire ce que je veux
Si vous avez vraiment besoin du fichier joint, je peux le charger mais il faut que je fasse un gros travail de tri car il y a beaucoup de nom/adresse/numéro de tel donc dites moi si c'est indispensable pour vous ou pas
Bonne journée à tous et merci à ceux qui prendront le temps d'étudier mon petit problème
Sub Filtre()
Dim Lig As Long
Dim Col As String
Dim Colini As String
Dim NbrLig As Long
Dim NumLig As Long
Dim Derlig As Long
Dim Trouve As Range, PlageDeRecherche As Range
Dim Valeur_Cherchee As String, AdresseTrouvee As String
With Sheets("fichier_source")
Sheets("fichier_source").Activate
Col = "AH"
Colini = "A"
NumLig = 2
NbrLig = ActiveSheet.Cells(65536, Colini).End(xlUp).Row
For Lig = 2 To NbrLig
If .Cells(Lig, Col).Value = "VRAI" Then
Valeur_Cherchee = Cells(Lig, Colini).Value
Set PlageDeRecherche = Sheets("personnes a contacter").Columns("A")
Set Trouve = PlageDeRecherche.Cells.Find(what:=Valeur_Cherchee, LookAt:=xlWhole)
If Trouve Is Nothing Then
Sheets("personnes a contacter").Activate
Derlig = Cells(65536, 1).End(xlUp).Row
Sheets("fichier_source").Activate
.Cells(Lig, Col).EntireRow.Copy
Sheets("personnes a contacter").Activate
Cells(NumLig, 1).Select
ActiveSheet.Paste
Else
End If
NumLig = NumLig + 1
End If
Next
End With
Sheets("personnes a contacter").Activate
End SubBonjour Marcou,
Je confirme, ton code est à revoir, mais je vais essayer de t'expliquer point par point les problèmes :
--> Instruction "With" : utilisée pour simplifier l'écriture d'une série d'instructions qui concernent un même objet (par exemple une feuille). Tout objet s'y rapportant commence alors par "."
--> Instruction "Select" et "Activate" : inutiles dans 95% des cas puisqu'il suffit simplement de préciser sur quel objet (feuille, cellule...) on travail, sans avoir besoin de le voir ni de le sélectionner.
--> Remarque précédente notamment vraie dans le cas d'une copie, rien à sélectionner : on précise ce qu'on copie, et en fin d’instruction, on précise où le coller. Par ailleurs, si seules les valeurs t'intéressent, pas besoin d'une copie, mais juste affecter à un plage les valeurs d'une autres plages avec une instruction type (+ rapide) :
Sheets(2).Rows(lig).Value = Sheets(1).Rows(lig).Value--> L'objet "Trouve" n'a pas besoin d'être réinitialisé, une nouvelle recherche écrasera le résultat précédent, même si la recherche est infructueuse (le résultat est alors rien, soit "nothing")
--> Pour ne pas écraser les résultats déjà présent dans ta feuille "personnes à contacter", il ne faut pas se baser sur NumLig, qui commence à la ligne 2, mais sur DerLig, qui tient compte de la dernière ligne complète.
--> Pas besoin d'affecter des références de colonne fixes ("AH" et "A") dans des variables, puisqu'elles ne changent pas ! J'ai donc remplacé "Colini" par 1 et "Col" par 34.
Voilà ta macro révisée, à tester sur ton fichier :
Sub Filtre()
Dim Lig As Long, NbrLig As Long, Derlig As Long
Dim Trouve As Range, PlageDeRecherche As Range
Dim Valeur_Cherchee As String, AdresseTrouvee As String
With Sheets("fichier_source") 'A partir d'ici, tout ce qui commence par "." concerne cette feuille
NbrLig = .Cells(Rows.Count, 1).End(xlUp).Row 'Dernière ligne
Derlig = Sheets("personnes a contacter").Cells(Rows.Count, 1).End(xlUp).Row 'Dernière ligne
For Lig = 2 To NbrLig 'Parcourir les lignes
If .Cells(Lig, 34).Value = "VRAI" Then 'Si valeur est à reporter
Valeur_Cherchee = .Cells(Lig, 1).Value
Set PlageDeRecherche = Sheets("personnes a contacter").Range("A2:A" & Derlig)
Set Trouve = PlageDeRecherche.Cells.Find(what:=Valeur_Cherchee, LookAt:=xlWhole)
If Trouve Is Nothing Then 'Si elle n'est pas déjà présente, on l'ajoute
Derlig = Derlig + 1
.Rows(Lig).Copy Sheets("personnes a contacter").Rows(Derlig)
End If
End If
Next
End With
Sheets("personnes a contacter").Activate 'Aller sur la feuille "personnes à contacter"
End SubWaou, merci beaucoup pour cette réponse rapide et complète, je comprends mieux les différentes formules que j'utilisais souvent à mauvais escient, et comme prévu ça fonctionne niquel.
Encore Merci Pedro22