Votre question
Résolu

Copier des lignes automatiquement, sous condition...

Tags :
  • Microsoft Excel
  • Programmation
  • VB
Dernière réponse : dans Programmation
8 Avril 2010 11:46:57

Bonjour,
Me revoilà avec une question de "nioubi" : Dans une formulaire créer sous Excel, je souhaite copier une ligne particulière lorsque l'utilisateur coche une case.
Pour ça, pas de problème, même si mon code n'est pas très "propre", ça fonctionne :

  1. Sub plus1()
  2. '
  3. ' Ajoute un additif
  4. '
  5.  
  6. '
  7. Rows("41:41").Select
  8. Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  9. Range("I40:AC40").Select
  10. Selection.Copy
  11. Range("I41").Select
  12. ActiveSheet.Paste
  13. Range("I40:L40").Select
  14. Application.CutCopyMode = True
  15. Selection.Copy
  16. Range("I41:L41").Select
  17. ActiveSheet.Paste
  18. Range("U40:X40").Select
  19. Application.CutCopyMode = True
  20. Selection.Copy
  21. Range("U41:X41").Select
  22. ActiveSheet.Paste
  23. End Sub


Maintenant, le vrai problème, c'est que en fonction de lignes qui auraient pu être insérées par cette même méthodes, mais plus haut dans le formulaire (par exemple au niveau de la Row 34), je ne vais plus copier la ligne que je souhaitais, qui se trouvait être la Row41, mais qui est maintenant en 42. :fou: 

Donc, ma question est : comment puis-je copier une ligne, quelque soit sa position dans la feuille Excel ?

Il y en a qui vont peut être trouver ça simple (et tant mieux parce qu'ils vont pouvoir m'aider), mais moi je bloque.

D'avance, merci à tous les contributeurs !

Autres pages sur : copier lignes automatiquement condition

a b L Programmation
8 Avril 2010 14:26:16

Non, non, non et non :fou:  :fou:  :fou:  :fou: 
(voilà, je suis tout énervé maintenant ... :(  )

...................

Salut JP,

Je n'aime pas voir un Selection suivre un Select dans vos codes. C'est une perte de temps pour le développeur et pour l'utilisateur de vos développements.

De plus, il me semble inadmissible qu'un programme (oui, bon, une macro, ça peut être un peu moins qu'un programme, mais c'est par principe) remplisse le presse-papier. Et si avant de lancer la macro j'y avais copié des trucs importants ? :o 
Donc on se sert du paramètre Destination de la méthode Copy.

Ça donne :
  1. Rows("41:41").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  2.  
  3. Range("I40:AC40").Copy Destination:=Range("I41")
  4. Range("I40:L40").Copy Destination:=Range("I41:L41")
  5. Range("U40:X40").Copy Destination:=Range("U41:X41")
C'est quand même plus clair, non ?
(En plus, comme ça, on voit tout de suite qu'il y a un chtit problème, les zones se recoupent ;)  )

Bon, maintenant, toutes ces adresses en dur, ce n'est pas terrible.

On peut toujours créer les adresses avec des "I" & n & ":AC" & n, mais le mieux est encore de se servir de Cells. Range("I40") devient alors Cells(40, 9). Au lieu de chaînes de caractères, on a des coordonnées numériques, ça va être plus simple.

On refait le code :
  1. Rows(41).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  2.  
  3. Range(Cells(40, 9); Cells(40, 29)).Copy Destination:=Cells(41, 9)
  4. Range(Cells(40, 9), Cells(40, 12)).Copy Destination:=Cells(41, 9)
  5. Range(Cells(40, 21), Cells(40, 24).Copy Destination:=Cells(41, 21)
Voilà. Il n'y a plus que des nombres. :) 
Pas la peine de définir une plage pour la destination, une cellule unique suffit (la première en haut à gauche).

Bon, ce bout de programme ne fonctionne que pour la ligne 41. Ben pour la ligne n, c'est très facile :
  1. Rows(n).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  2.  
  3. Range(Cells(n-1, 9); Cells(n-1, 29)).Copy Destination:=Cells(n, 9)
  4. Range(Cells(n-1, 9), Cells(n-1, 12)).Copy Destination:=Cells(n, 9)
  5. Range(Cells(n-1, 21), Cells(n-1, 24).Copy Destination:=Cells(n, 21)


Ça t'aide ?
m
0
l
8 Avril 2010 15:42:46

MERCI !

Effectivement, j'ai une sale manie avec mes selection suivi de select, mais ça vient de l'habitude de l'enregistreur de macro ... mea culpa ! :whistle: 

Par contre, je me permettrais de corriger un petit oubli de parenthèse dans ton code :
  1. Rows(n).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  2.  
  3. Range(Cells(n - 1, 9), Cells(n - 1, 29)).Copy Destination:=Cells(n, 9)
  4. Range(Cells(n - 1, 9), Cells(n - 1, 12)).Copy Destination:=Cells(n, 9)
  5. Range(Cells(n - 1, 21), Cells(n - 1, 24)).Copy Destination:=Cells(n, 21)


Donc, ça marche super, SAUF QUE (et oui, il fallait bien un sauf...) mon problème est que ce n'est pas toujours la ligne 41, mais que je ne sais pas à l'avance quelle ligne ce sera (puisqu'elle peut être décalée en fonction des modifications sur les lignes supérieures).

Comprends-tu mon angoisse ?

Merci d'avance, ô maître (oui je sais, j'en fais trop).
m
0
l
Contenus similaires

Meilleure solution

a b L Programmation
8 Avril 2010 17:19:23

Celui-là pour te faire passer tes sales manies : [:zeb:4]
Celui-là pour tes corrections : :sarcastic:  (une parenthèse, mais un point-virgule qui traîne, aussi)
Ces deux-là pour ton "ô maître" : :lol:  :lol: 

------------------------------------------------------

Et comment veux-tu qu'en VBA, on puisse deviner quelle ligne n utiliser ?

Echappons-nous en peu de VBA, pour discuter d'Excel. Sais-tu que les cellules d'un classeur peuvent avoir des noms ? Ceux-ci doivent être uniques pour un même classeur. Ainsi peut-on nommer la cellule B12 de la feuille 2 par le doux sobriquet de "SOMME_TOTALE". Ce n'est qu'un exemple. :o 

Revenons à nos moutons.
Et si tu nommais une cellule particulière du coté de la ligne 41 pour t'y référer ensuite !
partage
19 Avril 2010 08:23:55

Et oui, arrêter de cloisonner Excel et VBA ... Ah ! si évident qu'il suffisait d'y penser...
Encore merci !
m
0
l
19 Avril 2010 08:24:27

Meilleure réponse sélectionnée par jprieux.
m
0
l