Syntaxe pour copie cellules ligne active

Fermé
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 - Modifié le 30 mai 2020 à 12:02
eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024 - 1 juin 2020 à 19:06
Bonjour le forum

J'aurais besoin d'un coup de main pour corriger la syntaxe d'une macro.

Je cherche, dans un premier temps via VB, à copier certaines cellules de la ligne active d'une feuille F1 vers d'autres cellules une autre feuille F2 (sur la première ligne vide).

Voici la macro qui fonctionne :

Sub COPY() 'copie en cellule fixe :
Dim lig As Long
lig = Selection.Row
Application.ScreenUpdating = False
Sheets("F2").Range("G10").Value = Sheets("F1").Cells(lig, 25)
Sheets("F2").Range("H10").Value = Sheets("F1").Cells(lig, 19) & " - " & Sheets("F1").Cells(lig, 18).Value

With Application
.ScreenUpdating = False
.CutCopyMode = False
End With
End Sub


... là il me prend bien la ligne active, mais il copie dans une cellule précise.
Ça se gâte lorsque j'essaie de copier vers la première ligne non-vide.
Il me réclame "Référence incorrecte ou non qualifiée, visiblement parce que je n'utilise pas de With.
Mais je ne sais comment l'utiliser (j'aurais voulu m'en passer, j'aime bien les formules en 1 ligne !).
Dans le fond, je crois que j'ai du mal à comprendre la différence d'utilisation entre Range et Cells :

Sub COPY2() 'copie avec recherche première ligne non vide :
Dim lig As Long
lig = Selection.Row
Application.ScreenUpdating = False
Sheets("F2").Range(("G" & .Cells(Rows.Count, 1).End(xlUp).Row + 1)).Value = Sheets("F1").Cells(lig, 25)
Sheets("F2").Range(("H" & .Cells(Rows.Count, 1).End(xlUp).Row + 1)).Value = Sheets("F1").Cells(lig, 19) & " - " & Sheets("F1").Cells(lig, 18).Value

With Application
.ScreenUpdating = False
.CutCopyMode = False
End With
End Sub


Mon fichier d'exemple :
https://www.cjoint.com/c/JEEkaFlydyF

Pouvez-vous m'expliquer svp ce que je fais de travers ? :)

Merci par avance pour votre aide






Configuration: Windows 10 / Excel 2016
A voir également:

10 réponses

via55 Messages postés 14473 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 13 septembre 2024 2 728
30 mai 2020 à 12:12
Bonjour

Essaie ainsi :
Sub COPY2() 'copie avec recherche première ligne non vide :
Dim lig As Long
lig = Selection.Row
 ligne = Sheets("F2").Columns(7).Find("*", , , , xlByColumns, xlPrevious).Row + 1 '1ere ligne vide
Application.ScreenUpdating = False
 Sheets("F2").Range("G" & ligne) = Sheets("F1").Cells(lig, 25)
 Sheets("F2").Range("H" & ligne) = Sheets("F1").Cells(lig, 19) & " - " & Sheets("F1").Cells(lig, 18).Value

With Application
    .ScreenUpdating = False
    .CutCopyMode = False
End With
End Sub

Le With n'a rien à y voir, d'ailleurs tu l'as correctement utilisé

Dans Range on donne l'adresse d'une cellule :
Range("A1") ou Range("A" & n) utilisation d'une variable

Avec Cells on indique les coordonnées de la cellule
Cells(1,1) pour la cellule A1 ou Cells(1,n) ou Cells (x,y) avec variables

Cdlmnt
Via
1
via55 Messages postés 14473 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 13 septembre 2024 2 728
Modifié le 30 mai 2020 à 13:18
Re

Il faut boucler sur les lignes sélectionnées
Pour cela détecter d'abord le nombre de lignes sélectionnées avec Rows.Count
Sub COPY2() 'copie avec recherche première ligne non vide :
Dim lig As Long
lig = Selection.Row
nbl = Selection.Rows.Count
For n = lig To lig + nbl - 1
 ligne = Sheets("F2").Columns(7).Find("*", , , , xlByColumns, xlPrevious).Row + 1 '1ere ligne vide
Application.ScreenUpdating = False
 Sheets("F2").Range("G" & ligne) = Sheets("F1").Cells(n, 25)
 Sheets("F2").Range("H" & ligne) = Sheets("F1").Cells(n, 19) & " - " & Sheets("F1").Cells(n, 18).Value
Next
With Application
    .ScreenUpdating = False
    .CutCopyMode = False
End With
End Sub

Par contre ce que ne comprend pas dans ta macro c'est qu'il y a 2 fois .ScreenUpdating = False, un est donc superfétatoire, mais que jamais il n'est remis à True

1
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 305
30 mai 2020 à 13:54
Salut Via

Excuses l'incruste

With Application
.ScreenUpdating = False
.CutCopyMode = False
End With


Est dans ce cas inutile car:

