Se connecter avec
S'enregistrer | Connectez-vous

[Résolu] [Excel/VBA]Finalisation macro copier/coller

Dernière réponse : dans Programmation

Bien le bonjour.

Pour commencer je vais tenter de cadrer ma demande :
mon objectif est de récupérer les données d'un fichier (données de factures) pour les coller sur un autre classeur de récap.
Après survolage des 14 pages du fofo je n'ai pas trouvé ce qui m'intéresse précisément...

Mon problème est que j'aimerais coller ma sélection sur la prochaine ligne vide de mon fichier de récap.

N'ayant eu aucune formation en VBA je ne fonctionne quasiment qu'avec les macro d'imitations (désolé pour vos yeux :whistle:  )

Partie copie des données qui m'intéresse :
  1. Range("D2:G2").Select
  2. Selection.Copy
  3. Range("J2").Select
  4. Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  5. :=False, Transpose:=False
  6. Range("C18").Select
  7. Application.CutCopyMode = False
  8. Selection.Copy
  9. Range("K2").Select
  10. Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  11. :=False, Transpose:=False
  12. Range("C17").Select
  13. Application.CutCopyMode = False
  14. Selection.Copy
  15. Range("L2").Select
  16. Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  17. :=False, Transpose:=False
  18. Range("C13").Select
  19. Application.CutCopyMode = False
  20. Selection.Copy
  21. Range("M2").Select
  22. Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  23. :=False, Transpose:=False
  24. Range("G49").Select
  25. Selection.Copy
  26. Range("N2").Select
  27. ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
  28. Range("J2:N2").Select
  29. Selection.Copy

(améliorable ???)


Partie coller sur le fichier récap :
  1. Windows("RECAP FACTURE.xls").Activate
  2. Range("2:2").Select
  3. Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  4. :=False, Transpose:=False
  5. Windows("MODELE FACTURE.xls").Activate
  6. Range("J2:N2").Select
  7. Selection.ClearContents
  8. Range("D1:G1").Select
  9. End Sub


C'est là que mes problèmes arrivent =)

Comment coller sur la prochaine cellule vide ?

Je pense que ça se joue sur le point 2 : au lieu de
  1. Range("2:2").Select
qu'est-ce que je dois mettre ? (cellule de la colonne A pour info)


