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.
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.
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.
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.