I am trying to fix a leader line macro that was built 5 years ago in microstation, I put the code below and some images, can someone please help me?
'*************************************************************************
'**
'** LEADER.UCM
'**
'** Procedure to draw both detail and index leader lines
'** with either index numbers or detail letter boxes.
'** also made graphic group.
'**
'** AUTHOR: L.G. YEATES
'** -------
'**
'** MODIFIED:
'** ---------
'** july 1989 position the index number in line
'** with the arrow head and leader line
'** sept 1989 corrected problem with the index number
'** for 2 digit numbers and larger with the
'** starting position of the line
'** sept 1989 corrected to allow upper and lower
'** case inputs by users
'** dec 1989 corrected to allow leader line to be
'** put in at active angle
'** jan 1990 corrected problem with detail letter,
'** so it is put in font 42
'**
'**
'** oct 1990 modified for MicroStation use. (LGY)
'** 02-21-91 Changed color. (LGY)
'** 03-20-91 Made Graphic Group (LGY)
'** 10-03-91 Made "I"ndex the default.
'** 05-08-92 Fixed bugs with default selection "I".
'** 07-17-92 Changed cell library attachment from
'** "tut1" to "tut5".
'** 05-28-93 added saving active symbology.
'** 07-22-93 added turning off axis lock during execution
'** of this UCM if turned on.
'** 01-13-94 changed "detail" option for selection
'** of either Clear/Filled Letter.
'**
'*************************************************************************
Option Explicit
Dim saveActiveTextJustification As Integer
Dim saveActiveTextNodeJustification As Integer
Dim saveActiveAngle As Double
Dim saveActiveLevel As Level
Dim saveActiveFont As Font
Dim saveActiveCharHeight As Integer
Dim SaveActiveCharWidth As Integer
Dim saveActiveLineStyle As LineStyle
Dim saveActiveColor As Long
Dim saveActiveWeight As Integer
Dim myCIQ As CadInputQueue
Dim myCIM As CadInputMessage
Dim response As String
Sub Main()
SetUp
LeaderType
End Sub
Sub SetUp()
CadInputQueue.SendCommand "null"
CadInputQueue.SendKeyin "noecho"
CommandState.ErrorMessagesEnabled = False
'SET OUTFLG = OUTFLG ! 8 ;allow menu selection
' Save Active Settings
saveActiveTextJustification = ActiveSettings.TextStyle.Justification
saveActiveTextNodeJustification = ActiveSettings.TextStyle.NodeJustification
saveActiveAngle = ActiveSettings.Angle
Set saveActiveLevel = ActiveSettings.Level
Set saveActiveFont = ActiveSettings.Font
saveActiveCharHeight = ActiveSettings.TextStyle.Height
SaveActiveCharWidth = ActiveSettings.TextStyle.Width
Set saveActiveLineStyle = ActiveSettings.LineStyle ' save active symbology
saveActiveColor = ActiveSettings.Color ' save active symbology
saveActiveWeight = ActiveSettings.LineWeight ' save active symbology
' Turn off fast font (bit 1)
' Turn on slow font (bit 2)
'Does not work.
' Turn off text node lock (bit 2)
ActiveSettings.TextNodeLockEnabled = False
' Not recommended by Microststation, but this was in original UCM
' and it allows illustrator to ignore the prompt to enter data
' and place a datapoint instead.
CadInputQueue.SendKeyin "set parse off"
' Turn off axis lock SET FBFDCN = FBFDCN & 65531
CadInputQueue.SendKeyin "lock axis off"
' Setup parameters for user command
CadInputQueue.SendKeyin "TS=1" 'active terminator scale
CadInputQueue.SendKeyin "AA=0" 'active angle"
CadInputQueue.SendKeyin "AS=1" 'active scale"
' Start user command prompting
' LEADER:
'
End Sub
Sub LeaderType()
Dim index As Boolean
Dim response As String
response = ""
index = True
Do
ShowStatus ""
ShowError ""
ShowCommand "LEADER LINE User Command (Graphic Group)"
' TOP:
ShowPrompt "Select Type I)ndex or D)etail: [I]"
'GET K,INPUT,R,EXITUC,M,SLI,P,AGAIN
Set myCIQ = CadInputQueue
Set myCIM = myCIQ.GetInput(msdCadInputTypeKeyin, msdCadInputTypeReset, _
msdCadInputTypeCommand, msdCadInputTypeDataPoint)
Select Case myCIM.InputType
Case msdCadInputTypeReset
ResetVals
Exit Sub
Case msdCadInputTypeDataPoint
If (response = "D") Or (response = "d") Then
index = False
Else
index = True
End If
CreateLineWithTerminator (index)
Case msdCadInputTypeCommand
ResetVals
Exit Sub
Case msdCadInputTypeKeyin
response = myCIM.Keyin
'Set n10 = 3
'tst c10 eq 'UC=',SLI
If (response = "D") Or (response = "d") Then
index = False
ElseIf (response = "I") Or (response = "i") Then
index = True
Else
MsgBox "Invalid Entry, Please try again."
Exit Do
End If
CreateLineWithTerminator (index)
End Select 'I)ndex or D)etail
Loop
End Sub
Sub CreateLineWithTerminator(index As Boolean)
Do
SetUp
Dim myCIQ As CadInputQueue
Dim myCIM As CadInputMessage
Dim clearOrFilled As String
Dim detailLetter As String
Dim arrowPoint As Point3d
Dim termPoint As Point3d
Dim myLine As LineElement
CadInputQueue.SendKeyin "TS=1" 'active terminator scale
ShowStatus ""
ShowError ""
ShowPrompt ""
CadInputQueue.SendKeyin "WT=0" 'set active weight
CadInputQueue.SendKeyin "CO=1" 'set active color
If index = False Then
CadInputQueue.SendKeyin "LT=BARRO" 'line terminator assignment
ShowCommand "DETAIL ARROW User Command (Graphic Group)"
Else
CadInputQueue.SendKeyin "LT=LARRO"
ShowCommand "INDEX ARROW User Command (Graphic Group)"
End If
CadInputQueue.SendKeyin "rc=tut5.cel"
CadInputQueue.SendCommand "Place Line"
ShowPrompt "Enter Arrowhead Point"
Set myCIQ = CadInputQueue
Set myCIM = myCIQ.GetInput(msdCadInputTypeDataPoint, msdCadInputTypeReset, _
msdCadInputTypeKeyin, msdCadInputTypeCommand)
'GET P,FIRST,R,LEADER,M,SLI,K,SLI
Select Case myCIM.InputType
Case msdCadInputTypeReset 'Re-enter "D" or "I"
Exit Sub
Case msdCadInputTypeKeyin
ResetVals
Exit Sub
Case msdCadInputTypeCommand
ResetVals
Exit Sub
Case msdCadInputTypeDataPoint
CadInputQueue.SendCommand "Place Line"
arrowPoint = myCIM.point
CadInputQueue.SendDataPoint arrowPoint
ShowPrompt "Enter Terminator Point"
ShowError ""
End Select 'Enter Terminator Point
'GET P,PLACE,R,LEADER,M,SLI,K,SLI
Set myCIM = myCIQ.GetInput(msdCadInputTypeDataPoint, _
msdCadInputTypeReset, msdCadInputTypeKeyin, msdCadInputTypeCommand)
Select Case myCIM.InputType
Case msdCadInputTypeReset
CadInputQueue.SendCommand "null"
ShowPrompt ""
Exit Sub 'Re-enter "D" or "I"
Case msdCadInputTypeKeyin
CadInputQueue.SendCommand "null"
ShowPrompt ""
ResetVals
Case msdCadInputTypeCommand
CadInputQueue.SendCommand "null"
ShowPrompt ""
ResetVals
Case msdCadInputTypeDataPoint
ShowError ""
termPoint = myCIM.point
CadInputQueue.SendKeyin "lv=10"
CadInputQueue.SendKeyin "CO=1"
Set myLine = CreateLineElement2(Nothing, arrowPoint, termPoint)
ActiveModelReference.AddElement myLine
CadInputQueue.SendCommand "Place Terminator"
CadInputQueue.SendDataPoint arrowPoint
CadInputQueue.SendDataPoint arrowPoint
CadInputQueue.SendCommand "null"
End Select 'Enter Arrowhead Point
Dim ang As Double
ang = GetAngleOfLineBetweenTwoPoints(termPoint, arrowPoint)
If index = False Then 'Detail
ProcessDetail termPoint, arrowPoint, ang
Else
ProcessIndex termPoint, arrowPoint, ang
End If
Loop
End Sub
Sub ProcessIndex(termPoint As Point3d, arrowPoint As Point3d, ang As Double)
Dim indexNumber As String
ShowPrompt "Enter Index Nunber"
'GET K,LLETTER,R,INDEX,M,SLI
Set myCIM = myCIQ.GetInput(msdCadInputTypeDataPoint, _
msdCadInputTypeReset, msdCadInputTypeKeyin, msdCadInputTypeCommand)
Select Case myCIM.InputType
Case msdCadInputTypeKeyin
indexNumber = myCIM.Keyin
End Select 'Enter Index Number
' Calculate the position for placement
' of the index number
Dim newLocation As Point3d
newLocation = GetNewLocation(termPoint, arrowPoint, ang)
'PTEXT:
' define font and character height for index number
'CadInputQueue.SendKeyin "active txj cc" 'center-center text justification
'CadInputQueue.SendKeyin "active tnj cc" 'active text node justification
CadInputQueue.SendKeyin "ft=2"
CadInputQueue.SendKeyin "tx=.10"
CadInputQueue.SendKeyin "lv=48"
Dim oEL As TextElement
Dim textOrigin As Point3d
Dim textNote As String
textNote = indexNumber
'Set oEL = CreateTextElement1(Nothing, textNote, textOrigin, Matrix3dIdentity)
Set oEL = CreateTextElement1(Nothing, textNote, newLocation, Matrix3dIdentity)
oEL.TextStyle.Justification = msdTextJustificationCenterCenter
oEL.TextStyle.Color = 5
ActiveModelReference.AddElement oEL
CadInputQueue.SendCommand "ADD TO GRAPHIC GROUP"
CadInputQueue.SendDataPoint arrowPoint
CadInputQueue.SendDataPoint newLocation
CadInputQueue.SendDataPoint newLocation
CadInputQueue.SendCommand "null"
'do another
End Sub
Sub ProcessDetail(termPoint As Point3d, arrowPoint As Point3d, ang As Double)
Const halfDeltaX = 0.12
Const halfDeltaY = 0.16
Const deltaX = 0.24
Const deltaY = 0.32
Dim detailType As String
Dim clear As Boolean
Dim detailLetter As String
clear = True
ShowPrompt "Select type C)lear or F)illed: [C]"
'GET K,TYPED,R,DETAIL,M,SLI,P,AGAIN1
Set myCIQ = CadInputQueue
Set myCIM = myCIQ.GetInput(msdCadInputTypeDataPoint, _
msdCadInputTypeReset, msdCadInputTypeKeyin, msdCadInputTypeCommand)
Select Case myCIM.InputType
Case msdCadInputTypeReset 'ProcessDetail
Case msdCadInputTypeDataPoint ' Test for C)lear or F)illed.
Case msdCadInputTypeCommand 'Exit Program
ResetVals
Exit Sub
Case msdCadInputTypeKeyin
'msg 'er'
detailType = myCIM.Keyin
'tst c10 eq 'UC=',SLI
If (detailType = "F") Or (detailType = "f") Then
clear = False
ElseIf (detailType = "C") Or (detailType = "c") Then
clear = True
Else
MsgBox ("Invalid Entry, Please try again")
Exit Sub
End If
End Select 'C)lear or F)illed
ShowPrompt "Enter Detail Letter"
'GET K,DLETTER,R,TYPED,M,SLI
Set myCIM = myCIQ.GetInput(msdCadInputTypeDataPoint, _
msdCadInputTypeReset, msdCadInputTypeKeyin, msdCadInputTypeCommand)
Select Case myCIM.InputType
Case msdCadInputTypeReset
Case msdCadInputTypeCommand
Case msdCadInputTypeDataPoint
Case msdCadInputTypeKeyin
detailLetter = myCIM.Keyin
End Select 'Enter Detail Letter
'Assign the deltas and half deltas for placement
' of the detail box
' DETAIL LETTER TEST
' Test for angle of the arrow line
' then add the appropriate deltas
' for the CELL placement.
'TST A8 GT 360,EXITUC
Dim LTDegrees As Double
Dim halfDelta As Double
Dim completeLetter As String
If (ang > 360) Then
Exit Sub
ElseIf (ang <= 45) Then 'Left
LTDegrees = termPoint.X
halfDelta = termPoint.Y - halfDeltaY
ElseIf (ang <= 135) Then 'Bottom
LTDegrees = termPoint.X - halfDeltaX
halfDelta = termPoint.Y
ElseIf (ang <= 225) Then 'Right
LTDegrees = termPoint.X - deltaX
halfDelta = termPoint.Y - halfDeltaY
ElseIf (ang <= 315) Then 'Topp
LTDegrees = termPoint.X - halfDeltaX
halfDelta = termPoint.Y - deltaY
End If
CadInputQueue.SendKeyin "RC=tut10.cel" 'attach cell library
'CadInputQueue.SendKeyin "co = 1"
If clear = True Then
completeLetter = "det"
Else 'filled
completeLetter = "dltr"
End If
completeLetter = completeLetter + detailLetter
completeLetter = "ac=" + completeLetter
CadInputQueue.SendKeyin completeLetter
Dim letterPoint As Point3d
letterPoint.X = LTDegrees
letterPoint.Y = halfDelta
CadInputQueue.SendDataPoint letterPoint
' CadInputQueue.SendCommand "GROUP ADD"
'CadInputQueue.SendDataPoint arrowPoint
'CadInputQueue.SendDataPoint letterPoint
' CadInputQueue.SendDataPoint letterPoint
CadInputQueue.SendCommand "null"
End Sub
' Determines the angle of a straight line drawn between point one and two.
' The number returned, which is a float in degrees, tells us how much we have
' to rotate a horizontal line clockwise for it to match the line between the
' two points.
Function GetAngleOfLineBetweenTwoPoints(point1 As Point3d, point2 As Point3d) As Double
Dim xDiff As Double
Dim yDiff As Double
xDiff = point2.X - point1.X
yDiff = point2.Y - point1.Y
If xDiff <> 0 Then
GetAngleOfLineBetweenTwoPoints = Atn(yDiff / xDiff) * (180 / Pi())
'GetAngleOfLineBetweenTwoPoints = Atn2(yDiff, xDiff) * (180 / Pi())
Else
GetAngleOfLineBetweenTwoPoints = 0
End If
End Function
Function GetNewLocation(termPoint As Point3d, arrowPoint As Point3d, ang)
Dim distEndLineToCtr As Double
Dim sinByDist As Double
Dim cosByDist As Double
Dim xLoc As Double
Dim yLoc As Double
Dim newLoc As Point3d
Dim deltaOfXPoints As Double
Dim deltaOfYPoints As Double
Dim sumSquares As Double
Dim sinAngle As Double
Dim cosAngle As Double
Dim hypotenuse As Double
Dim cosByDistTest As Double
Dim sinByDistTest As Double
Dim newLocation As Point3d
distEndLineToCtr = 0.1 'distance from the end of the line
'to the center of the index number
' Test number of characters to determine if extra space is needed
' in the positioning of the leader line for index numbers
' along the x-axis
deltaOfXPoints = termPoint.X - arrowPoint.X 'deltaOfXPoints = delta x
deltaOfYPoints = termPoint.Y - arrowPoint.Y 'deltaOfYPoints = delta y
sumSquares = (deltaOfXPoints * deltaOfXPoints) + (deltaOfYPoints * deltaOfYPoints) 'Calculate length of hypotenuse
hypotenuse = Sqr(sumSquares)
sinAngle = deltaOfYPoints / hypotenuse
cosAngle = deltaOfXPoints / hypotenuse
'If "distEndLineToCtr" is >= 2, skip the Fudge Factor.
If ((ang <= 45) Or (ang > 135 And ang <= 225)) And (distEndLineToCtr < 2) Then
distEndLineToCtr = distEndLineToCtr * 1
distEndLineToCtr = distEndLineToCtr * 0.7 'FUDGE FACTOR
End If
'Multiply sin by the distance
sinByDist = sinAngle * distEndLineToCtr
'Calculate the new Y location
newLocation.Y = sinByDist + termPoint.Y
'Multiply cos by the distance
cosByDist = cosAngle * distEndLineToCtr
'Now calculate the new X location
newLocation.X = cosByDist + termPoint.X
GetNewLocation = newLocation
End Function
Sub ResetVals()
CadInputQueue.SendCommand "echo"
ActiveSettings.TextStyle.Justification = saveActiveTextJustification
ActiveSettings.TextStyle.NodeJustification = saveActiveTextNodeJustification
ActiveSettings.Angle = saveActiveAngle
'Set ActiveSettings.Level = saveActiveLevel
Set saveActiveFont = ActiveSettings.Font
ActiveSettings.TextStyle.Height = saveActiveCharHeight
ActiveSettings.TextStyle.Width = SaveActiveCharWidth
'ActiveSettings.LineStyle = saveActiveLineStyle ' reset active symbology
ActiveSettings.Color = saveActiveColor ' reset active symbology
ActiveSettings.LineWeight = saveActiveWeight ' reset active symbology
CadInputQueue.SendKeyin "lock axis on"
CadInputQueue.SendCommand "null"
ShowCommand "LEADER LINE User Command Exited"
End Sub
![]()
![]()