Partie facultative (mais que j'aimerais optimiser :D  )

Serait-il possible d'ouvrir le fichier de réception (S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls) au lieu d'activer le classeur :
  1. Windows("RECAP FACTURE.xls" ).Activate

avec un truc du genre
  1. ActiveWorkbook
mais je n'ai aucune idée du reste de la syntaxe

y copier les info (ça c'est bon)

sauvegarder
  1. SaveAs Filename:= _
  2. "S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls", FileFormat:= _
  3. xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
  4. , CreateBackup:=False
ça marcherait ???

et le fermer (ça je sais pas comment faire)

Merci d'avance pour toutes les réponses que vous pourrez me fournir.

Et bon appétit aussi !!!
Lassé par la pub ? Créez un compte
Expert Programmation

Aïe mes yeux !

J'ai pleins de choses à t'apprendre si tu veux. Je te demande juste un peu de réactivité et de bonne volonté. Et au bout de quelques questions, je parie que non seulement ton code ressemblera à quelque chose, mais qu'en plus il fonctionnera et bien.

On y va ?
Première question : As-tu lu ces topics ?
http://www.presence-pc.com/forum/ppc/Programmation/vous...
http://www.presence-pc.com/forum/ppc/Programmation/exce...
http://www.presence-pc.com/forum/ppc/Programmation/exce...

Je les ai écrit pour fournir une aide générale. Ton problème particulier peut sans doute y trouver une solution, mais on en reparlera. Je pense en particulier au message "La dernière ligne" des trucs et astuces.

J'ai déjà un peu regardé ton problème, si tu es réactif, tu auras rapidement la solution ;) 

Avant tout, merci de répondre aussi vite !!!

Pour répondre à tes question j'ai vu ton 3ème lien, mais pas les 2 premiers => MERCI !!!

Bon pour commencer, et ça va sûrement te faire plaisir voilà l'amélioration de la 1ère partie :
  1. Range("D2:G2").Copy
  2. Range("J2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  3. :=False, Transpose:=False
  4. Range("C18").Copy
  5. Range("K2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  6. :=False, Transpose:=False
  7. Range("C17").Copy
  8. Range("L2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  9. :=False, Transpose:=False
  10. Range("C13").Copy
  11. Range("M2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
  12. :=False, Transpose:=False
  13. Range("G49").Copy
  14. Range("N2").Select
  15. ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
  16. Range("J2:N2").Copy


j'ai essayé de virer ":=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False" dans les lignes, mais du coup ça me colle les données en direct, pas en coller valeur, donc ça me fait tout foirer ^^'

En fait ça veux dire quoi tout ça, qu'est-ce qui est indispensable, et qu'est-ce qu'on peut supprimer ?



Pour le reste j'ai réussi à intégrer la sauvegarde :
  1. ActiveWorkbook.SaveAs Filename:= _
  2. "S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls", FileFormat:= _
  3. xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
  4. , CreateBackup:=False

(même question, comment le nettoyer ???)



Et enfin pour le coeur du problème
j'ai essayé
  1. Range("A1" ).End(xlDown).Row + 1

eu lieu de
  1. Range("2:2" ).Select

mais ça me donne : "erreur de compilation : utilisation incorrecte de la propriété" en me surlignant .Row

et là, ben je sèche à nouveau...

Expert Programmation

Ah, voilà quelqu'un avec du répondant ! :) 
J'aime beaucoup ton amélioration.


2:2
, c'est l'adresse de la ligne 2.
Range()
, ce sont les cellules de la plage dont on a donné l'adresse.
Range("A1" ).End(xlDown).Row + 1
, c'est le numéro de la ligne.

Donc il faut se débrouiller pour écrire n:n dans Range. Si c'st possible, c'est moche. Dans les trucs et astuces sur VBA./Excel, je donne l'utilisation de Cells. C'est quand même plus pratique, puis que le numéro de colonne et le numéro de ligne sont donnés à part et en numérique.

Tu m'essayes ça ?

Quant au nettoyage, relis l'aide de PasteSpecial et de SaveAs, et retire chaque élément optionnel auquel tu n'as pas mis une valeur différente de celle par défaut.

merci du compliment :D 

alors j'ai testé
  1. Range("2:2").End(xlDown).Row 1

et ça marche toujours pas, même erreur que précédemment, mais je pense que ça vient du .Row pas du Range

D'ailleurs en t'écrivant cette réponse je viens de capter pourquoi :
Mon VBA ne garde pas le "+" de ".Row+1"...


sinon ça s'améliore bien :
  1. Range("D2:G2").Copy
  2. Range("J2").PasteSpecial Paste:=xlPasteValues
  3. Range("C18").Copy
  4. Range("K2").PasteSpecial Paste:=xlPasteValues
  5. Range("C17").Copy
  6. Range("L2").PasteSpecial Paste:=xlPasteValues
  7. Range("C13").Copy
  8. Range("M2").PasteSpecial Paste:=xlPasteValues
  9. Range("N2").Select
  10. ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
  11. Range("J2:N2").Copy
  12. Windows("RECAP FACTURE.xls").Activate
  13. Range("2:2").PasteSpecial Paste:=xlPasteValues
  14. Range("A1").Select
  15. ActiveWorkbook.SaveAs Filename:= _
  16. "S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls", FileFormat:= _
  17. xlNormal
  18. Windows("MODELE FACTURE.xls").Activate
  19. Range("J2:N2").ClearContents
  20. Range("D1:G1").Select



Possibilité de combiner
  1. Range("N2" ).Select
  2. ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"


  1. Range("N2" ).ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
ça, ça marche pas en tout cas...

Expert Programmation

Range("2:2" ).End(xlDown).Row + 1
est un numéro de ligne !!!!!!
C'est la ligne (Row) suivante (+1) de la dernière (End) cellule vers le bas du bloc auquel appartient la cellule 2:2 ! (Bon, c'est idiot de considérer une ligne, je mettrais plutôt A2 pour contrôler dans quel colonne je cherche la première cellule vide.)

Donc :
  1. n = Range("A2" ).End(xlDown).Row + 1
  2. MsgBox "Il serait judicieux de considérer la ligne " & n


Relis bien ceci et écris-toi "Mais c'est bien sûr !"
Range("N2" ).FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"

:whistle: 

Encore un tout petit effort et on peut passer à la réécriture totale du code ;) 

j'en suis là :
  1. Range("D2:G2").Copy
  2. Range("J2").PasteSpecial Paste:=xlPasteValues
  3. Range("C18").Copy
  4. Range("K2").PasteSpecial Paste:=xlPasteValues
  5. Range("C17").Copy
  6. Range("L2").PasteSpecial Paste:=xlPasteValues
  7. Range("C13").Copy
  8. Range("M2").PasteSpecial Paste:=xlPasteValues
  9. Range("N2").FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
  10. Range("J2:N2").Copy
  11. Windows("RECAP FACTURE.xls").Activate
  12. Range("A2").PasteSpecial Paste:=xlPasteValues
  13. Range("A1").Select
  14. ActiveWorkbook.SaveAs Filename:="S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls"
  15. Windows("MODELE FACTURE.xls").Activate
  16. Range("J2:N2").ClearContents
  17. Range("D1:G1").Select


et je continue à sécher sur
  1. Range("A2" ).End(xlDown).Row+1.PasteSpecial Paste:=xlPasteValues


je vois vraiment pas le truc là... :??:  :??:  :??: 
Expert Programmation

  1. Dim ligne As Long
  2.  
  3. ligne = Range("A2" ).End(xlDown).Row + 1
  4. MsgBox "La ligne est la n°" & ligne
  5. MsgBox "La cellule est " & Cells(ligne, 1).Address

Non ? Toujours pas ?
Expert Programmation

Bon alors maintenant revenons à ce programme vraiment laid.
Par principe, il est inadmissible d'utiliser le presse-papier pour stocker les données temporaires d'un programme.

On ouvre l'aide de VBA/Excel et on apprend à se servir de Copy. Oh, bah il y a un paramètre facultatif Destination pour préciser vers où copier les données !
  1. Range("D2:G2" ).Copy Range("J2" )

Ah ! Là, c'est propre. Cool :sol: 

Hein, pas cool ? Ben non. La méthode Copy est pas fichue d'avoir des paramètres genre Paste:=xlPasteValues et ce ne sont pas les valeurs qui sont copiées mais les formules :/ 


Bon, ben on va faire autrement. On prend le problème dans l'autre sens :
  1. Range("J2").Value = Range("D2").Value
  2. Range("K2").Value = Range("E2").Value
  3. Range("L2").Value = Range("F2").Value
  4. Range("M2").Value = Range("G2").Value

Là, ça marche.

Allez, juste par principe, on va mettre une boucle, car si on observe bien, on remarque que c'est juste un décalage (offset) de 6 cases à droite :
  1. Dim cellule As Range
  2. For Each cellule In Range("D2:G2")
  3. cellule.Offset(0, 6).Value = cellule.Value
  4. Next

Ah, là c'est beau :sol: 

Bon, ça fait :
  1. Dim cellule As Range
  2. For Each cellule In Range("D2:G2")
  3. cellule.Offset(0, 6).Value = cellule.Value
  4. Next
  5. Range("K2").Value = Range("C18").Value
  6. Range("L2").Value = Range("C17").Value
  7. Range("M2").Value = Range("C13").Value
  8. Range("N2").FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"


Bon, et après on ouvre un autre classeur, on copie nos valeurs dans le nouveau classeur et on supprime ce qu'on vient de faire !
:pfff:  Et ben....

On efface tout et on recommence.
Expert Programmation

  • Soit wb_source le classeur actif duquel on copie les données.
  • Soit wb_cible le classeur vers lequel on copie les données.
  • Ouvrir wb_cible.
  • Pour chaque cellule de wb_cible, copier la cellule correspondante de wb_source.
  • Sauvegarder et fermer wb_cible.

    vraiment plus clair comme ça, tu as bien raison :
    1. Range("J2").Value = Range("D2:G2").Value
    2. Range("K2").Value = Range("C18").Value
    3. Range("L2").Value = Range("c17").Value
    4. Range("M2").Value = Range("c13").Value
    5. Range("N2").FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"
    6. Range("J2:N2").Copy
    7. Windows("RECAP FACTURE.xls").Activate
    8. Range("A2").PasteSpecial Paste:=xlPasteValues
    9. Range("A1").Select
    10. ActiveWorkbook.SaveAs Filename:="S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls"
    11. Windows("MODELE FACTURE.xls").Activate
    12. Range("J2:N2").ClearContents
    13. Range("D1:G1").Select


    je garde "D2:G2" car il s'agit d'une cellule fusionnée en fait

    mais je trouve toujours pas pour la prochaine cellule vide !!!!!!!! (pourtant j'ai essayé pleins de trucs...)
    Expert Programmation

    Minute papillon, j'ai pas eu le temps de tout écrire ;) 
    Bon, j'ai dit qu'on recommençait tout.

    Allez, étudie-moi ça :

    1. Sub au_boulot()
    2. Dim wb_source As Workbook
    3. Dim wb_target As Workbook
    4. Dim ws_source As Worksheet
    5. Dim ws_target As Worksheet
    6. Dim ln_target As Range
    7.  
    8. Set wb_source = ActiveWorkbook
    9. Set wb_target = Workbooks.Open("chemin\recap.xls")
    10.  
    11. ' On ne considère que la première feuille de chaque classeur
    12. Set ws_source = wb_source.Worksheets(1)
    13. Set ws_target = wb_target.Worksheets(1)
    14.  
    15. ' Recherche de la première cellule vide de la colonne A dans le classeur cible
    16. Set ln_target = ws_target.Range("A1").End(xlDown).Offset(1).EntireRow
    17.  
    18. ' Etude de la ligne précédente :
    19. MsgBox "Nom de la feuille : " & ws_target.Name & vbCrLf & _
    20. "Adresse de A1 : " & ws_target.Range("A1").Address & vbCrLf & _
    21. "Adresse de la dernière cellule pleine : " & ws_target.Range("A1").End(xlDown).Address & vbCrLf & _
    22. "Ligne de la première cellule vide : " & ws_target.Range("A1").End(xlDown).Row + 1 & vbCrLf & _
    23. "Adresse de la première cellule vide : " & ws_target.Range("A1").End(xlDown).Offset(1).Address & vbCrLf & _
    24. "Adresse de la première ligne vide : " & ws_target.Range("A1").End(xlDown).Offset(1).EntireRow.Address
    25.  
    26. ln_target.Cells(1).Value = ws_source.Range("D2").Value
    27. ln_target.Cells(2).Value = ws_source.Range("C18").Value
    28. ln_target.Cells(3).Value = ws_source.Range("C17").Value
    29. ln_target.Cells(4).Value = ws_source.Range("C13").Value
    30. ln_target.Cells(5).Value = Application.WorksheetFunction.VLookup(ws_source.Range("N9"), ws_source.Range("A:G"), 7, False)
    31. End Sub

    Houla chaud ta macro, c'est pas du même niveau que le mien !!! (quoique je crois que je la comprends à peu près)

    Par contre je ne percute toujours pas le fonctionnement pour la cellule vide:
    Range("A1") => où se placer pour faire notre "enquête"
    End(x1Down) => descendre jusqu'à la dernière ligne renseignée
    Row+1 => descendre une ligne en dessous
    enfin y coller ce qu'on veut

    soit :
    1. Range("A1").End(x1Down).Row+1.PasteSpecial Paste:=xlPasteValues

    mais ça marche pas )'=


    Questions sur ton code :
    - Toute la première partie (jusqu'à la ligne 25) sert à définir où sont les données de base et où les intégrer c'est bien ça ?
    - la MesageBox a une utilité pour la macro ou est juste là à titre indicatif ?
    - Comment on définit les Target.Cells du ws.target ???

    J'avoue que je suis un peu dépassé par ton code (impossible pour moi de le reproduire pour l'instant) mais je persisterai jusqu'à le comprendre vraiment et pouvoir en faire de même !!!
    Vivement demain le retour au boulot pour voir tes réponses.

    Et aussi, un grand MERCI pour tout tes conseils, passer en une demi journée de néophyte en VBA à commencer à le comprendre ça fait vraiment plaisir, tu es de très bon conseil =)

    Bonne soirée et à demain !!!
    Expert Programmation

    Tu fais plaisir à lire :) 

    Le msgbox est une 'étude'. C'est-à-dire que je te donne l'occasion de 'voir' chaque étape de la ligne précédente. C'est donc du debuggage. Ne pas laisser ce bout de code dans le programme définitif.

    Jusqu'à la ligne 25, on ne fait que viser (target ;)  <-- t'as vu ? je ferme un oeil pour mieux viser :D  ) effectivement.

    Citation :
    Row+1 => descendre une ligne en dessous

    Non, non et non. Cela ne descend rien. Si je dis que ton salaire est de 100€, et que (salaire*40) est ce que tu mériterais, je n'ai pas augmenté ton salaire. Range().End().Row+1 est le numéro de la ligne où il faut mettre tes données. En fait, il faut référencer la ligne, pas sont numéro. L'exemple donné dans les trucs et astuces est générique.

    Relis ce topic : http://www.presence-pc.com/forum/ppc/Programmation/exce... et mets un point d'arrêt sur la ligne 16 (touche [F9]) puis lance la macro ([F5]). Quand ton programme s'arrête, glisse dans la fenêtre espion les mots ws_target.Range("A1" ). Explore un peu cet objet. Tu comprendras pas mal de chose. Glisse-y aussi Range("A1" ).End(x1Down) et explore-le aussi. Ce sont des objets Range, ils ont pleins de propriétés, dont Row qui est la ligne de la feuille à laquelle ils appartiennent.

    Cette propriété n'est pas un objet, c'est un scalaire. Un scalaire n'a pas de propriété, juste une valeur. La valeur scalaire de Row pour A1, c'est 1. On ne peut donc pas ce servir de Range("Xn").Row comme objet, puisque ce n'est qu'un nombre. Range("A1" ).End(x1Down).Row+1.PasteSpecial n'a aucun sens.

    Range() est un Range (Range=une plage de une ou plusieurs cellules)
    Range().End() est aussi un Range
    Range().Row est un Long (un entier long). On ne s'en servira pas.
    Range().Offset() est un Range
    Range().EntireRow est un Range

    Donc Range().End().Offset().EntireRow est un Range sur lequel on va pouvoir travailler.

    Citation :
    Houla chaud ta macro

    Ch'chuis pas d'accord, je prétends que mon code est plus facile à comprendre que le tien :o 
    Ce qui se conçoit bien s’énonce clairement – Et les mots pour le dire arrivent aisément.
    Je n'ai donc pas plus de mérite que cela, sinon que d'accepter de t'en faire profiter.

    Expert Programmation

    Tiens voilà une version encore plus épurée :

    1. Dim wb_target As Workbook
    2. Dim ws_source As Worksheet
    3. Dim ln_target As Range
    4.  
    5. Set ws_source = ActiveWorkbook.Worksheets(1)
    6. Set wb_target = Workbooks.Open("chemin\recap.xls")
    7. Set ln_target = wb_target.Worksheets(1).Cells(1, 1).End(xlDown).Offset(1).EntireRow
    8.  
    9. ln_target.Cells(1).Value = ws_source.Range("D2").Value
    10. ln_target.Cells(2).Value = ws_source.Range("C18").Value
    11. ln_target.Cells(3).Value = ws_source.Range("C17").Value
    12. ln_target.Cells(4).Value = ws_source.Range("C13").Value
    13. ln_target.Cells(5).Value = Application.WorksheetFunction.VLookup(ws_source.Range("N9"), ws_source.Range("A:G"), 7, False)
    14.  
    15. wb_target.Save


    A charge pour toi d'y ajouter des commentaires. Moi je le lis comme du français, toi pas encore ;) 

    Salut

    Ok je commence à bien capter là.

    1 : on vise le classeur source.
    2 : on vise la feuille source.
    3 : on se positionne sur nos cellules cibles (?)

    5 : la feuille active devient nos données sources
    6 : le classeur qu'on ouvre devient le fichier cible
    7 : la première ligne vide devient notre zone cible

    9 à 13 : on colle dans les cellules cibles nos données qui sortent directement du classeur source.
    0-1-2... correspondent à la 1ère cellule, 2nde cellule... de la sélection ? (ici la première ligne vide définie avant c'est bien ça?)

    J'ai bon ?


    Juste je trouve pas à quoi correspond "ln" (c'est bien LN et pas IN ?)


    Et quand je l'exécute, je constate bien (par l'onglet espion) qu'on vise bien la bonne ligne, mais j'ai un message d'erreur :
    "Erreur d'exécution '1004'
    Erreur définie par l'application ou l'objet"

    et là, une fois de plus je capte pas le problème...



    Sinon pour revenir sur la première case vide, j'ai compris le déroulement de Range(A1).End(xlDown).Row+1 mais ça me positionnera sur la ligne, pas sur la cellule vide c'est bien ça ?
    Dans ce cas là, comment demander le positionnement sur la première cellule vide (bien que je comprenne que ça devienne inutile car avec ta méthode on défini cette ligne comme le range où on va travailler sans avoir besoin de s'y positionner, mais ça me servira à mieux comprendre ^^)



    PS : bon appétit =)
    Expert Programmation

    Yes :)  T'as bon !
    A part qu'on ne parle pas de 'coller' les cellules parce qu'on ne passe pas par le presse-papier. La nuance est importante. (Je l'ai mise en rouge ). En programmation, on affecte une valeur à une variable. Bon, là on pourrait dire 'je mets la valeur'.

    J'aurais très bien pu écrire
    1. ln_target.Cells(1) = ws_source.Range("D2" )

    Mais je trouve important de faire le distingo entre Value, Text et Formula.

    Grrrr :fou: , une coquille s'est glissée dans mon code. J'ai corrigé. Il faut commencer la numérotation ces Cells à 1, pas à 0 :/ 
    Je lis couramment le VB, mais je vais des fautes d'orthographe quand je l'écris ^^

    re-grrrr :fou:  Non, ça ne te positionnera pas sur la ligne, ça te donne le numéro de ligne.


    PS: Merci. Vapeurs sauce piquante + nem au poulet. :jap:  ça pête le bide mais on est Vendredi :D 
    Expert Programmation

    Bon, alors en testant mon code, je m'aperçois d'une grosse bêtise.
    C'est l'utilisation de End(). Si tu n'as moins de deux lignes, c'est-à-dire en ligne 1 un entête et en ligne 2, déjà une ligne, on va se retrouver tout en bas de la feuille. Essayer de voir avec une, deux, plus de lignes comment réagissent les combinaison de touches [Ctrl+Up] et [Ctrl+Down].

    Bon, la solution est .

    Application pratique :
    1. Set ln_target = wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1).EntireRow

    ça marche !!!!!!!!!!

    1. Sub Extraction_tableau_recap ()
    2. Dim wb_source As Workbook
    3. Dim wb_target As Workbook
    4. Dim ws_source As Worksheet
    5. Dim ws_target As Worksheet
    6. Dim ln_target As Range
    7.  
    8. Set wb_source = ActiveWorkbook
    9. Set wb_target = Workbooks.Open("S:\GESTION\- CdG°\YB\RECAP FACTURE\RECAP FACTURE.xls")
    10.  
    11. Set ws_source = wb_source.Worksheets(1)
    12. Set ws_target = wb_target.Worksheets(1)
    13.  
    14. Set ln_target = wb_target.Worksheets(1).Cells(1,1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1).EntireRow
    15.  
    16. ln_target.Cells(1).Value = ws_source.Range("D2").Value
    17. ln_target.Cells(2).Value = ws_source.Range("C18").Value
    18. ln_target.Cells(3).Value = ws_source.Range("C17").Value
    19. ln_target.Cells(4).Value = ws_source.Range("C13").Value
    20. ln_target.Cells(5).Value = Application.WorksheetFunction.VLookup(ws_source.Range("N1"),ws_source.Range("A:G"), 7,False)
    21.  
    22. wb_target.Save
    23. wb_target.Close
    24. End Sub


    c'était volontaire la petite feinte (N9 au lieu de N1)????? :kaola:  :D 
    1. ln_target.Cells(5).Value = Application.WorksheetFunction.VLookup(ws_source.Range("N9"), ws_source.Range("A:G"),7, False)




    Donc en résumé pour faire un codage propre ça se joue en gros en 3 étapes (du moins dans ce genre de cas) :

    - viser les classeurs / feuilles / zone de travail
    - définir le fichier source, le fichier cible et la zone cible
    - dire quoi faire dans chaque cellule cible


    Maintenant si je veux coller plus de données j'aurais juste à faire

    - pour copier une valeur :
    1. ln_target.Cells(x).Value = ws_source.Range("Xn").Value


    - pour obtenir le résultat d'une formule :
    1. ln_target.Cells(x).Value = Application.WorksheetFunction.la fonction désirée



    Donc ne rajouter qu'une ligne par nouvelle info au lieu d'en utiliser 3 ou 4 comme dans ma "macro" de base (entre "" car maintenant on peux vraiment parler de macro ^^)


    Pour terminer encore quelques question =)

    Tu voudrais bien m'expliquer, en littéraire, ce que veux dire "CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1)" dans
    1. Set ln_target = wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1).EntireRow



    Nécessité de mettre "Application.WorksheetFunction" pour appliquer une fonction ???
    pourquoi pas
    1. ln_target.Cells(x).Value = ws_source.la fonction désirée




    Et si je voulais coller mes valeurs à 2 endroits différents, comment définir 2 targets différentes (N° 1, N°2...???) et comment dire de "mettre la valeur" ( ;)  ) dans la cible 1 ou dans la 2 (suis-je clair ?)



    Et sans oublier : MERCIIIIIIIIIIIIIIIIIIII !!!!!!!!!!!!!!!
    Super conseils, super méthode, là je sens que j'ai vraiment appris des choses, c'est bien mieux que de filer la soluce direct !!!


    Re =)

    Je viens d'essayer d'intégrer une nouvelle ligne :
    copier la date, sauf que seuls les 10 derniers caractères de la cellule m'intéresse.
    J'ai donc essayé :
    1. ln_target.Cells(1).Value = Application.WorksheetFunction.Right(ws_source("D3"), 10)

    mais ça marche pô...

    J'ai essayé de reproduire le même processus que pour
    1. ln_target.Cells(5).Value = Application.WorksheetFunction.VLookup(ws_source.Range("N1" ),ws_source.Range("A:G" ), 7,False)

    mais vu que ça ne fonctionne pas, j'ai du passer à côté d'une subtilité...

    J'attends tes commentaires coupaing :bounce: 
    Expert Programmation

    1°) Feinte ?! Eh, c'est ton code, ça, tout en relatif :
    1. ActiveCell.FormulaR1C1 = "=+VLOOKUP(R[-1]C,C[-13]:C[-7],7,FALSE)"


    2°)
    1. ln_target.Cells(x).Value = ws_source.Range("Xn" ).Value

    Je dirais plutôt, dans le cas générique :
    1. ws_target.Cells(row_target, col_target).Value = ws_source.Cells(row_source, col_source).Value
    Mais c'est vrai que c'est plus lisible d'utiliser la notation A1 du range.

    3°) VLookUp n'est pas une fonction VB ni VBA. C'est une macro interne Excel. Impossible donc de l'utiliser en VB, sauf à passer par l'objet WorksheetFunction. C'est tordu, mais c'est comme ça.

    4°) Tu voudrais bien m'expliquer, en littéraire... Non. Vas lire la doc d'Excel. Un point entre deux mots trahit une construction objet. Donc pour comprendre wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1).EntireRow, il faut comprendre wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1).EntireRow, il faut comprendre wb_target, wb_target.Worksheets(1), wb_target.Worksheets(1).Cells(1, 1), wb_target.Worksheets(1).Cells(1, 1).CurrentRegion, wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell) et wb_target.Worksheets(1).Cells(1, 1).CurrentRegion.SpecialCells(xlCellTypeLastCell).Offset(1). L'aide en ligne est là pour toi. Fais des tests, fonction par fonction, en t'aidant du déboggueur. Ce n'est pas si difficile. En plus, tu prendras de bonnes habitudes : en ayant chercher soi-même avant de poser une question, d'une part on peut trouver par soi-même, si, si, d'autre part, on comprend beaucoup mieux la réponse, surtout si elle est astucieuse. Par contre, il arrive qu'on cherche longtemps sans trouver, qu'on se permette de poser la question et que la réponse soit vexante tellement elle est simple. Ne pas en prendre ombrage, les forums sont aussi là pour ça. :) 

    Bon alors, tu me fais croire que tu as cherché que je puisses te répondre ?
    Expert Programmation

    Ah, je n'ai pas répondu à toute tes questions.

    Plusieurs targets :
    1. Cells(2, 1).Value = Cells(1, 1).Value
    2. Cells(3, 1).Value = Cells(1, 1).Value
    3. Cells(4, 1).Value = Cells(1, 1).Value
    4. Cells(5, 1).Value = Cells(1, 1).Value
    5. Cells(6, 1).Value = Cells(1, 1).Value


    Pour "Mettre la valeur", reporte-toi à
    Citation :
    Mais je trouve important de faire le distingo entre Value, Text et Formula.
    C'est à dire [F1] sur Value, Text et Formula.

    C'est bien vrai ça, et pour partir en week-end du bon pied !!!!!!!!!!

    1. ln_target.Cells(1).Value = Right(ws_source.Range("D3"), 10)


    "C'est bon pour le moral, c'est bon bon, c'est bon pour le moral" :bounce:  :bounce:  :bounce: 


    Encore merci et bon week-end à toi !!!
    Expert Programmation

    Et non, ti male ! Bien essayé mais il ne faut pas confondre Valeur et Format :o 

    Citation :
    copier la date, sauf que seuls les 10 derniers caractères de la cellule m'intéresse.


    1. ln_target.Cells(1).Value = ws_source.Range("D3" )
    2. ln_target.Cells(1).NumberFormat = "yyyy/mm/dd"


    :sol: 

    Je suppose que tu ne liras ça que Lundi matin. Alors j'espère que toi aussi tu auras passé un bon we.

    Bien le bonjour !!!

    En effet je ne lis ça que maintenant.

    Et pour ta formule ça n'ira pas, car dans la cellule d'origine on trouve : "Le xx/xx/20xx", donc il ne me faut vraiment que les 10 derniers caractères.
    Par contre j'ai noté pour le format de cellule.

    Merci encore et bonne continuation.

    Je repasserai en cas de besoin reprendre une petite dose de tes judicieux conseils =)
    Lassé par la pub ? Créez un compte