VBA Macro Arguments

Published on October 1, 2012

Written by Rod Wing.

MicroStation VBA allows for supplying arguments in a macro call, most other VBA implementations including the Microsoft Office apps to do not support this feature. The arguments are stored as a single string in the application’s KeyinArguments property. Multiple arguments must be parsed by the program prior to use.

Using arguments to call a macro allows for much more flexibility, such as allowing for variable inputs for use in a Batch Process script. The following macro illustrates how arguments can be parsed. In the case of this macro all of the arguments must be separated by spaces.

vba run MacroWithArguments arg1 arg2 arg3

Sub MacroWithArguments()
Dim strArgs() As String
Dim i As Long
Dim iStart As Long
Dim iEnd As Long
If Len(KeyinArguments) > 0 Then
'
' Arguments separated by spaces
'
strArgs = Split(KeyinArguments, " ")
iStart = LBound(strArgs)
iEnd = UBound(strArgs)
For i = iStart To iEnd
Debug.Print strArgs(i)
Next
End If
End Sub

 

Here is an example of how this could be put to use. This PlaceCell macro will open a userform if no arguments are supplied. It also allows the arguments to be supplied in any order by using the command switches (-n, -s, -a, etc.)

 

Usage: vba run PlaceCell -n<cellName> -s<cellScale> -a<cellAngle> -x<xValue> -y<yValue> -z<zValue>

Sub PlaceCell()
Dim strArgs() As String
Dim i As Long
Dim iStart As Long
Dim iEnd As Long
Dim cellName As String
Dim cellScale As String
Dim cellAngle As String
Dim strSwitch As String
Dim x As String
Dim y As String
Dim z As String

 

'
' Set default values for arguments not supplied
'
cellName = ActiveSettings.cellName
cellScale = cStr(ActiveSettings.Scale.x)
cellAngle = cStr(Degrees(ActiveSettings.Angle))
x = "0"
y = "0"
z = "0"

 

If Len(KeyinArguments) = 0 Then
'
' No arguments - show user form
'
UserForm1.Show
Else
'
' Arguments supplied - run in batch mode
'
strArgs = Split(KeyinArguments, " ")
iStart = LBound(strArgs)
iEnd = UBound(strArgs)
For i = iStart To iEnd
strSwitch = Left$(strArgs(i), 2)
Select Case strSwitch
Case "-n"
cellName = Mid$(strArgs(i), 3)
Case "-s"
cellScale = Mid$(strArgs(i), 3)
Case "-a"
cellAngle = Mid$(strArgs(i), 3)
Case "-x"
x = Mid$(strArgs(i), 3)
Case "-y"
y = Mid$(strArgs(i), 3)
Case "-z"
z = Mid$(strArgs(i), 3)
End Select
Next

With CadInputQueue
.SendKeyin "active cell " & cellName
.SendKeyin "active scale " & cellScale
.SendKeyin "active angle " & cellAngle
.SendKeyin "place cell icon"
.SendDataPoint Point3dFromXYZ(CDbl(x), CDbl(y), CDbl(z))
End With
End If
End Sub

Tags:
Like this article? Share it!

2 Responses to “VBA Macro Arguments”

  1. Basti Says:

    September 22nd, 2013 at 9:29 pm

    I am really new in VBA in microstation. I cannot see any forum which discuss about cells already inserted to change in a different scale. for example “SectionTag” that’s been inserted in 1:50 scale and need to be re-scale to 1:75.. Could anyone please help me on this.. Thank you very much

  2. Rod Wing Says:

    September 23rd, 2013 at 10:13 am

    The method required to change the scale will be determined by you use of annotation scale. If you have placed the cells using annotation scale the VBA code would be to simply change the model’s annotation scale property like this….

    Sub ChangeAnnotationScale(NewScale As Double)
    ActiveModelReference.GetSheetDefinition.AnnotationScaleFactor = NewScale
    End Sub

    If the cells were not placed using annotation scale then you must calculate the scale difference, iterate through each cell, and modify its scale. Something like this…

    Sub ChangeCellScale(OldScale As Double, NewScale As Double)
    Dim elCell As CellElement
    Dim dScale As Double
    Dim ee As ElementEnumerator
    Dim es As ElementScanCriteria
    Dim elArray() As Element
    Dim i As Long
    Dim iStart As Long
    Dim iEnd As Long

    ‘Calculate change in scale
    dScale = NewScale / OldScale

    ‘Scan for all cells
    Set es = New ElementScanCriteria
    With es
    .ExcludeAllTypes
    .IncludeType msdElementTypeCellHeader
    End With

    Set ee = ActiveModelReference.Scan(es)

    elArray = ee.BuildArrayFromContents
    iStart = LBound(elArray)
    iEnd = UBound(elArray)

    ‘ iterate through all the cells and change the scale
    For i = iStart To iEnd
    Set elCell = elArray(i).AsCellElement
    elCell.ScaleUniform elCell.Origin, dScale
    elCell.Rewrite
    Next
    End Sub

    I hope this answers your question.
    Rod

Leave a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Privacy Policy