vba Excel : enregistrement de valeures - VB/VBA/VBS - Programmation
Marsh Posté le 24-07-2006 à 15:26:08
ton bout de programme plante-t-il ? qu'attends-tu de ce topic ? Doit-on optimiser ton code, le débugger ?
Marsh Posté le 24-07-2006 à 16:38:01
bonjour,
ce programme bug parce que à chaque fois que tu changes une valeur
Cells(iy + 1, ix) = ...
Cells(1, 3) =...
...cela appelle la procédure Change de manière récursive et il n'y a aucune possibilité de sortir de la sub
A+
Marsh Posté le 24-07-2006 à 16:40:13
Il dit quoi comme plantage ?
Le worksheet_change est activé lorsque tu entres dans une cellule. La Target correspond à la nouvelle cellule sélectionné, tu n'a plus la dernière.
Tu peux entrer dans une cellule et en sortir sans rien changer, le worksheet_change va se déclencher. Je ne suis pas sûr que ce soit ca que tu cherches.
Marsh Posté le 24-07-2006 à 16:56:32
Je n'avais pas vu la réponse de Galopin ...
si tu veux mettre à jour ta cellule tout en conservant la fonction change tu peux utiliser la variable
Application.EnableEvents = False
avant la mise à jour de la cellule et une fois celle-ci fait remettre
Application.EnableEvents = True
En fait Application.EnableEvents = False permet de désactiver la gestion evenementielle.
Marsh Posté le 24-07-2006 à 17:25:48
j'ai avancé dans mon code, maintenant ça fonctionne avec le code suivant:
Sub worksheet_change(ByVal target As Range)
If target.Address = "$D$2" _
Or target.Address = "$E$2" _
Or target.Address = "$F$2" _
Or target.Address = "$G$2" _
Or target.Address = "$H$2" _
Or
target.Address = "$I$2" _
Or target.Address = "$J$2" _
Or target.Address = "$K$2" _
Or target.Address = "$L$2" _
Or target.Address = "$M$2" _
Or target.Address = "$N$2" _
Or target.Address = "$O$2" _
Or target.Address = "$P$2" _
Or target.Address = "$Q$2" _
Or target.Address = "$R$2" _
Or target.Address = "$S$2" _
Or target.Address = "$T$2" _
Or target.Address = "$U$2" Then
Nbr_Val = 42 'Nombres de valeures sauvegardées
If iy < 2 Then 'Test pour que iy reste entre 2 et Nbr_Val
iy = 2
ElseIf iy = Nbr_Val Then
iy = 2
End If
For ix = 2 To Nbr_Var 'Boucle For pour faire toutes les variables
Cells(iy + 2, ix) = Cells(2, ix) 'Recopie valeur
Next
iy = iy + 1 'Incrémentation compteur valeurs
Range("B2" ).Value = Now 'affichage de la date et de l'heure
Cells(2, 3) = (iy) - 1 'affichage de l'index iy sur la feuille
End If
End Sub
par contre, est-ce-que quelqu'un peut me dire comment simplifier l'équation avec les OR
OR
OR
OR.....
Marsh Posté le 24-07-2006 à 17:29:27
une boucle for fera l'affaire, par contre, d'ou sors tu tes iy ?
Marsh Posté le 24-07-2006 à 17:38:05
If Not Application.Intersect(Target, Range("D2:U2" )) Is Nothing Then
MsgBox "Ton code ici"
End If
Marsh Posté le 25-07-2006 à 10:23:53
Le seul problème c'est que tu ne sais s'il a changé la valeur mais seulement s'il est entré dans la celulle (touche F2) et resorti. Tu risque de conserver des données identiques si tu ne fais pas de test.
A chaque fois qu'une valeur est modifiée tu sauves toutes la ligne sur une nouvelle ligne ?
Marsh Posté le 25-07-2006 à 10:31:54
Oui, il faut qu'à chaque foi qu'une valeur est modifiée je sauvegarde toute la ligne.
Mais tu a raison, ce serait mieux si je pouvai tester directement les valeure qui sont dans mes cellules de départ. j'ai fait quelques essais en ajoutant des ".value", mais je n'y arrive pas.
il faudrait utiliser une autre instruction que "Taret.address", mais comme je débute en VBA, je n'en connai pas.
est-ce que quelqu'un peut m'aider???
Marsh Posté le 25-07-2006 à 10:45:45
Ce que tu peux faire c'est copier ta ligne 2 sur une autre ligne (par ex 65536).
Quand ta procédure "change" se déclenche, compare les données de ta ligne2 (target.value) avec celle de la ligne 65536 (cells(65536,target.column). Si il y a une différence tu copies ta ligne2 en ligne iy+2 et après tu copies la cellule de la ligne 2 en ligne 65536.
C'est plus claire ?
Marsh Posté le 25-07-2006 à 10:56:34
oui, je vois ce que tu veux dire.
Mais est ce que tu as le temps de m'écrire un exemple?
Marsh Posté le 25-07-2006 à 11:09:02
il faut que je détecte un changement de valeure sur ma première ligne, donc, il faudrait que je la recopie en permanence vers 65536?
Marsh Posté le 25-07-2006 à 11:25:14
Cgplaco a écrit : oui, je vois ce que tu veux dire. |
Rapidement...a tester !!!!
Dans ton ThisWorkbook
Private Sub Workbook_Open()
Sheet("Feuil1" ).Range("D2:U2" ).Copy Sheet("Feuil1" ).Range("D65536:U65536" )
End Sub
Dans ta feuille ("Feuil1" )
Private Sub Worksheet_Change(ByVal Target As Range)
application.enabledevents=false
If Not Application.Intersect(Target, Range("D2:U2" )) Is Nothing Then
If Target.Value <> Cells(65536, Target.Column).Value Then
Sheet("Feuil1" ).Range("D2:U2" ).Copy Sheet("Feuil1" ).Range("D" & iy & ":U" & iy)
Cells(65536, Target.Column) = Target.Value
iy = iy + 1
End If
End If
application.enabledevents=true
End Sub
Marsh Posté le 25-07-2006 à 14:03:20
J'ai fait l'essais, mais je n'arrive pas à faire fonctionner ce code.
Je poursuit mes recherches, peut être que je ne suis pas parti dans la bonne direction au départ.
Si quelqu'un à une idée, elle sera la bienvenue.
Marsh Posté le 25-07-2006 à 14:11:41
Cgplaco a écrit : J'ai fait l'essais, mais je n'arrive pas à faire fonctionner ce code. |
Il faut que tu initialises ton iy, je ne sais pas où tu vas le chercher.
Chez moi le code suvant fonctionne
Private Sub Worksheet_Change(ByVal Target As Range)
Dim iy as Integer
Application.EnableEvents = False
iy= Sheets("Feuil1" ).cells(1,3).value
If Not Application.Intersect(Target, Range("D2:U2" )) Is Nothing Then
If Target.Value <> Cells(65536, Target.Column).Value Then
Sheets("Feuil1" ).Range("D2:U2" ).Copy Sheets("Feuil1" ).Range("D" & iy & ":U" & iy)
Sheets("Feuil1" ).Cells(65536, Target.Column).Value = Target.Value
iy = iy + 1
Sheets("Feuil1" ).cells(1,3).value=iy
End If
End If
Application.EnableEvents = True
End Sub
Mais tu peux sûrement faire autrement ...
edit : j'ai mis iy dans la cellule(1,3) "C1"
Marsh Posté le 25-07-2006 à 14:13:00
Private Sub Workbook_Open()
Sheet("Feuil1" ).Range("D2:U2" ).Copy Sheet("Feuil1" ).Range("D65536:U65536" ).Paste
End Sub
ca devrait déjà etre plus intéressant
Marsh Posté le 25-07-2006 à 14:16:47
jpcheck a écrit : Private Sub Workbook_Open() |
ca marche aussi sans le paste !! (humour !)
En cas de doute tu peux directement mettre dans tes cellules sous excel
D65536 : =D2; E65536 : =E2; etc ..
Marsh Posté le 24-07-2006 à 15:17:30
Bonjour, je débute en VBA et j'ai un projet à réaliser avec Excel,
Pour ce projet, je reçcoi des valeures dans des cellules Excel : C1 à U1
il faut qu'à chaque changement de valeure dans une des cellules, j'historise la valeure précédente.
Il faut donc que à chaque changement, je copie les valeures des cellules C1 à U1 sur les lignes suivantes
(C2 à U2, puis C3 à U3, puis C4 à U4, puis C5 à U5....)
Sub worksheet_change(ByVal target As Range)
If target.Address = "$A$2" Then Nbr_Var = 21 'Nombre de variables
Nbr_Val = 42 'Nombres de valeures sauvegardées
If iy < 2 Then 'Test pour que iy reste entre 2 et Nbr_Val
iy = 2
ElseIf iy = Nbr_Val Then
iy = 2
End If
For ix = 2 To Nbr_Var 'Boucle For pour faire toutes les variables
Cells(iy + 1, ix) = Cells(1, ix) 'Recopie valeur
Next
iy = iy + 1 'Incrémentation compteur valeurs
Cells(1, 3) = (iy) - 1 'affichage de l'index iy sur la feuille
End Sub