DataEntryRegion.Length not working in Connect Update 16

Hello, I searched but couldn't find anything related, so here goes. We're on Update 16 of Connect and a script that was working fine in v8i doesn't seem to produce the same results in Connect. So i have simplified it here to duplicate the error:

Sub TestTextChanges()
Dim oEnum  As ElementEnumerator
Dim oelem  As Element
Set oEnum = ActiveModelReference.GetSelectedElements
Do While oEnum.MoveNext
    Set oelem = oEnum.Current
    If oelem.IsTextElement Then
        Dim t As TextElement
        Set t = oelem
        t.DeleteAllDataEntryRegions
        
        Dim d As DataEntryRegion
        d.length = 30
        d.justification = msdDataEntryRegionJustificationCenter
        d.StartPosition = 1
        t.AddDataEntryRegion d
        t.Text = "THIS IS A TEST"
        t.Rewrite
        t.Redraw
        
    End If
Loop

End Sub

What happens is that once you create a datafield with length of 30, add it to textelement and set the text value to it, it resizes back to length of text instead of 30. What's odd is that if you're testing the length at every step, it actually says that it is 30 even after the rewrite/redraw but visually I can see the datafield is only the length of the text, and then if i go to manually edit the datafield it will show length of 14, but vba will still report 30...

I get it that Bentley doesn't want us to use datafields anymore, but we have thousands of drawings with them, you can't just break this feature. It was bad enough when they published the first iteration of Connect without a way to edit them...

  • Hi,

    I searched but couldn't find anything related

    It is probably because this feature is not used too frequently (especially from VBA ;-).

    So i have simplified it here to duplicate the error:

    Great to have something to be tested!

    I tried it (really quickly ;-) with MicroStation CE U16.2, V8i SS10 and V8 2004 Edition, and I always received the same result (first line is input, the second is the code result)

    What happens is that once you create a datafield with length of 30, add it to textelement and set the text value to it, it resizes back to length of text instead of 30.

    I see it in all tested versions.

    and then if i go to manually edit the datafield it will show length of 14, but vba will still report 30...

    It looks like bug in VBA API.

    I get it that Bentley doesn't want us to use datafields anymore

    I do not think it is true. It is just a consequence of very low priority of this old tool, when bugs are removed.

    With regards,

      Jan

  • It seems that a datafield character needs a space character to occupy it. I changed your VBA code as below. It can create a text string follow a 30 length datafield.

    Sub TestTextChanges()
        Dim oEnum  As ElementEnumerator
        Dim oelem  As Element
        Set oEnum = ActiveModelReference.GetSelectedElements
        Do While oEnum.MoveNext
            Set oelem = oEnum.Current
            If oelem.IsTextElement Then
                Dim t As TextElement
                Set t = oelem
                t.DeleteAllDataEntryRegions
                t.Text = "THIS IS A TEST" + Space(30)
                
                Dim d As DataEntryRegion
                d.Length = 30
                d.Justification = msdDataEntryRegionJustificationCenter
                d.StartPosition = 15
                t.AddDataEntryRegion d
                t.Rewrite
                t.Redraw
            End If
        Loop
    End Sub

    Created result is as below:



  • Yea I tried the same and thought that would fix it, but it doesn't work every time and not consistently. For example, if you keep changing the length on the same text element it doesn't seem to update after first time, sometimes not at all, and then other times microstation will just close out. 

    So can anyone test if the API is also buggy on .net SDK? I don't have access to it at the moment.

  • So can anyone test if the API is also buggy on .net SDK?

    NET API is (in the most cases) just a wrapper around C++ API, so to bugs in C++ functionality, some extra in wrappers are added ;-)

    But seriously, both C++ and NET are far better in terms of quality.

    Concerning enter-data (ED) API: old C functions from V8i were deprecated (so still available, but not recommended to use), which in my opinion is a consequence of completely new Text API. It unifies complete text functionality (text, text node, dimensions..., ED, Text fields...), which is great, on the other hand is really complex (better to say complicated).

    Consequently, it is not simple to test ED in C++ or NET, because there is no ED API available and text must be analyzed.

    From deprecation notes:

    There is no direct equivalent to TextEDParam in TextBlock. You must iterate the runs
    and dynamic_cast to an EdfCharStream to get EDF information.

    So API he functionality can be tested, but it is not as simple as in VBA :-(

    I don't have access to it at the moment.

    To access NET API, no SDK is required, because all NET assemblies are part of MicroStation itself.

    But it is true that without documentation (both NET, and when required, also C++), it is hard to write the code.

    Regards,

      Jan

  • Not very inspiring about the .net api, but thank you. Yea kind of sucks the way the SDK is locked up behind a curtain, waiting on someone in a company with access just so I can get my hands on it, I'm too spoiled with Autodesk i guess.

  • Unfortunately, I do not see anything constructive in your reaction:

    • So far, your code seems work fine in all versions where I was able to test, providing consistent results. No change or bug visible.
    • Yongan.Fu shared the idea how to preserve the length (probably can be used in any MicroStation version).
    • I do not understand why "SDK is behind a curtain"

    Instead of lamenting, it would be great to share (publicly or send to support) example where Yongan's approach is not consistent, so it can be analyzed further. It can be caused by both code and DGN itself, similarly to (old) bug in tag edit functionality, crashing MicroStation only with some old, probably originally V7 files, but no with any others.

    Until the not working example, the bug does not exist, because it is not how to analyze what can cause the problem.

    Regards,

      Jan

  • When i read your original reply it seemed to indicate that you tested in all versions and WAS able to replicate the issue? But you're saying it did work as expected? When I look at the image you provided, the second line should be sized to 30 but instead it is sized to 14 which confirms the issue for me.

  • Well, I need to apologize as I see why I misled you both on what I was after. I noticed that in the test code i posted above I was setting the TextElement.Text property instead of TextElement.DataEntryRegionText. So Yongan.Fu did provide the right answer by adding spaces, which forces the datafield to expand to the right size, but in my non-test code i was using DataEntryRegionText so the result wasn't the same.

    Here's code that works in the way I was expecting:

    Sub TestTextChanges()
    Dim oEnum  As ElementEnumerator
    Dim oelem  As Element
    Set oEnum = ActiveModelReference.GetSelectedElements
    Do While oEnum.MoveNext
        Set oelem = oEnum.Current
        If oelem.IsTextElement Then
            Dim t As TextElement
            Set t = oelem
            t.DeleteAllDataEntryRegions
    
            
            Dim d As DataEntryRegion
            d.length = 12
            d.justification = msdDataEntryRegionJustificationLeft
            d.StartPosition = 1
            t.AddDataEntryRegion d
    
            t.DataEntryRegionText(1) = t.Text
            
            t.Rewrite
            t.Redraw
            
        End If
    Loop
    
    End Sub
    Function GetTextToLength(val As String, length As Integer) As String
    Do While Len(val) < length
        val = val + " "
    Loop
    GetTextToLength = val
    End Function

    The justification of the datafield does not seem to update the actual text though, if i force the datafield to right justified, it will still appear left justified until I go in to manual edit it and then it actually shows up right justified. That's a different issue.

  • Well, after a bit of poking around, figured I should contribute to someone else that may need a similar feature. Here's the code that works with the exception of justification which works to set the property but doesn't appear changed until manually open the datafield.

    Sub ModifyDataFields(dLength As Integer, dJustification As Integer, tWidth As Double)
    Dim results As Collection
    Set results = GetAllTextElements(ActiveModelReference.GetSelectedElements)
    If results Is Nothing Then Exit Sub
    
    Dim t As TextElement
    For Each t In results
        If Len(t.Text) > 0 Then
             
                If t.DataEntryRegionsCount = 1 Then
                    MatchDataFieldLengths t, dJustification, dLength, tWidth
                End If
                
        End If
    Next
            
    
    End Sub
    
    Function GetAllTextElements(elemEnum As ElementEnumerator) As Collection
    Dim coll As New Collection
    Do While elemEnum.MoveNext
        If elemEnum.Current.IsTextElement Then
            coll.Add elemEnum.Current.AsTextElement
        End If
        If elemEnum.Current.IsTextNodeElement Then
            Dim nodeResults As Collection
            Set nodeResults = GetAllTextElements(elemEnum.Current.AsTextNodeElement.GetSubElements)
            If Not nodeResults Is Nothing Then
                If nodeResults.count > 0 Then
                    For Each Item In nodeResults
                        coll.Add Item
                    Next
                End If
            End If
        End If
        If elemEnum.Current.IsCellElement Then
            Dim cellResults As Collection
            Set cellResults = GetAllTextElements(elemEnum.Current.AsCellElement.GetSubElements)
            If Not cellResults Is Nothing Then
                If cellResults.count > 0 Then
                    For Each Item In cellResults
                        coll.Add Item
                    Next
                End If
            End If
        End If
    Loop
    Set GetAllTextElements = coll
    
    End Function
    
    
    Function MatchDataFieldLengths(ByVal t As TextElement, dJustification As Integer, dLength As Integer, width As Double) As TextElement
    
           t.DeleteAllDataEntryRegions
                
            Dim d As DataEntryRegion
            d.length = dLength
            
            Select Case dJustification
            Case Is = 1
                d.justification = msdDataEntryRegionJustificationLeft
            Case Is = 2
                d.justification = msdDataEntryRegionJustificationCenter
            Case Is = 3
                d.justification = msdDataEntryRegionJustificationRight
            End Select
            
            d.StartPosition = 1
            t.AddDataEntryRegion d
            t.DataEntryRegionText(1) = t.Text
            
            t.Rewrite
            t.Redraw
            
            t.TextStyle.width = width
            
            t.Rewrite
            t.Redraw
       
    
    End Function