1/ screenupdating il est inutile de le remettre à "true" en fdn fe macro (d'après le célèbre Laurent Longre)

2/ .CutCopyMode = False inutile car dans cette macro, on utilise pas le copier coller.


d'autre part,
ligne = Sheets("F2").Columns(7).Find("*", , , , xlByColumns, xlPrevious).Row
tu définis la fin de zone de recherche en colonne 7 , il est donc inutile de préciser "xlByColumns"

Penser à mettre toujours en "option explicit" (ligne n'est pas déclarée)


Cordialement
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 305 > michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023
30 mai 2020 à 16:04
Excusez moi d'avoir dérangé
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16 > michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023
30 mai 2020 à 19:33
Bonjour Michel

Merci pour ton intervention qu'on avait loupé car tu la mets en commentaire ...
Du coup je n'ai pas reçu la notification.
Je viens juste de la voir.
Tu veux dire que quand tu mets un screenupdating à False tu n'as pas besoin de la remettre en True ?
J'ai viré aussi le CutCopyMode
@ plus
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 305 > touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024
Modifié le 31 mai 2020 à 09:06
Bonjour,
Tu veux dire que quand tu mets un screenupdating à False tu n'as pas besoin de la remettre en True ?

Oui, cette instruction "s'éteint" à la fin de la procédure.... Laurent Longre était un des Chefs à 3 plumes reconnu MVP(Most Valuable Professionnal) par Microsoft et son site était une mine d'or tellement il y avait de solutions magiques dont le fameux "morefunc..." encore très utilisé aux USA; malheureusement il a tout fait disparaître....

Pour ta dernière intervention (le filtre), il faudrait savoir ce que tu filtres et combien as tu de lignes (un grand nombre ne veut rien en programmation) car il peut y avoir des problèmes au delà de 1000 lignes
le mieux serait que tu joignes un extrait de ton classeur)
Mettre le classeur sans données confidentielles en pièce jointe sur 
https://mon-partage.fr
Dans lien de téléchargement
faire un clic droit- copier l’adresse du lien et le coller dans votre message en cours sur ccm
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16 > michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023
31 mai 2020 à 09:02
Bonjour Michel
Dommage en effet
On n'entend plus trop Jacques Boisgontier non plus, mais son site reste une référence.
Pour tes conseils, une fois appliqués, en effet ça ne perturbe rien, au contraire la macro doit être un poil plus rapide.
Pour mon dernier post ci-dessous, as-tu une idée ?

A plus bon dimanche
0
eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024 7 234
30 mai 2020 à 13:40
Bonjour à tous,

pour t'éclairer sur ton 1er message d'erreur.
Tu mets :
Sheets("F2").Range(("G" & .Cells(Rows.Count, 1).End(xlUp).Row + 1)).Value = ...


avec le . de .Cells(Rows.Count, 1) tu lui dis de se référer au précédent With qui n'existe pas.
Il fallait écrire :
With Sheets("F2")
   .Range(("G" & .Cells(Rows.Count, 1).End(xlUp).Row + 1)).Value = ...
end With

le .Range et le .Cells se référeront à Sheets("F2")
eric
1
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
Modifié le 30 mai 2020 à 15:28
Bonjour Eric

Merci pour tes explications.
Heureusement car pour être franc je ne faisais pas la relation entre les points et les blocs With/End With.

Bonne journée à toi
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
Modifié le 30 mai 2020 à 12:29
Bonjour Via

Effectivement, ça fonctionne ainsi, j'ai pu adapter. Et merci aussi pour les explications.
En fait, j'étais loin du compte, je suis déçu ...

J'avais une deuxième étape, mais je voulais y aller molo.
Je souhaitais boucler sur cette macro.
A savoir, l'exécuter non pas sur la ligne active, mais sur toutes les lignes actives (les lignes des cellules sélectionnées en F1)

Mais en rédigeant ma question, ... je l'ai résolue ! MDR !


Un grand merci pour ton aide.
Bonne journée
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
30 mai 2020 à 12:42
Oups Via ..
J'ai été un peu vite.
Lorsque je sélectionne plusieurs lignes (par exemple 4), il me recopie 4 fois la première.
Je remets un fichiers d'exemple en ayant numéroté mes champs pour que ce soit plus clair :
https://www.cjoint.com/c/JEEkP13imcF

Merci encore ...
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
30 mai 2020 à 13:41
Cette fois c'est parfait, mille mercis.
C'était plus complexe que j'avais imaginé.

Pour le ScreenUpdating c'est juste une erreur de recopie depuis mon fichier source, pardon.
Je mets bien évidemment en résolu en t'adressant tous mes remerciements.

Bonne journée à toi
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
30 mai 2020 à 19:40
Bonsoir

Je reviens sur mon post, car j'ai encore un souci.
D'ailleurs je doute que ce soit le dernier.

Lorsque j'utilise la macro avec plusieurs lignes sélectionnées, ça fonctionne à présent, il me recopie bien toutes les cellules sur la feuille F2.
Par contre, mon tableau comporte un très grand nombre de lignes, et lorsque je lance la macro, j'ai appliqué auparavant un filtre sur mes colonnes (en F1).
Du coup, il me recopie les données de toutes les cellules masquées par le filtre, entre les 2 lignes sélectionnées.
Y a-t-il un autre moyen de boucler que :
For n = lig To lig + nbl - 1
?

Je ne sais pas si c'est possible, mais ça rend ma macro inutile.

Merci pour votre soutien.
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 305
31 mai 2020 à 09:11
re,
lis ou relis mon post 12
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
Modifié le 31 mai 2020 à 10:57
Michel, il y a plus de 1000 lignes, mais ce n'est pas le problème car le comportement est le même dans mon fichier exemple :

https://mon-partage.fr/f/CdYbEMOU/

As-tu une idée ?
A plus
0
eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024 7 234
Modifié le 31 mai 2020 à 13:55
Bonjour à tous,

exemple :
    Dim pl As Range, ar As Range, datas
    ' je prend le titre car SpecialCells(xlCellTypeVisible)
    ' retourne n'importe quoi si 1 seule cellule passée (visible)
    Set pl = [Y5].Resize(Cells(Rows.Count, "Y").End(xlUp).Row - 4)
    Set pl = pl.SpecialCells(xlCellTypeVisible)
    If Not pl Is Nothing Then
        For Each ar In pl.Areas
            ' attention que la 1ère ligne du 1er Area est le titre...
            datas = ar.Value     ' tableau ou valeur unique
            ' traitement qu'on ignore...
        Next ar
    End If

eric

0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16
Modifié le 31 mai 2020 à 19:28
Bonjour Eric

Merci, mais ... malgré le fait que je ne comprenne pas la macro, j'ai essayé d'adapter, sans succès.
J'ai fait ça, supposant que tu n'avais pas mis mon code de départ :
Sub TOUTLIG3()

Dim pl As Range, ar As Range, datas
' je prend le titre car SpecialCells(xlCellTypeVisible)
' retourne n'importe quoi si 1 seule cellule passée (visible)
Set pl = [Y5].Resize(Cells(Rows.Count, "Y").End(xlUp).Row - 4)
Set pl = pl.SpecialCells(xlCellTypeVisible)
If Not pl Is Nothing Then
For Each ar In pl.Areas
' attention que la 1ère ligne du 1er Area est le titre...
datas = ar.Value ' tableau ou valeur unique
Sheets("F2").Range("G" & pl) = Sheets("F1").Cells(n, 25)
Sheets("F2").Range("H" & pl) = Sheets("F1").Cells(n, 19) & " - " & Sheets("F1").Cells(n, 18).Value
Next ar
End If
End Sub


Peux-tu expliquer stp ? Ca me paraît intéressant mais il faut que je comprenne ...

https://mon-partage.fr/f/HhbH5X4E/

Merci par avance !
0
eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024 7 234
Modifié le 1 juin 2020 à 01:04
Selon ton filtre, pl va avoir des plages disjointes.
On ne peut pas les copier-coller comme ça.
( enfin je n'avais pas souvenir de ça, mais là il ne voulait pas...)
On doit donc boucler sur les areas et tu reçois les données par paquets successifs.
A chaque Area tu as soit une valeur unique, soit un tableau de 1 à x valeur, à traiter différemment.
Il faut donc d'abord tester ce que tu reçois
 If isarray(ar) then
    ' tu as un tableau à coller
else
    ' valeur unique
endif

Et soit tu colles directement en comptant les lignes collées pour décaler d'autant le collage du ar suivant.
Soit tu reconstitues un tableau unique à coller en une fois à la fin.
eric
0
touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024 16 > eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024
1 juin 2020 à 16:12
Bonjour Eric

Merci bien pour tes explications, je suis en train d'adapter maintenant que je sais ce que je fais, je reposterai ici une fois fini.

Cependant, j'aimerais partager ici la solution de Gbinforme avec lequel je converse par un autre biais.
Il a exploité le fait que dans un tableau filtré, les lignes non-affichées sont en attribut Hidden. Sa façon de faire est pleinement fonctionnelle en ajoutant ce code avant le début de la boucle :
If Sheets("F1").Rows(n).Hidden = False Then

Pour mémoire, pourra reservir.

Bonne journée
0
eriiic Messages postés 24595 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 2 septembre 2024 7 234 > touroul Messages postés 470 Date d'inscription mardi 5 octobre 2010 Statut Membre Dernière intervention 17 juin 2024
1 juin 2020 à 19:06
La différence c'est que tu dois boucler sur toutes les lignes ce qui prend du temps.
Avec SpecialCells(xlCellTypeVisible) tu les as toutes d'un coup.
eric
0