Questions similar to this appear on the Be Community Forums. This problem appeared in the VBA discussion group.

Q  Sometimes you want to group multiple operations, so that a MicroStation operator can use the Edit|Undo and Edit|Redo commands. Unfortunately, MicroStation VBA doesn't provide an Undo or Redo method, so we have to borrow one from MDL.

Group Operations

A  Use MDL's mdlUndo_startGroup and mdlUndo_endGroup to bracket a sequence of operations. If the sequence is bracketted, then a MicroStation user can undo the entire sequence using menu Edit|Undo. To use MDL functions in VBA, we must first declare them. The declaration informs the VBA compiler where the function is to be found and its formal parameter list …

'	MDL function declarations
Declare Sub mdlUndo_startGroup Lib "stdmdlbltin.dll" ()
Declare Sub mdlUndo_endGroup Lib "stdmdlbltin.dll" ()

To make the functions easy to call from VBA, put them in their own module and provide a public VBA procedure that calls the MDL function …

Public Sub StartUndoGroup()
    mdlUndo_startGroup
End Sub
Public Sub EndUndoGroup()
    mdlUndo_endGroup
End Sub

Now, if you have some VBA code that performs an number of element manipulation or creation operations, wrap them in StartUndoGroup … EndUndoGroup calls …

Sub SequenceOfUndoableOperations ()
	StartUndoGroup
	 … 
	'	Create or modify multiple elements
	 … 
	EndUndoGroup
End Sub

Now you'll find that MicroStation's Edit|Undo works with your code. The user can undo the work performed by procedure SequenceOfUndoableOperations.

There's a slight snag with the above suggestion: there is no command associated with the Edit|Undo menu. For instance, if you use one of MicroStation's commands, such as place line, you will see that the menu is modified to Edit|Undo Place Line. To see how to modify the menu, see the Command Name section.

Command Name

A  You can provide a command name to MicroStation from your VBA code by calling MDL function mdlState_setCurrentCommandName. When you provide a command name, it becomes available for example in the Edit|Undo menu. To use an MDL function in VBA, we must first declare it. The declaration informs the VBA compiler where the function is to be found and its formal parameter list …

'	MDL function declarations
'	The following function was introduced with MicroStation v8.9.2
Declare Sub mdlState_setCurrentCommandName Lib "stdmdlbltin.dll" (ByVal newName As Long)

Using mdlState_setCurrentCommandName is a little tricky, because it wants a Unicode string. For reasons not covered here, we inform VBA that this function wants Unicode using the undocumented VB StrPtr function …

Public Sub SetCurrentCommandName(ByVal commandName As String)
	'	StrPtr() tells VBA to pass Unicode string to MDL
	mdlState_setCurrentCommandName StrPtr(commandName)
End Sub

You can use this function in conjunction with Group Operations. If you start an undo group and set the command name, then your command appears in MicroStation's Edit|Undo menu.

Group Undo MyCommand

Here's the code to make that happen …

Public Sub StartUndoGroup(Optional ByVal commandName As String)
    If Not IsMissing(commandName) Then mdlState_setCurrentCommandName StrPtr(commandName)
    mdlUndo_startGroup
End Sub

Note: mdlState_setCurrentCommandName became available with MicroStation v8.9.2, meaning you can't use it with MicroStation V8 2004 Edition or earlier.