.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Trouble getting textstring from attribute definition

62 REPLIES 62
Reply
Message 1 of 63
myspambox111
1091 Views, 62 Replies

Trouble getting textstring from attribute definition

I have been creating block attributes with some good success. Example:







While btrEnum.MoveNext

Dim ent As Entity = btrEnum.Current.GetObject(OpenMode.ForWrite)

If TypeOf ent Is AttributeDefinition Then

Dim attdef As AttributeDefinition = ent

Dim attref As New AttributeReference

attref.SetAttributeFromBlock(attdef, myBRef.BlockTransform)

attref.TextString = myReader.ReadLine

attColl.AppendAttribute(attref)

trans.AddNewlyCreatedDBObject(attref, True)

End If



End While

Now, when I try to read those attribute's textstrings back later for different reasons, I receive only the "default" attribute textstring instead of the one I inserted earlier in the program. Example:



While btrEnum.MoveNext

Dim ent As Entity = btrEnum.Current.GetObject(OpenMode.ForWrite)

If TypeOf ent Is AttributeDefinition Then

Dim attdef As AttributeDefinition = ent

Dim attref As New AttributeReference

attref.SetAttributeFromBlock(attdef, myBRef.BlockTransform)

If attdef.Tag.ToUpper = myTag.ToUpper Then

value = attdef.TextString

End If

End If

End While

Why doesn't this return the textstring value recorded earlier?



Is there an easier way to do this?
62 REPLIES 62
Message 21 of 63

That's because the enumerator returned by the AttributeCollection is a System type which does not implement IDisposable, not a SymbolTableEnumerator, which does.



Hard to call something that's not implemented.
Dave O.                                                                  Sig-Logos32.png
Message 22 of 63
NathTay
in reply to: myspambox111


The GetEnumerator method of the BlockTableRecord returns a BlockTableRecordEnumerator which does implement IDisposable.



GetEnumerator is being called on the BlockTableRecord in the examples above not on an AttributeCollection.

Message 23 of 63
myspambox111
in reply to: myspambox111

Well, without digressing further guys, can someone please post an example addressing my original question?

I realize I still have things to learn about autocad programming in .NET but I seem to get more understanding from an example containing a few lines of code than an hours worth of reading. It allows me (and others) to see how it works rather than trying to comprehend ambiguous concepts in an API thats lacking a lot of references and resources. I understand that sometimes giving someone the answer right away can be counterproductive, but in the instance of autocad in .net, theres really little else we can rely on than answers from you guru's who have done this full time for years. If you have the answer, please post it. It not only saves the inquirer time, but also those who are seeking the same answers on the forums.
Message 24 of 63
Mikko
in reply to: myspambox111


Just a bit of my 2¢ and having seen an example from ADN ID: TS88193 which applies to AutoCAD® 2007 and AutoCAD® 2008 versions, you will see that they also use as an example:





Dim iEnumerator As IEnumerator = btr.GetEnumerator()

'Try to get the attribute in the block definition

While (iEnumerator.MoveNext())

....





C# or VB both use it. Of course that doesn't have to make it correct, look how well these forums work. Bottom line: Does it work for you? If so run with it and get on with the show.





I've used something like this in the past to read attributes.





<CommandMethod("attRefs")> Public Sub attRefs()

Call GetAttributes("YourBlockName")

End Sub



Private Sub GetAttributes(ByVal NameOfBlock As String)

Dim findThis() As TypedValue = {New TypedValue(0, "INSERT"), New TypedValue(2, NameOfBlock)}

Dim sf = New SelectionFilter(findThis)

Dim psr As PromptSelectionResult = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.SelectAll(sf)

If psr.Status = PromptStatus.OK Then

Using t As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()

For Each h As ObjectId In From q As ObjectId In psr.Value.GetObjectIds()

Dim br = CType(t.GetObject(h, OpenMode.ForRead), BlockReference)

For i As Integer = 0 To br.AttributeCollection.Count - 1

