Forum Clubic

Prog VB copier coller des lignes

Après qq efforts de novice, j’ai établi le code ci-dessous.
Il me permet :
de rechercher un mot clé dans une feuille “Donnee” (qui me sert de base de données)
de sélectionner la ligne qui le contient
de copier cette ligne dans une autre feuille “recherche”

Pbs dans ce programme:
il ne fonctionne que si une ligne est déjà sélectionnée dans la feuille “Recherche”
il écrase la copie quand il trouve plusieurs fois le mot clé (donc plusieurs lignes à copier)

Je souhaite donc que ce programme sélectionne la ligne (6 par exemple) dans “recherche” avant de coller, et qu’il colle sur les lignes suivantes s’il trouve d’autres mots.
j’ai essayé bcp de choses sans y arriver. Merci d’avance pour l’aide.

[Code]
Sub Macro1()

Dim Plage As String
Dim Cel As Range
Dim Mot As String

Mot = InputBox(“Mot à rechercher ?”)

If Mot = “” Then
Exit Sub
Else
Plage = UsedRange.Address

For Each Cel In Range(Plage)

If UCase(Cel) = UCase(Mot) Then

Cel.EntireRow.Select
Selection.Copy
Sheets(“Recherche”).Select
ActiveSheet.Paste
Sheets(“Donnee”).Select

End If

Next Cel

Application.CutCopyMode = False
'Sheets(“Recherche”).Select
End If

End Sub

Tu n’es pas loin de la solution, mais il y a quand même encore des modifs à faire

1- normal que la copie écrase, puisqu’à aucun endroit tu ne gères la position de la cellule active dans ta feuille cible
En plus, rien ne garantit qu’il commence au bon endroit
Ce qu’il faut, c’est te positionner en début de programme au début de la zone souhaitée (A1 ?)
puis lui faire rechercher la première cellule vide de la colonne correspondante
et ensuite, après chaque copie, faire se déplacer la position d’une cellule vers le bas
(il y a plusieurs méthodes pour effectuer cet enchainement d’opérations, à toi de choisir celle qui te convient le mieux)

2- curieux que tu dises que ca marche, je pensais que
Plage = UsedRange.Address
t’aurait retourné un message d’erreur, dans la mesure où tu ne fais référence à aucune feuille
j’aurais mis
Plage = ActiveSheet.UsedRange.Address

3- pas bloquant, mais quel est l’intérêt d’utiliser une variable Plage de type string ?
Cel est de type range, il attend donc un périmètre de type Range
Or UsedRange est déjà de type Range, alors pourquoi une double conversion ?

4- toujours pas bloquant : tu n’as pas besoin d’activer ta feuille cible pour copier dedans
Regarde dans l’aide la syntaxe de la fonction copy() appliquée à l’objet Range

Essaie de solutionner point par point, et n’hésite pas à préciser ce qui ne va pas si tu bloques

Merci pour les conseils, plus le temps de m’y coller aujourd’hui. Je vois ça la semaine prochaine. A+

Rq1: pas touché
Rq 2: ok, ça fonctionne bien
Rq 3: si je comprend bien, ici, pas besoin de déclarer Plage de type string. Si je supprime"Dim Plage as String", le programme marche bien. OK
Rq 4 : J’ai remplacé 2 lignes en 1: Sheets(“Recherche”).Paste. C’est la bonne syntaxe?

Bilan: le prog fonctionne toujours, avec une syntaxe simplifiée, c’est déjà ça! Merci

Je vois pour la sélection de la cellule active, la recherche de la cellule vide, copie et délacement…

Code:
Sub Macro1()

Dim Cel As Range 'Définition de la cellule de recherche
Dim Mot As String 'définition du mot à rechercher

Mot = InputBox(“Mot à rechercher ?”) 'Entrée du mot à rechercher
If Mot = “” Then
Exit Sub
Else
Plage = ActiveSheet.UsedRange.Address 'Définition de la plage de recherche
For Each Cel In Range(Plage)
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Select
Selection.Copy
Sheets(“Recherche”).Paste
Sheets(“Donnee”).Select
End If
Next Cel
Application.CutCopyMode = False
Sheets(“Recherche”).Select
End If
End Sub


en simplifiant la syntaxe Rq4, je me rend compte que je n'ai plus besoin de sélectionner la feuille donnee après le collage, normal... j'ai donc encore un peu simplifié le code ci-dessus en enlevant - Sheets("Donnee").Select - juste avant End If

pour copier au bon endroit la première ligne, je commence par sélectionner la bonne ligne (ici L3) dans “recherche” puis je reviens sur ma feuille “Donnee” faire ma recherche de mots clés.
Pb: ca ne fonctionne que si j’exécute mon prog à partir de recherche et ca me renvoie erreur 400 si je l’exécute à partir de Donnee
D’ou vient l’erreur?

code:
Sub Macro1()

Dim Cel As Range 'Définition de la cellule de recherche
Dim Mot As String 'définition du mot à rechercher

Sheets(“Recherche”).Range(“3:3”).Select
Sheets(“Donnee”).Select

Mot = InputBox(“Mot à rechercher ?”) 'Entrée du mot à rechercher
If Mot = “” Then
Exit Sub
Else
Plage = ActiveSheet.UsedRange.Address 'Définition de la plage de recherche
For Each Cel In Range(Plage)
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Select
Selection.Copy
Sheets(“Recherche”).Paste
End If
Next Cel
Application.CutCopyMode = False
Sheets(“Recherche”).Select
End If
End Sub

