I have to add 80 Xdata to some objects. How to populate them within a loop. This what I did for 11 of them . But
I am pretty sure there is a way to do it in a loop which I don't know . Any help from experts would be appreciated.
Public Sub SetXData2() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor ' Ask the user to select an entity ' for which to set XData Dim opt As New PromptEntityOptions(vbLf & "Select entity: ") Dim res As PromptEntityResult = ed.GetEntity(opt) If res.Status = PromptStatus.OK Then Dim tr As Transaction = doc.TransactionManager.StartTransaction() Using tr Dim obj As DBObject = tr.GetObject(res.ObjectId, OpenMode.ForWrite) AddRegAppTableRecord1("Hello") Dim rb As New ResultBuffer(New TypedValue(1001, "Hello"), _ New TypedValue(1000, "test1"), New TypedValue(1000, "test2") _ , New TypedValue(1000, "test3"), New TypedValue(1000, "test4") _ , New TypedValue(1000, "test5"), New TypedValue(1000, "test6") _ , New TypedValue(1000, "test7"), New TypedValue(1000, "test8") _ , New TypedValue(1000, "test9"), New TypedValue(1000, "test10") _ , New TypedValue(1000, "test11")) obj.XData = rb rb.Dispose() tr.Commit() End Using End If End Sub
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
Hello Sharifi,
Below is example for automaticaly add data to resultbuffer.
Public Sub SetXData2() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor ' Ask the user to select an entity ' for which to set XData Dim opt As New PromptEntityOptions(vbLf & "Select entity: ") Dim res As PromptEntityResult = ed.GetEntity(opt) If res.Status = PromptStatus.OK Then Dim tr As Transaction = doc.TransactionManager.StartTransaction() Using tr Dim obj As DBObject = tr.GetObject(res.ObjectId, OpenMode.ForWrite) 'This is new instance of result buffer Dim rb As New ResultBuffer 'Here we add elements as typedvalue to resul buffer For i As Integer = 0 To 10 Dim tv As New TypedValue(DxfCode.ExtendedDataAsciiString, i.ToString) rb.Add(tv) Next obj.XData = rb rb.Dispose() tr.Commit() End Using End If End Sub
Best regards,
Danijel
Just a remind: There is a byte limit for the XData that is attached to an entity: 16K. When attaching 80 pieces of XData to an entitiy, you need to carefully watch the data size.
You do not want to use up or close to the 16K just for your single application. What if the other applications (yours or the third parties') also need to use XData but the 16K is exceeded? So, it is good idea of store only minmumly required XData for a single application.
Norman Yuan
Thanks Dani . With your help and good advice from my other friends (Fixo is main) . attached is working code. for other people who has this problem
Public Sub SetXData() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim opt As New PromptEntityOptions(vbLf & "Select entity: ") Dim res As PromptEntityResult = ed.GetEntity(opt) If res.Status = PromptStatus.OK Then Dim tr As Transaction = doc.TransactionManager.StartTransaction() Using tr Dim obj As DBObject = tr.GetObject(res.ObjectId, OpenMode.ForWrite) AddRegAppTableRecord1("TCB") Dim lstXdata As List(Of Object) = New List(Of Object) For i As Integer = 0 To 99 lstXdata.Add("Test" + (i + 1).ToString) Next Dim rb As New ResultBuffer rb.Add(New TypedValue(1001, "TCB")) For Each strVal As String In lstXdata rb.Add(New TypedValue(1000, strVal)) Next obj.XData = rb rb.Dispose() tr.Commit() End Using End If End Sub Private Shared Sub AddRegAppTableRecord1(ByVal regAppName As String) Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim db As Database = doc.Database Dim tr As Transaction = doc.TransactionManager.StartTransaction() Using tr Dim rat As RegAppTable = DirectCast(tr.GetObject(db.RegAppTableId, OpenMode.ForRead, False), RegAppTable) If Not rat.Has(regAppName) Then rat.UpgradeOpen() Dim ratr As New RegAppTableRecord() ratr.Name = regAppName rat.Add(ratr) tr.AddNewlyCreatedDBObject(ratr, True) End If tr.Commit() End Using End Sub
Thanks For Tip Norman. Could you give me sense of 16K . HOw many string I could put for an object to reach 16K ?
this is quoted from somewhere:
strings take up 20+(n/2)*4 bytes (rounding the value of n/2 down), where n is the number of characters in the string.
Autodesk recommends an app do not use up more than 2K XData. So, if you have 80 text Xdata, you would be able to see how easy it is to fill it up 2K, 4K or more...
Norman Yuan
Thanks Norman. I got it.
As a test I tried to put 100 text and each text 6 characters and added those to just one line object . Nothing wrong so far.
base on your Formula 20+( 6/2)*4 = 240 byes and I have 100*240 = 24000 bytes means 2.3K.
I should be good . I guess. I hope I don't get fatal error when I do this for 2000 object in one drawing.
Cross your finger.
Hello Sharifi,
I mean
1 Kbytes = 1024 Bytes
I tested this function, and geting similiar result as windows report
in *.txt file. Result depends from type of encoding.
Public Function GetSize(ByVal _List As List(Of String)) As Integer Dim encoding As New System.Text.UnicodeEncoding() Dim Size As Integer=0 For Each Str As String In _List Size += encoding.GetByteCount(Str) Next Return Size End Function
Does someone know more about this?
Best regards,
Danijel
Can't find what you're looking for? Ask the community or share your knowledge.