Dim ar As AttributeReference = CType(t.GetObject(br.AttributeCollection(i), OpenMode.ForRead), AttributeReference)

MsgBox(ar.TextString)

Next

Next

t.Commit()

End Using

End If

End Sub



Tony, I really would like to see your For Each AttributeReference Next example. I could probably learn even more and somebody might even hire my unemployed a$$ but then we would all miss these lively discussions.

Message 25 of 63
NathTay
in reply to: myspambox111


That looks like a pretty poor example from ADN given that the GetEnumerator method of BlockTableRecord returns a BlockTableRecordEnumerator type. Although I am making the assumption they have not changed the return type from IEnumerator in 2009.

Message 26 of 63
NathTay
in reply to: myspambox111

The connection between the examples above that use GetEnumerator and using For Each is as follows.



The code that uses GetEnumerator calls the Current property of the BlockTableRecordEnumerator which returns an ObjectId.



Therefore the For Each approch is as follows.



For Each objEntId as ObjectId in objBTR





Next objEntId
Message 27 of 63
Anonymous
in reply to: myspambox111

Wrong.

The object returned by AttributeCollection.GetEnumerator()
most certainly does implement IDisposable.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message news:6116732@discussion.autodesk.com...
That's because the enumerator returned by the AttributeCollection is a
System type which does not implement IDisposable, not a
SymbolTableEnumerator, which does.



Hard to call something that's not implemented.
Message 28 of 63
Anonymous
in reply to: myspambox111

Just because you see it in an ADN sample, doesn't make it
correct.

Shame on whomever in ADN approved that.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message news:6116779@discussion.autodesk.com...

Just a bit of my 2¢ and having seen an example from ADN ID: TS88193 which
applies to AutoCAD® 2007 and AutoCAD® 2008 versions, you will see that they
also use as an example:







Dim iEnumerator As IEnumerator = btr.GetEnumerator()

'Try to get the attribute in the block definition

While (iEnumerator.MoveNext())

....







C# or VB both use it. Of course that doesn't have to make it correct, look
how well these forums work. Bottom line: Does it work for you? If so run
with it and get on with the show.







I've used something like this in the past to read attributes.







Public Sub attRefs()

Call GetAttributes("YourBlockName")

End Sub






Private Sub GetAttributes(ByVal NameOfBlock As String)

Dim findThis() As TypedValue = {New TypedValue(0, "INSERT"), New
TypedValue(2, NameOfBlock)}

Dim sf = New SelectionFilter(findThis)

Dim psr As PromptSelectionResult =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.SelectAll(sf)

If psr.Status = PromptStatus.OK Then

Using t As Transaction =
HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()

For Each h As ObjectId In From q As ObjectId In psr.Value.GetObjectIds()

Dim br = CType(t.GetObject(h, OpenMode.ForRead), BlockReference)

For i As Integer = 0 To br.AttributeCollection.Count - 1

Dim ar As AttributeReference = CType(t.GetObject(br.AttributeCollection(i),
OpenMode.ForRead), AttributeReference)

MsgBox(ar.TextString)

Next

Next

t.Commit()

End Using

End If

End Sub






Tony, I really would like to see your For Each AttributeReference Next
example. I could probably learn even more and somebody might even hire my
unemployed a$$ but then we would all miss these lively discussions.
Message 29 of 63
Mikko
in reply to: myspambox111

Private Sub GetAttributes(ByVal NameOfBlock As String)

Dim findThis() As TypedValue = {New TypedValue(0, "INSERT"), New TypedValue(2, NameOfBlock)}

Dim sf = New SelectionFilter(findThis)

Dim psr As PromptSelectionResult = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.SelectAll(sf)

If psr.Status = PromptStatus.OK Then

Using t As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()

For Each h As ObjectId In From q As ObjectId In psr.Value.GetObjectIds()

Dim br = CType(t.GetObject(h, OpenMode.ForRead), BlockReference)

For Each k As ObjectId In br.AttributeCollection

Dim ar As AttributeReference = CType(t.GetObject(k, OpenMode.ForRead), AttributeReference)

