Macro Excel pour copier le résultat de formules
Bonjour le forum,
Je viens de m'inscrire pour faire appel à vos compétences, car je galère vraiment !
J'ai des formules Excel et je souhaite créer une macro qui recopie le résultat de ces formules sur la même ligne, en décalant à chaque fois d'une colonne. Exemple : dès que la valeur de la liste déroulante en B29 est modifiée, un calcul se fait en C29. Puis, après un message, la valeur de C29 est automatiquement recopiée en N29. S'il y a une autre valeur du même type en B29, un nouveau calcul se fait et la valeur se recopie en O29. Ainsi de suite avec P29, Q29 ..., jusqu'à ce qu'il y ait des valeurs. Puis on passe à la ligne 30.
Le but est d'additionner les différentes valeurs, par ligne, dans la colonne M
A l'heure actuelle, je suis obligé de cliquer dans la cellule qui contient la formule (C29, par exemple) pour déclencher la macro.
J'ai essayé en faisant un copier-coller spécial, mais ça ne fonctionne pas. Dans un premier temps, je ne suis pas allé plus loin que vouloir copier la valeur dans une cellule donnée. Le but, c'est de mettre la valeur dans la première colonne vide à gauche (mais, je ne vois pas exactement comment adapter quelque chose comme "End(xlToLeft).Offset(0, 1)" à mon cas).
Quelqu'un aurait-il une idée ?
Voici mon code :
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Pl As Range 'déclare la variable Pl (Plage)
Dim i, Col As Long
Set Pl = Application.Union(Range("C29:C35"), Range("C37:C42")) 'définit la plage Pl
If Application.Intersect(Target, Pl) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage Pl, la macro sort de la procédure
If Target.Value = "" Then Exit Sub 'si la cellule est vide, la macro sort de la procédure
'Copie de la cellule de la plage dans la première colonne vide de la même ligne après la colonne L
MsgBox "Vos données vont être sauvegardées et vous allez pouvoir en renseigner d'autres du même type." & vbLf & vbLf & "Si vous n'avez pas d'autres informations de ce type à insérer, vous pouvez passer à la ligne suivante.", vbOKOnly + vbInformation, _
"InfosShop"
If Target.Value <> "" Then
Target.Value.Select
Selection.Copy
ActiveWindow.ScrollColumn = 2
ActiveWindow.ScrollColumn = 3
Range("N30").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
End If
End SubJe joins également mon fichier Test.
Merci d'avance pour votre aide.
Cordialement.
Bonjour,
je ne vois pas exactement comment adapter quelque chose comme "End(xlToLeft).Offset(0, 1)" à mon cas
Cells(Target.Row, Cells(Target.Row, Columns.Count).End(xlToLeft).Column + 1)?
eric
Bonjour Eric,
Merci pour la réponse, mais ça ne fonctionne pas avec ma macro.
En fait, voici le code que j'essaie vainement d'adapter à mon cas :
Private Sub Worksheet_Change(ByVal Target As Range)
Set Pl = Application.Union(Range("C29:C35"), Range("C37:C42")) 'définit la plage Pl
If Application.Intersect(Target, Pl) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage Pl, la macro sort de la procédure
If Target.Value = "" Then Exit Sub 'si la cellule est effacée, la macro sort de la procédure
si "Oui" au message copie la cellule de la plage dans la première colonne vide de la même ligne après la colonne L
If MsgBox(""Vos données vont être sauvegardées et vous allez pouvoir en renseigner d'autres du même type." & vbLf & vbLf & "Si vous n'avez pas d'autres informations de ce type à insérer, vous pouvez passer à la ligne suivante.", vbOKOnly + vbInformation, _
"InfosShop") = vbOK Then Cells(Target.Row, Application.Columns.Count).End(xlToLeft).Offset(0, 1).Value = Target.Value
With Target
.Select 'sélectionne la cellule modifiée
End With
End SubCe code fonctionne très bien, sauf que je suis obligé de cliquer dans la cellule concernée pour que la macro démarre. Or, ce que je cherche, c'est que la macro se déclenche sans clic (voir mon message de tout à l'heure).
Merci d'avance.
A +
Bonjour Eric,
Merci pour la réponse, mais ça ne fonctionne pas avec ma macro.
En fait, voici le code que j'essaie vainement d'adapter à mon cas :
Private Sub Worksheet_Change(ByVal Target As Range)
Set Pl = Application.Union(Range("C29:C35"), Range("C37:C42")) 'définit la plage Pl
If Application.Intersect(Target, Pl) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage Pl, la macro sort de la procédure
If Target.Value = "" Then Exit Sub 'si la cellule est effacée, la macro sort de la procédure
si "Oui" au message copie la cellule de la plage dans la première colonne vide de la même ligne après la colonne L
If MsgBox(""Vos données vont être sauvegardées et vous allez pouvoir en renseigner d'autres du même type." & vbLf & vbLf & "Si vous n'avez pas d'autres informations de ce type à insérer, vous pouvez passer à la ligne suivante.", vbOKOnly + vbInformation, _
"InfosShop") = vbOK Then Cells(Target.Row, Application.Columns.Count).End(xlToLeft).Offset(0, 1).Value = Target.Value
With Target
.Select 'sélectionne la cellule modifiée
End With
End SubCe code fonctionne très bien, sauf que je suis obligé de cliquer dans la cellule concernée pour que la macro démarre. Or, ce que je cherche, c'est que la macro se déclenche sans clic (voir mon message de tout à l'heure).
Merci d'avance.
A +
Tu es sur l'évènement Change, il faut modifier la cellule pour le déclencher.
Il ne se déclenchera jamais sur la colonne C, il n'y a pas de saisie. C'est la B que tu modifies et qu'il faut surveiller.
eric
Merci encore pour le temps que tu me consacres.
Mais, n'étant pas un pro des macros, je ne comprends pas tout !
D'après ce que je comprends, il faut que je remplace la colonne C par la colonne B, puisqu'effectectivement, c'est la colonne B qui change.
Si je te suis bien, je dois donc avoir :
Set Pl = Application.Union(Range("B29:B35"), Range("B37:B42"))Mais, dans ce cas, la macro va me recopier la valeur de la colonne B ?! Ou alors, il faut que je lui dise que si B change, il recopie la valeur de C ?! Mais, là, je suis un peu paumé. Peu-être faut-il changer quelque chose au niveau de
Cells(Target.Row, Application.Columns.Count).End(xlToLeft).Offset(0, 1).Value = Target.ValuePourrais-tu encore me consacrer encore de ton temps pour me mettre sur la voie ?
Merci d'avance.
Bien cordialement.
Avec la ligne de code suivante, tu définis la plage dont tu surveilles les modifications (B29:B32 et B34:B36 dans ton exemple)
Set Pl = Application.Union(Range("B29:B32"), Range("B34:B36"))
La cellule à copier est celle qui se trouve décalée d'une colonne par rapport à la cellule modifiée, soit
Target.Offset(0, 1)
Et enfin, pour trouver la colonne sur laquelle coller la donnée
Col = Cells(Target.Row, Columns.Count).End(xlToLeft).Column + 1
A+
Bonjour Frangy,
Merci pour ton aide.
J'ai fait ce que tu as dit, mais je ne sais pas où intégrer Target.Offset(0, 1).
Voici mon code :
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Pl As Range 'déclare la variable Pl (Plage)
Dim i, Col As Long
Set Pl = Application.Union(Range("B29:B35"), Range("B37:B42")) 'définit la plage Pl
If Application.Intersect(Target, Pl) Is Nothing Then Exit Sub 'si le changement a lieu ailleurs que dans la plage Pl, la macro sort de la procédure
If Target.Value = "" Then Exit Sub 'si la cellule est vide, la macro sort de la procédure
'Copie de la cellule de la plage dans la première colonne vide de la même ligne après la colonne L
MsgBox "Vos données vont être sauvegardées et vous allez pouvoir en renseigner d'autres du même type." & vbLf & vbLf & "Si vous n'avez pas d'autres informations de ce type à insérer, vous pouvez passer à la ligne suivante.", vbOKOnly + vbInformation, _
"InfoShop"
If Target.Value <> "" Then Col = Cells(Target.Row, Cells(Target.Row, Columns.Count).End(xlToLeft).Column + 1)
End SubPourrais-tu de nouveau m'aider et me dire précisément où je dois intégrer ce Target.Offset(0, 1) ?
Merci d'avance.
Cordialement.
J'en déduis que tu n'as pas ouvert le fichier que je t'ai envoyé
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Pl As Range 'déclare la variable Pl (Plage)
Dim i, Col As Long
If Target.Count > 1 Then Exit Sub
Set Pl = Application.Union(Range("B29:B32"), Range("B34:B36")) 'définit la plage Pl
If Not Application.Intersect(Target, Pl) Is Nothing And Target.Value <> "" Then 'si le changement a lieu ailleurs que dans la plage Pl, la macro sort de la procédure
'Copie de la cellule de la plage dans la première colonne vide de la même ligne après la colonne L
MsgBox "Vos données vont être sauvegardées et vous allez pouvoir en renseigner d'autres du même type." & _
vbLf & vbLf & "Si vous n'avez pas d'autres informations de ce type à insérer, vous pouvez passer à la ligne suivante.", _
vbOKOnly + vbInformation, "InfosShop"
Col = Cells(Target.Row, Columns.Count).End(xlToLeft).Column + 1
Target.Offset(0, 1).Copy
Cells(Target.Row, Col).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
End If
End SubA+
Re-,
Désolé, je n'avais pas vu que tu m'avais envoyé un fichier.
En tout cas, ça marche très bien ! C'est impeccable.
Merci beaucoup.
A +