How to make a macro "atomic"
For those who prefer JavaScript for writing OOo macros, here is the minimum snippet that should work (it was tested, but I isolated this code from more context):
importClass( Packages.com.sun.star.document.XUndoManager );
importClass( Packages.com.sun.star.document.XUndoManagerSupplier );
var doc = XSCRIPTCONTEXT.getDocument();
var undo_manager = UnoRuntime.queryInterface(XUndoManagerSupplier, doc).getUndoManager();
undo_manager.enterUndoContext( 'your descriptive title here' );
// get stuff done
undo_manager.leaveUndoContext();
a source to share
In Word, this can be achieved by adding a bookmark to the document at the beginning of the macro, which is then removed when the macro is run. When "Undo" is called, the presence of such a special bookmark is checked, and the undo operation is repeated until the special bookmark is removed from the document.
I assume a similar approach will work with OpenOffice.org as well.
See Can I create an undo transaction in Word or Excel? (VSTO) for more details.
a source to share
You can talk to UndoManager by calling enterUndoContext()
at the very beginning of your macro and then leaveUndoContext()
at the end. For instance:
Dim undo As Object
undo = ThisComponent.UndoManager
undo.enterUndoContext("MyAtomicTest")
...
[YOUR COMPLEX OPERATIONS HERE]
...
undo.leaveUndoContext
This creates an atom undo operation that appears to the user as "MyAtomicTest".
a source to share
Starting in 2018 (Office 365) the solution from Undo VBA Code Cancellation in One Step is fine. Also saw the same solution on Microsoft site, but I can't find this link now.
Sub YourMacroName
Dim objUndo As UndoRecord
Set objUndo = Application.UndoRecord
objUndo.StartCustomRecord ("Your unique string - e.g. the macro name")
' your multi-step macro goes here
objUndo.EndCustomRecord
End Sub
a source to share