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,
Viktor_Kulik said:I searched but couldn't find anything related
It is probably because this feature is not used too frequently (especially from VBA ;-).
Viktor_Kulik said: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)
Viktor_Kulik said: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.
Viktor_Kulik said: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.
Viktor_Kulik said: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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
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.
Viktor_Kulik said: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 :-(
Viktor_Kulik said: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,
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:
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.
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