MsgBox(ar.TextString)

Next k

Next

t.Commit()

End Using

End If

End Sub



Yes you are correct but it doesn't seem to shorten my code any that I posted earlier. I'm off to Denny's for the free Grand Slam Breakfast. Today only. Later.....
Message 30 of 63
Anonymous
in reply to: myspambox111


you are missing the point - it's not about the
length of the code but not needing

dispose of the object returned by GetEnumerator().
As was pointed out - dispose()

is not called in most code that uses it! Including
my own at one point ~)


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Private
Sub GetAttributes(ByVal NameOfBlock As String)

Dim findThis() As
TypedValue = {New TypedValue(0, "INSERT"), New TypedValue(2,
NameOfBlock)}

Dim sf = New SelectionFilter(findThis)

Dim psr As
PromptSelectionResult =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.SelectAll(sf)

If
psr.Status = PromptStatus.OK Then

Using t As Transaction =
HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()

For
Each h As ObjectId In From q As ObjectId In
psr.Value.GetObjectIds()

Dim br = CType(t.GetObject(h,
OpenMode.ForRead), BlockReference)

For Each k As ObjectId In
br.AttributeCollection

Dim ar As AttributeReference =
CType(t.GetObject(k, OpenMode.ForRead),
AttributeReference)

MsgBox(ar.TextString)

Next
k

Next

t.Commit()

End Using

End If

End
Sub



Yes you are correct but it doesn't seem to shorten my code
any that I posted earlier. I'm off to Denny's for the free Grand Slam
Breakfast. Today only. Later.....
Message 31 of 63
sgsawdy
in reply to: myspambox111

Tony, I owe you an apology and for anyone else reading this, please know that I am being as sincere as I know how to be. I have obviously offended you by being ignorant, lost and using resource material that is poorly written. It is absolutely true that I am ignorant on programming, that I am lost in VB.NET programming, that I am an electrical designer and not a programmer, that I have learned how to program incorrectly by using the only resources available to me outside of this forum.

This is all very true, and it also why I have been coming to this forum to ask questions and to ask for help. It is also why I will continue to do so even if it exposes my ignorance, but I will try to do so without annoying you or anyone else. There is no other alternatives available and it is important that this forum remains civil, helpful and open to all of us that need it to help us with our respective jobs.

Sincerely, Tony, I apologize for offending you and expressing my frustration over your responses to my questions.

Scott
Message 32 of 63
NathTay
in reply to: myspambox111

What!! You asked for an example of using For Each in the context of a discussion involving GetEnumerator. I provided it and how it relates to GetEnumerator. Your code isn't using GetEnumerator it already uses For Each.



If you were refering to the ADN snippet you posted then below is a real example of a direct comparison.



For Each objEntId as ObjectId in objBTR

Dim objEnt as Entity = CType(objTrans.GetObject(objEntId, DatabaseServices.OpenMode.ForWrite, False), Entity)



Next objEntId



As opposed to



Dim objBTRE as BlockTableRecordEnumerator = objBTR.GetEnumerator

While objBTRE.MoveNext

Dim objEnt as Entity = CType(objBTRE.Current.GetObject(DatabaseServices.OpenMode.ForWrite, False),Entity)



End While

objBTRE.Dispose





I have not and will not argue that one is better than the other. The purpose of the example is to show those that wanted to know how to use For Each how to do so and to allow those that want to compare the methods to compare apples with apples.



I have always used For Each and will continue to do so but am interested to here a full explanation of why using GetEnumerator is bad.
Message 33 of 63
Mikko
in reply to: myspambox111

I never said that I used GetEnumerator in that context. Just wanted to see how somebody else would code it. I pointed out what I saw in an ADN example. I just looked at your reply and decided that I would change my "For i As Integer = 0 To br.AttributeCollection.Count - 1" section of code to use the For Each also. Using LINQ and writing a custom iterator class, I would use GetEnumerator, MoveNext and return Current. To every thing there is a season.... I'm old and its late and I've had way to much coffee. My mind is racing. Time to play some XBox. Till another day and another issue.
Message 34 of 63
NathTay
in reply to: myspambox111


