frostrap 发表于 2022-7-6 11:39:24

[vb.net] Modifying block attri

This is driving me crazy.
 
I'm am writing a program that inserts a drawing as a block and at the time of insertion changes a single attribute's text.
 
The code I'm using isn't working. When I set a breakpoint and inspect the blockreference that I am trying to retrieve info from, it seems to show that there is no attributereference in the block... which I don't believe is true because I know for a fact that the block contains an attribute. Obviouslt there's something I don't understand about retrieving and modifying block attributes with .net.
 
I know some of you use vb.net. Your help would be much appreciated. What am I doing wrong? What don't I understand about how to access block attribute info?
 

Sub InsertBlock(ByVal BlockPath AsString, ByVal thePoint As Point3d)Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocumentDim fname AsString = BlockPathHostApplicationServices.Current.FindFile(fname, doc.Database, FindFileHint.Default)Dim db As Database = New Database(False, False)Trydb.ReadDwgFile(fname, System.IO.FileShare.Read, True, Nothing)Dim t As Transaction = doc.TransactionManager.StartTransactionTryDim idBTR As ObjectId = doc.Database.Insert(BlockPath, db, False)Dim bt As BlockTable = CType(t.GetObject(doc.Database.BlockTableId, OpenMode.ForRead), BlockTable)Dim btr As BlockTableRecord = CType(t.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)Dim bref As BlockReference = New BlockReference(thePoint, idBTR)Dim theScale As Scale3d = New Scale3d(GetSystemVariable("DIMSCALE"), _GetSystemVariable("DIMSCALE"), _GetSystemVariable("DIMSCALE"))bref.ScaleFactors = theScalebref.Layer = "HANGERS"Dim attIDs As AttributeCollection = bref.AttributeCollectionForEach attID As ObjectId In attIDsDim attRef As AttributeReference = t.GetObject(attID, OpenMode.ForWrite)attRef.TextString = "Test"NextTrybtr.AppendEntity(bref)t.TransactionManager.AddNewlyCreatedDBObject(bref, True)FinallyCType(bref, IDisposable).Dispose()EndTryt.Commit()FinallyCType(t, IDisposable).Dispose()EndTryFinallyCType(db, IDisposable).Dispose()EndTryEndSub

SEANT 发表于 2022-7-6 11:55:18

Working with attributes does require a convoluted ass-backward flow.See if this works out.
 

    Sub InsertBlock(ByVal BlockPath As String, ByVal thePoint As Point3d)       Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument       Dim fname As String = BlockPath       HostApplicationServices.Current.FindFile(fname, doc.Database, FindFileHint.Default)       Dim db As Database = New Database(False, False)       Try         db.ReadDwgFile(fname, System.IO.FileShare.Read, True, Nothing)         Dim t As Transaction = doc.TransactionManager.StartTransaction         Try               Dim idBTR As ObjectId = doc.Database.Insert(BlockPath, db, False)               Dim bt As BlockTable = CType(t.GetObject(doc.Database.BlockTableId, OpenMode.ForRead), BlockTable)               Dim btr As BlockTableRecord = CType(t.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)               Dim bref As BlockReference = New BlockReference(thePoint, idBTR)               Dim dblscale As Double = doc.Database.Dimscale               Dim theScale As Scale3d = New Scale3d(dblscale, dblscale, dblscale)               bref.ScaleFactors = theScale               bref.Layer = "HANGERS"               Try                   btr.AppendEntity(bref)                   t.TransactionManager.AddNewlyCreatedDBObject(bref, True)               Finally               End Try               Dim RefBTR As BlockTableRecord = t.GetObject(bref.BlockTableRecord, OpenMode.ForRead)               Dim attEnt As Entity               For Each attID As ObjectId In RefBTR                   attEnt = t.GetObject(attID, OpenMode.ForRead)                   If TypeOf attEnt Is AttributeDefinition Then                     Dim attDef As AttributeDefinition = attEnt                     Dim attRef As AttributeReference = New AttributeReference()                     attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)                     Dim attRefID As ObjectId                     attRefID = bref.AttributeCollection.AppendAttribute(attRef)                     attRef.TextString = "Test"                     t.AddNewlyCreatedDBObject(attRef, True)                   End If               Next               t.Commit()               db.CloseInput(True)               db.Dispose()         Finally         End Try       Finally       End Try   End Sub

frostrap 发表于 2022-7-6 11:59:49

That works. thanks man.
 
I'm a little hazy about what's going on in some of that code, particularly where the SetAttributeFromBlock method is invoked. Why does that method require a blocktransform? When I think of blocktransform I think of a transformation matrix... but that just doesn't seem right to me.

SEANT 发表于 2022-7-6 12:09:24

I can’t say I know the rational for that either.Presumably, because it is an entity not yet fully defined (constant attributes notwithstanding) AutoCAD leaves some of the final details – transformations already established with the geometry for example – to the last possible moment.
 
AutoCAD’s procrastinating, basically.   In that light, AutoCAD and I are part of the same fellowship.

serdas 发表于 2022-7-6 12:19:36

Is it possible to have something that will help me (to insert a blockif possible as well) to update my block information in each drawing without opening each drawing
I have over 100 drawing and I have a block on each of them, and has few attributes in the block and I need to change one or all of them. All will be same throughout the project.

also i have a new block with attributes that i have to insert to all drwings.


Can you help me with this please?

Is it doable?

frostrap 发表于 2022-7-6 12:29:47

 
What you're explaining is doable. You may not need vb.net to do it either. You may be able to accompish it with one of the more accessible languages such as lisp or VBA.
 
You may get more responces if you post your question as its own thread, or search for other people who have had similar issues in this forum.
 
- Joe

sandeepsshewale 发表于 2022-7-6 12:33:30

I have created a block in AutoCAD2009 with default layer and linetype, now i want to change the color of the block(want to edit the block) can any one help me in this regards
 
Thanks in advance!
 
Sandy

SEANT 发表于 2022-7-6 12:45:14

I assume you are interested in a .NET solution (based on the location of this new post):Is that, indeed, the API of choice?
页: [1]
查看完整版本: [vb.net] Modifying block attri