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 ExplicitDim saveActiveTextJustification As IntegerDim saveActiveTextNodeJustification As IntegerDim saveActiveAngle As DoubleDim saveActiveLevel As LevelDim saveActiveFont As FontDim saveActiveCharHeight As IntegerDim SaveActiveCharWidth As IntegerDim saveActiveLineStyle As LineStyleDim saveActiveColor As LongDim saveActiveWeight As Integer
Dim myCIQ As CadInputQueueDim myCIM As CadInputMessageDim response As String
Sub Main() SetUp LeaderTypeEnd 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 BooleanDim 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 anotherEnd 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
Bertrand Resolus said:I am trying to fix a leader line macro that was built 5 years ago
Bertrand Resolus said:'** july 1989 position the index number in line
That looks more like 30 years ago. It was originally a user command macro (UCM), probably converted to BASIC, then upgraded to VBA.
I have no idea why ActiveSettings.TextNodeLockEnabled = False should cause an error.
ActiveSettings.TextNodeLockEnabled = False
Regards, Jon Summers LA Solutions
Yea the UCM was from about 30 years ago and then changed to VBA in 2014
Can you describe the purpose of your macro? The initial comments mention leader lines. MicroStation has advanced a lot in 30 years: perhaps it now has the tools that the macro was designed to implement?
It looks likes the image below and has the ability to point anywhere and being able to input a letter or number
Yes, the Place Note will do that with a couple dimension settings. Once you get the parameters the way you like, be sure to save it as a style so you can easily use it again.
Connect r17 10.17.2.61 self-employed-Unpaid Beta tester for Bentley
How do I recreate this special arrowhead though, I haven't seen any option to do so.
Create a cell. than assign that cell to be used when "Place Note" is called.
The built in filled arrow looks like this with height set to ½ width. Or make your own.
Hello, thank you for the help, I got the macro to work but can not get the detail letter prompt to work, do you know why?