I think you need sleep beacause you aren't making any sense.





My original post was an example of using For Each and how it correlates to GetEnumerator.





I now realise your reaction was because you think I was telling you that you could shorten your For i To code. I don't know how you came to that conclusion.

Message 35 of 63
Anonymous
in reply to: myspambox111

{quote}

Tony, I owe you an apology and for anyone else reading this, please know
that I am being as sincere as I know how to be. I have obviously offended
you by being ignorant, lost and using resource material that is poorly
written.

{quote}

Sorry, that's wrong.

What you're doing is trying to run before you've learned to walk, which does
not offend me, but certainly can be frustrating if I have to spend more time
than I can afford, to explain very basic things that can be learned from the
proper learning materials, which that book you have is nothing of the sort.

Rather than being suckered in by that book, you should get a non-AutoCAD
specific book that focuses on the basics of VB.NET and the .NET Framework
(not necessarily one book, mind you), and use that to become more familiar
with the basics of the tools you want to use first, before actually trying
to to use them to do something with AutoCAD.
Message 36 of 63

I'm not sure if you didn't have your wheaties that day, or ran out of V8 juice, but your reply, Tony, was once again, off target.



I thank you for the tid bit of information you packed in it, but you didn't acually address my issue at all. Why would For Next work when For Each Next would not? And even more interesting, Why would For Each Next work on one PC, and not on another? What does For Next have OVER For Each Next? Mr, I have all the clues... Don't play master of all if you are going to read so fast that you fail to comprehend.



btw, I can't get lost, I have an uncanny sense of direction, and keep finding my way back.



jvj
Message 37 of 63

BTW, the book in question is still selling copies. Where's your book?



Nuff said.



jvj
Message 38 of 63
NathTay
in reply to: myspambox111

And we have the winner of the moronic response of the week.



First of all that book has a captive market so of course it is going to sell copies.



What is your point of this remark? "Where's your book?" Is it saying Jerry is better than everyone else because he has written a book? Is it saying Tony is incompetent because he hasn't written a book? If you are going to ask Tony where his book is then maybe you should tell us where your book is and why writing a book holds any relevance.
Message 39 of 63

Well the relevance is pretty simple Nath...



We have 3 maybe 4 major players in the AutoCAD customization education market. Jerry, whom I think deserves loads of credit for having created a book that works in VB.Net, the most modern and complex API that is going mainstream by demand. Joe who wrote a few good books recently, on VBA, the 'beginner' language for most programmers starting today. Tony, who co-wrote 2 books back in the day on LISP and mastering AutoCAD. I reserve the 4th for the new upcomming programmers that are most helpful, vs degrading to new programmers. One of these is bound to be a writer. I ask Tony where his book is as I always have since I began in VB.Net 2 years ago. Tony has loads of good ideas, but his approach to delivery is becomming more and more degrading. Joe's replies have always been kind and with high respect. Jerry has been hard to find, but when he does respond, he is also very kind. If you want me too, and my boss would give me the time, I'm sure I could compile a logical programming educational path from scratch to production. It would just be a collage of what I learned from these guys, this forum, my boss, and the internet. That doesn't really matter. What matters is the sour attitude portrayed by a 40's something programmer who expects everybody to be born with knowledge of all code from assembley to VB.Net in order to help point people in the right direction. Be nice. That is the point.



Write that in your AutoCAD cliff notes.



jvj
Message 40 of 63
NathTay
in reply to: myspambox111

That is a jumble of irrelevant nonsense which only goes to show your true reason for the question which is a deep hatred of Tony for belittling you.



The quality of information you are spreading has absolutey no connection to how nice you are. You aren't actually in a position to take the moral high ground either with your debates with Tony it hasn't exactly been one sided nastiness.



Please not not write a book as your incompetence has been shown time and time again.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost