Hi
I'm really new to VBA and haven't really gotten a grip of how it works. I've managed to write some VBA-code for placing text by coordinates.
Set oText = CreateTextElement1(Nothing, ooDate, point_text_Date, Matrix3dIdentity)ActiveModelReference.AddElement oText
But now I would like to edit that text, and I have no clue how to. I've searched a lot after "edit text VBA microstation" and most answers is for when you need to search for some text, and replace it if found.
What I'm not really sure of is if I can select text in a particular coordinate by VBA, and then replace it by some text. Is there a command for selecting elements?
I've also seen a lot about the element enumerator in these cases. Could that be used for coordinates as well?
Would it make a difference if that text was inside a cell?
Running Openbuildigs, connect, update 5.
Regards,
Robert
Hi Robert,
at first, a few recommendations:
BTW There is no product named Openbuildings. To be developer require to be precise, so specify your product (as required by the best practices) exactly: OpenBuildings Designer CONNECT Edition Update 5, English version (?), probably build number 10.05.00.49. Is it correct? In the post subject it can shortened to [OBD U5 VBA], because there is no conflict with V8i names.
Robert Högberg said:I'm really new to VBA and haven't really gotten a grip of how it works.
I strongly recommend to first learn VBA and when you understand basics, to move to MicroStation VBA. Otherwise it will be painful progress with a lot of confusion. There are plenty of "general VBA tutorials available", also you can read Learning MicroStation VBA book. It's quite old, but the most of content is valid for CE also and it offers quick introduction into VBA langauge.
Robert Högberg said:But now I would like to edit that text, and I have no clue how to.
It's simple:
Dim te As TextElement ' Retrieve text element anyhow, e.g. using ID Set te = ActiveModelReference.GetElementByID(DLongFromLong(123456)) ' Modify and rewrite text te.Text = "This is text" te.Rewrite
Robert Högberg said:What I'm not really sure of is if I can select text in a particular coordinate by VBA
Again, please be exact. Too many sentences and still not quite clear what do you want to achieve and what the workflow should be:
Robert Högberg said:if I can select text in a particular coordinate by VBA
If you think about something like
Dim te As TextElement ' Retrieve text element anyhow, e.g. using ID Set te = ActiveModelReference.GetElementByID(DLongFromLong(123456)) ' Check whether coordinates are correct If (te.Origin.X = 1.2345 And te.Origin.Y = 9.8765) Then ' Do something End If
it's incorrect and cannot be used. You cannot test decimal numbers euqality this way, never! When using element scanning, you should use Range criteria, and when individual coordinates are tested, they alwyas have to be tested in defined tolerance (e.g. using Point3dEqualTolerance).
Robert Högberg said:Would it make a difference if that text was inside a cell?
Do not break best practices! One question (issue / area) per one post. When you want to discuss another topic, create a new post.
An answer in this case is: "Yes, it makes (huge) difference, but details depends how the cell will be selected (by user, using scan...)".
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan, thanks for your reply. Haven't had a chance to try it till now.
Promise to be better at specifying my program in the future.
Jan Šlegr said:It's simple:
I tried your code but I get a "type mismatch" error on the set te = ... line. Is there something else I have to do?
Jan Šlegr said:Again, please be exact. Too many sentences and still not quite clear what do you want to achieve and what the workflow should be:
I would actually like to retrieve the object just by coordinates. Not elementID. After that maybe run a check that it's a textelement, and then change the text to whatever the user has chosen.
Reason is we have the legend text placed in our seed, and now we manually edit it en every sheetmodel. I'm trying to write something that will edit it for me.
Robert Högberg said:I tried your code but I get a "type mismatch" error
Of course you did ;-)
It's just an example how code can looks like, but when tested with any other design file than my original one, the same element ID (when exists) will represent another (and probably another type) element.
Robert Högberg said:I would actually like to retrieve the object just by coordinates.
In such case you have to use ElementScanCriteria with Range filter.
To search "by location" is not good idea in general, but when you are able to ensure the texts will be always at the same coordinates, it would be fine.
Robert Högberg said:After that maybe run a check that it's a textelement
No, it's wrong! You have to define your ElementScanCriteria to scan and select only required element types.
To select everything and to do any tests later is wrong both from code algorithm perspective as well as because of worse performance.
Jan Šlegr said:It's just an example how code can looks like, but when tested with any other design file than my original one, the same element ID (when exists) will represent another (and probably another type) element.
But I did change the element ID to an existing one. Or is it not this one?
But never mind, that's not what I'm after.
Jan Šlegr said:To search "by location" is not good idea in general, but when you are able to ensure the texts will be always at the same coordinates, it would be fine.
Ok, so how would that look. It's what I've been searching for without any luck!
//Robert
Robert Högberg said:But I did change the element ID to an existing one. Or is it not this one?
My code works with TextElement, not with TextNodeElement.
When you received TextNodeElement, you have to go "one level deeper" to receive text elements stored in text node (which is ComplexElement).
Robert Högberg said:It's what I've been searching for without any luck!
MicroStation VBA help contains several examples how to use ElementScanCriterie together with Scan method (plus many times discussed in this forum). I am not sure whether "scan wtih range criteria" is demonstrated somewhere, but there is no big difference from scanning based on another criteria (e.g. element type).
I see! Ok, I'll try to figure something out. Thank you!
Robert Högberg said:I'll try to figure something out.
Without sharing an example design file it's complicated to provide more detail advice...
Ok, I found out that you shared the file in another discussion.
Using that file, "code demonstrator" how to edit a text node in upper right corner is:
Option Explicit Public Sub StartMacro() Dim location As Range3d location = Range3dFromXYZXYZ(721, 542, 0, 723, 555, 0) Dim tn As TextNodeElement Set tn = FindFirstTnInLocation(location) If tn Is Nothing Then MessageCenter.AddMessage "No text found at location", vbNullString, msdMessageCenterPriorityWarning, False Exit Sub End If ModifyTextNode tn End Sub Private Function FindFirstTnInLocation(location As Range3d) As TextNodeElement Dim esc As New ElementScanCriteria esc.ExcludeAllTypes esc.IncludeType msdElementTypeTextNode esc.IncludeOnlyWithinRange location Dim ee As ElementEnumerator Set ee = ActiveModelReference.Scan(esc) Do While ee.MoveNext Set FindFirstTnInLocation = ee.Current Exit Function Loop Set FindFirstTnInLocation = Nothing End Function Private Sub ModifyTextNode(tn As TextNodeElement) Dim ee As ElementEnumerator Set ee = tn.GetSubElements Dim counter As Integer: counter = 1 Do While ee.MoveNext Dim txt As TextElement Set txt = ee.Current.AsTextElement txt.Text = "Line " & CStr(counter) txt.Rewrite counter = counter + 1 Loop End Sub
With ergards,
Answer Verified By: Robert Högberg
Oh, big thanks for that!!