Syntaxe pour copie cellules ligne active

touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   -  
eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   -
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

10 réponses

  1. via55 Messages postés 14393 Date d'inscription   Statut Membre Dernière intervention   2 759
     
    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
  2. via55 Messages postés 14393 Date d'inscription   Statut Membre Dernière intervention   2 759
     
    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
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      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
    2. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320 > michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention  
       
      Excusez moi d'avoir dérangé
      0
    3. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17 > michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention  
       
      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
    4. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320 > touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    5. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17 > michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention  
       
      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
  3. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    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
    1. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
       
      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
  4. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
  7. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
  8. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      re,
      lis ou relis mon post 12
      0
  9. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
  10. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
     
    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
  11. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17
     
    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
    1. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281
       
      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
      1. touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention   17 > eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention  
         
        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
      2. eriiic Messages postés 24581 Date d'inscription   Statut Contributeur Dernière intervention   7 281 > touroul Messages postés 526 Date d'inscription   Statut Membre Dernière intervention  
         
        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