Undo mogelijk maken voor macro's in Excel VBA

Pagina's in dit artikel

  1. Klasse Modules (1)
  2. Klasse Modules (2)
  3. Implementatie
  4. Conclusie

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.