Ca ne devrait pas fonctionner ; si tu supprimes le DIM, tu t’engages quelque part à ne plus utiliser la variable en question …
Alors pourquoi ça fonctionne ?
Parce que la déclaration de variables est optionnelle en VBA.
Mais je te conseille vivement de te l’imposer pour éviter que le compilateur ne fasse ensuite des interprétations à tort difficilement décelables lors de l’exécution.
Pour cela, il faut que tu rajoutes en première ligne de ton module option explicit

Pour en revenir à ta variable Plage, tu peux l’ignorer en faisant directement référence au Range (et non pas à son adresse)
For Each Cel In ActiveSheet.UsedRange

C’est bon, mais on peut encore simplifier (on verra plus bas)

Tu n’as pas besoin de sélectionner la ligne complète. La première cellule suffit pour un paste (l’étendue sera automatiquement celle du copy)
Est-tu sûr de bien vouloir copier tous les résultats de ta recherche sur la ligne 3 ? ils vont s’écraser les uns les autres …
Plutôt qu’utiliser Select (qui t’oblige à activer ta feuille), place plutôt un pointeur de type range sur ta cellule cible :
set R = Sheets(“Recherche”).Range(“A3”)
Cette syntaxe fonctionne y compris depuis la feuille “Données” et la copie est notablement simplifiée :
For Each Cel In ActiveSheet.UsedRange
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Copy R
End If
Next

Le problème vient de ce que tu essaies de faire un select dans une feuille non active.
Il faudrait mettre
Sheets(“Recherche”).Activate
activesheet.Range(“3:3”).Select
Sheets(“Donnee”).Select

Normalement, tu n’as plus à te servir de ce morceau de programme.

Ok pour Plage mais comprend pas “”…option explicit"

Syntaxe avec R me va aussi mais le prog ne fonctionne pas encore en l’état (voir ci-desous) message “Objet requis”

Non, je ne vaux pas écraser ma ligne, mais déjà, si j’arrive à faire ça, je devrais savoir faire le reste!

CODE
Sub Macro1()

Dim Cel As Range
Dim Mot As String

Set R = Sheets(“Recherche”).Range(“A3”)
Sheets(“Donnee”).Activate
Mot = InputBox(“Mot à rechercher ?”)
If Mot = “” Then
Exit Sub
Else
For Each Cel In ActiveSheet.UsedRange
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Select.Copy R
End If
Next Cel
Application.CutCopyMode = False
Sheets(“Recherche”).Select
End If
End Sub

il faut juste rajouter cette ligne en tête de don module
CODE
Option Explicit
sub Macro1()
etc …

Une fois que c’est fait, supprime (temporairement) Dim Cel As Range, tu vas comprendre tout de suite

Il te dit Objet Requis sur quelle ligne ?
Je n’ai pas testé, mais je pense que c’est
Cel.EntireRow.Select.Copy R
qui ne lui plait pas ; la bonne syntaxe est
Cel.EntireRow.Copy R

ok, ca marche maintenant sauf que j’ai pas réellement compris le rôle de “Option Explicit”;
j’ai aussi déclaré R as range (nécésaire comme de déclarer Cel as range) je crois que c’est ça que tu sous-entendais, non?

Le code fonctionne en écrasant, je m’attaque au déplacement de la cellule de copie dans recherche…
CODE:
Option Explicit
Sub Macro1()

Dim Cel As Range
Dim Mot As String
Dim R As Range

Set R = Sheets(“Recherche”).Range(“A3”)
Sheets(“Donnee”).Activate
Mot = InputBox(“Mot à rechercher ?”)
If Mot = “” Then
Exit Sub
Else
For Each Cel In ActiveSheet.UsedRange
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Copy R
End If
Next Cel
Application.CutCopyMode = False
Sheets(“Recherche”).Select
End If
End Sub

dans le prog ci-dessus, si je déclare i, et je dis que i = 3, et je remplace A3 par Ai dans Set R… Si je rajoute i = i + 1 dans la boucle If après la copie, ça ne marche pas. Ou est l’erreur de conception? Je cherche toujours…

Comment as-tu défini i ?
si tu veux l’incrémenter, il faut que ce soit un numérique (Integer)
et donc tu ne peux pas l’utiliser tel quel dans l’expression Ai
il faudrait que tu écrives Range(“A”&i)

Mais ici ce n’est pas la meilleure méthode méthode
C’est le R lui-même qu’il faut que tu déplaces, c’est plus simple
Cel.EntireRow.Copy R
set R=R.offset(1)
End If

Ok tout semble fonctionner comme je le voulais; merci pour les infos et les explications. A+
CODE:
Option Explicit
Sub Macro1()

Dim Cel As Range
Dim Mot As String
Dim R As Range

Set R = Sheets(“Recherche”).Range(“A3”)
Sheets(“Donnee”).Activate
Mot = InputBox(“Mot à rechercher ?”)
If Mot = “” Then
Exit Sub
Else
For Each Cel In ActiveSheet.UsedRange
If UCase(Cel) = UCase(Mot) Then
Cel.EntireRow.Copy R
Set R = R.Offset(1)
End If
Next Cel
Application.CutCopyMode = False
Sheets(“Recherche”).Select
End If

End Sub