Jump to content

[vb.net] Modifying block attributes


Recommended Posts

Posted

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?

 

[size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size][/color][/size][size=2] InsertBlock([/size][size=2][color=#0000ff][size=2][color=#0000ff]ByVal[/color][/size][/color][/size][size=2] BlockPath [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]String[/color][/size][/color][/size][size=2], [/size][size=2][color=#0000ff][size=2][color=#0000ff]ByVal[/color][/size][/color][/size][size=2] thePoint [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Point3d)[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] doc [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] fname [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]String[/color][/size][/color][/size][size=2] = BlockPath[/size]
[size=2]HostApplicationServices.Current.FindFile(fname, doc.Database, FindFileHint.Default)[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] db [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Database = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] Database([/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2], [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2])[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2]db.ReadDwgFile(fname, System.IO.FileShare.Read, [/size][size=2][color=#0000ff][size=2][color=#0000ff]True[/color][/size][/color][/size][size=2], [/size][size=2][color=#0000ff][size=2][color=#0000ff]Nothing[/color][/size][/color][/size][size=2])[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] t [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Transaction = doc.TransactionManager.StartTransaction[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] idBTR [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] ObjectId = doc.Database.Insert(BlockPath, db, [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2])[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] bt [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] BlockTable = [/size][size=2][color=#0000ff][size=2][color=#0000ff]CType[/color][/size][/color][/size][size=2](t.GetObject(doc.Database.BlockTableId, OpenMode.ForRead), BlockTable)[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] btr [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] BlockTableRecord = [/size][size=2][color=#0000ff][size=2][color=#0000ff]CType[/color][/size][/color][/size][size=2](t.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] bref [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] BlockReference = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] BlockReference(thePoint, idBTR)[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] theScale [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Scale3d = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] Scale3d(GetSystemVariable([/size][size=2][color=#a31515][size=2][color=#a31515]"DIMSCALE"[/color][/size][/color][/size][size=2]), _[/size]
[size=2]GetSystemVariable([/size][size=2][color=#a31515][size=2][color=#a31515]"DIMSCALE"[/color][/size][/color][/size][size=2]), _[/size]
[size=2]GetSystemVariable([/size][size=2][color=#a31515][size=2][color=#a31515]"DIMSCALE"[/color][/size][/color][/size][size=2]))[/size]
[size=2]bref.ScaleFactors = theScale[/size]
[size=2]bref.Layer = [/size][size=2][color=#a31515][size=2][color=#a31515]"HANGERS"[/color][/size]


[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] attIDs [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AttributeCollection = bref.AttributeCollection[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]For[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Each[/color][/size][/color][/size][size=2] attID [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] ObjectId [/size][size=2][color=#0000ff][size=2][color=#0000ff]In[/color][/size][/color][/size][size=2] attIDs[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] attRef [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AttributeReference = t.GetObject(attID, OpenMode.ForWrite)[/size]
[size=2]attRef.TextString = [/size][size=2][color=#a31515][size=2][color=#a31515]"Test"[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Next[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2]btr.AppendEntity(bref)[/size]
[size=2]t.TransactionManager.AddNewlyCreatedDBObject(bref, [/size][size=2][color=#0000ff][size=2][color=#0000ff]True[/color][/size][/color][/size][size=2])[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Finally[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]CType[/color][/size][/color][/size][size=2](bref, IDisposable).Dispose()[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2]t.Commit()[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]Finally[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]CType[/color][/size][/color][/size][size=2](t, IDisposable).Dispose()[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Finally[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]CType[/color][/size][/color][/size][size=2](db, IDisposable).Dispose()[/size]
[size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size]
[/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size]
[/color][/size]

Posted

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

Posted

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.

Posted

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. :)

Posted

Is it possible to have something that will help me (to insert a block if 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?

Posted
Is it possible to have something that will help me (to insert a block if 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?

 

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

  • 1 year later...
Posted

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! :D

 

Sandy

Posted

I assume you are interested in a .NET solution (based on the location of this new post): Is that, indeed, the API of choice?

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...