Edit text with VBA by coordinates

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:

    • Please read and follow MicroStation Programming forum best practices, especially how subject should be formatted and what information should always be shared.
    • This is general programming forum, not specific to MicroStation-based (power platfrom) products. Because (from reasons I do not know) there is no "building programming forum" and your question is quite general, I recommend to move it to MicroStation Programming forum. To move your post, use More > Move tool below your original post (do not duplicate your post somewhere else).
    • Always use Insert > Insert code tool when you want to share a code, even when it's one line only! To place the code as a plain unformatted text is like you want to make your text to be harder readable and especially when code is longer, it's a poisoning to read it and try to understand it.

    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.

    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.

    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

    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:

    • Do you want to select text by a user? In such case implement ILocateCommandEvents object. It allows to select an element "by coordinates" selecting it by the user in a view.
    • Do you want to select all texts at specific coordinates? Use ElementScanCriteria with Range filter applied.
    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).

    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

  • 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. 

    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? 

    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. 

  • Hi Robert,

    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.

    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.

    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.

    With regards,

      Jan

  • 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.

    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

  • 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).

    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).

    Regards,

      Jan

  • I would like to edit that text, and I have no clue how
    I've also seen a lot about the element enumerator in these cases

    Here's an article about Text Search and Replace with MicroStation VBA.

    Text Search with VBA

    The VBA project you can download from that link is not locked: it includes the source code.  It shows how to use the Model.Scan method to make an ElementEnumerator of text elements.  It shows how to find text elements inside cell instances.  It shows how to find text elements inside text nodes.  It shows how to find text in tags, even though — from the programmer's point of view — tag elements aren't text elements!

     
    Regards, Jon Summers
    LA Solutions

  • I'll try to figure something out.

    Without sharing an example design file it's complicated to provide more detail advice...

    Regards,

      Jan

  • 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,

      Jan

    Answer Verified By: Robert Högberg