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
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
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
hey i need same above coding for autocad vba for designing a connecting rod!! plss help
Kimbra,
Contact me directly via email (rod@envisioncad.com) to discuss your requirements.
Rod
Rod,
My problem is determining the OldScale. In my case the same scale has been placed in different models at different scales. I don’t want to manually determine the existing scale for each cell.
How can I do this with VBA?
Thanks,
Al
Sorry, I meant the same CELL has been placed in different models at different scales.
Al
Al
The VBA CellElement object has a Scale property that can be queried to get the scale of the cell. An example of how that might be used is shown below.
Sub test()
PrintCellScales “DTREE”
End Sub
Sub PrintCellScales(cellName As String)
Dim ee As ElementEnumerator
Dim es As ElementScanCriteria
Set es = New ElementScanCriteria
‘
‘ Set scan criteria to only find cells with
‘ supplied cellName
‘
With es
.ExcludeAllTypes
.IncludeType msdElementTypeCellHeader
.IncludeOnlyCell cellName
End With
Set ee = ActiveModelReference.Scan(es)
Do While ee.MoveNext
Debug.Print “Cell Name: ” & ee.Current.AsCellElement.Name
Debug.Print vbTab & “X Scale: ” & CStr(ee.Current.AsCellElement.Scale.X)
Debug.Print vbTab & “Y Scale: ” & CStr(ee.Current.AsCellElement.Scale.Y)
Debug.Print vbTab & “Z Scale: ” & CStr(ee.Current.AsCellElement.Scale.Z)
Loop
End Sub
I’m no longer positive where you’re getting your info, however good topic.
I must spend some time studying much more or understanding more.
Thank you for wonderful info I was in search of this information for
my mission.