52 votes

Comment obtenir l'ancienne valeur d'une cellule modifiée dans Excel VBA ?

Je détecte des changements dans les valeurs de certaines cellules dans une feuille de calcul Excel comme celle-ci...

 Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Dim old_value As String
Dim new_value As String

For Each cell In Target

    If Not (Intersect(cell, Range("cell_of_interest")) Is Nothing) Then
        new_value = cell.Value
        old_value = ' what here?
        Call DoFoo (old_value, new_value)
    End If

Next cell

End Sub

En supposant que ce ne soit pas une trop mauvaise façon de coder cela, comment puis-je obtenir la valeur de la cellule avant le changement?

60voto

binil Points 3504

essaye ça

déclarer une variable dire

 Dim oval

et dans l'événement SelectionChange

 Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oval = Target.Value
End Sub

et dans votre ensemble d'événements Worksheet_Change

 old_value = oval

33voto

RonnieDickson Points 690

Vous pouvez utiliser un événement sur le changement de cellule pour déclencher une macro qui effectue les opérations suivantes :

 vNew = Range("cellChanged").value
Application.EnableEvents = False
Application.Undo
vOld = Range("cellChanged").value
Range("cellChanged").value = vNew
Application.EnableEvents = True 

13voto

Matt Roy Points 194

Je devais le faire aussi. J'ai trouvé la solution de "Chris R" vraiment bonne, mais j'ai pensé qu'elle pourrait être plus compatible en n'ajoutant aucune référence. Chris, vous avez parlé d'utiliser Collection. Voici donc une autre solution utilisant Collection. Et ce n'est pas si lent, dans mon cas. De plus, avec cette solution, en ajoutant l'événement "_SelectionChange", cela fonctionne toujours (pas besoin de workbook_open).

 Dim OldValues As New Collection

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    'Copy old values
    Set OldValues = Nothing
    Dim c As Range
    For Each c In Target
        OldValues.Add c.Value, c.Address
    Next c
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    On Local Error Resume Next  ' To avoid error if the old value of the cell address you're looking for has not been copied
    Dim c As Range
    For Each c In Target
        Debug.Print "New value of " & c.Address & " is " & c.Value & "; old value was " & OldValues(c.Address)
    Next c
    'Copy old values (in case you made any changes in previous lines of code)
    Set OldValues = Nothing
    For Each c In Target
        OldValues.Add c.Value, c.Address
    Next c
End Sub

11voto

Nick Points 2321

J'ai une solution alternative pour vous. Vous pouvez créer une feuille de calcul masquée pour conserver les anciennes valeurs de votre plage d'intérêt.

 Private Sub Workbook_Open()

Dim hiddenSheet As Worksheet

Set hiddenSheet = Me.Worksheets.Add
hiddenSheet.Visible = xlSheetVeryHidden
hiddenSheet.Name = "HiddenSheet"

'Change Sheet1 to whatever sheet you're working with
Sheet1.UsedRange.Copy ThisWorkbook.Worksheets("HiddenSheet").Range(Sheet1.UsedRange.Address)

End Sub

Supprimez-le lorsque le classeur est fermé...

 Private Sub Workbook_BeforeClose(Cancel As Boolean)

Application.DisplayAlerts = False
Me.Worksheets("HiddenSheet").Delete
Application.DisplayAlerts = True

End Sub

Et modifiez votre événement Worksheet_Change comme ceci ...

 For Each cell In Target

    If Not (Intersect(cell, Range("cell_of_interest")) Is Nothing) Then
        new_value = cell.Value
        ' here's your "old" value...
        old_value = ThisWorkbook.Worksheets("HiddenSheet").Range(cell.Address).Value
        Call DoFoo(old_value, new_value)
    End If

Next cell

' Update your "old" values...
ThisWorkbook.Worksheets("HiddenSheet").UsedRange.Clear
Me.UsedRange.Copy ThisWorkbook.Worksheets("HiddenSheet").Range(Me.UsedRange.Address)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X