Undo mogelijk maken voor macro's in Excel VBA
Pagina's in dit artikel
Implementatie
De eerste stap die genomen moet worden is het kopiëren van de twee klasse modules uit de vorige twee bladzijden naar het project. Hoe deze twee klasse modules kunnen worden gebruikt staat hieronder beschreven.
Een eigenschap wijzigen en toevoegen aan de "undo stack"
Nu de twee klasse modules in het project staan is het tijd ze aan het werk te zetten. Het code fragment hieronder (geplaatst in een normale module) toont hoe een en ander in zijn werk gaat:
Option Explicit
Dim mUndoClass As clsExecAndUndo
Sub MakeAChange()
Dim i As Integer
If mUndoClass Is Nothing Then
Set mUndoClass = New clsExecAndUndo
Else
'Previous undoset, must be removed
Set mUndoClass = Nothing
Set mUndoClass = New clsExecAndUndo
End If
For i = 1 To 10
mUndoClass.AddAndProcessObject
ActiveSheet.Cells(i, 1), _
"Interior.Colorindex", 15
Next
Application.OnUndo "Restore colours A1:A10", "UndoChange"
End Sub
De routine hierboven controleert eerst of er nog een instantie van mUndoClass bestaat. Zo niet, dan wordt een nieuwe instantie geïnitialiseerd. Is er wel een instantie, dan zijn er twee mogelijkheden:
1. Verwijder de vorige Undo stack (hierboven getoond)
2. Bewaar de vorige undo set, zodat deze wijzigingen ook ongedaan gemaakt kunnen worden (verwijder alles tussen het Else....End If deel van de sub hierboven)
Wordt gekozen voor (1), dan kan in de beschrijving van het OnUndo statement gewoon beschrijven wat deze routine gewijzigd heeft. Wordt gekozen voor (2), denk er dan aan om de beschrijving van het OnUndo statement aan te passen.
Wees er wel op alert, dat als er tussen de vorige reeks wijzigingen en deze door de gebruiker zaken gewijzigd zijn, de vorige OnUndo door Excel uit de gebruikersinterface zal zijn verwijderd. Het uitvoeren van de VBA undo zal bovendien eventuele handmatige wijzigingen die zijn uitgevoerd na de VBA wijzigingen uit de undo stack laten verdwijnen. Deze kunnen dus NIET meer ongedaan worden gemaakt.
Zoals te zien is, is de syntaxis die nodig is om de techniek te gebruiken niet heel praktisch, omdat de eigenschap die moet worden gewijzigd als een string moet worden ingevoerd, hetgeen intellisense onmogelijk maakt. Helaas is dit de prijs die wordt betaald om een Undo routine werkend te krijgen via deze techniek.
Heeft u ideeën over een betere methode, laat dat dan via het commentaar veld hieronder even weten!
Ongedaan maken
De routine die is ingesteld om te worden uitgevoerd bij het intikken van control-z wordt hieronder getoond. Deze maakt alle wijzigingen ongedaan die in de variabele mUndoClass zijn bijgehouden.
Sub UndoChange()
If mUndoClass Is Nothing Then Exit Sub
mUndoClass.UndoAll
Set mUndoClass = Nothing
End Sub
Een tweede routine die wordt getoond maakt slechts de laatste actieongedaan:
Sub UndoStepwise()
If mUndoClass Is Nothing Then Exit Sub
mUndoClass.UndoLast
If mUndoClass.UndoCount = 0 Then
MsgBox "Last action undone"
Set mUndoClass = Nothing
End If
End Sub
De routine merkt ook wanneer de laatste actie uit de lijst ongedaan is gemaakt en als dat het geval is, wordt een berichtje getoond en wordt de mUndoClass variable leeg gemaakt.