Hello Everyone,
Please help me with this
I need to add a attribute Tag and a value (position Z) to each block on my dwg
But doing this in vb.net
Here is my code so far
<CommandMethod("LISTATT")> _
Public Sub ListAttributes()
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db2 As Database = Application.DocumentManager.MdiActiveDocument.Database
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tr As Transaction = db.TransactionManager.StartTransaction()
' Start the transaction
Try
' Build a filter list so that only
' block references are selected
Dim values() As TypedValue = { _
New TypedValue(DxfCode.BlockName, "DOT")
}
Dim sfilter As New SelectionFilter(values)
Dim opts As New PromptSelectionOptions()
opts.MessageForAdding = "Select blocks: "
Dim res As PromptSelectionResult = ed.GetSelection(opts, sfilter)
' Do nothing if selection is unsuccessful
If res.Status <> PromptStatus.OK Then
Return
End If
Dim selSet As SelectionSet = res.Value
Dim idArray As ObjectId() = selSet.GetObjectIds()
For Each blkId As ObjectId In idArray
Dim blkRef As BlockReference = DirectCast(tr.GetObject(blkId, OpenMode.ForRead), BlockReference)
Dim btr As BlockTableRecord = DirectCast(tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)
ed.WriteMessage(vbLf & "Block: " + btr.Name)
btr.Dispose()
Dim attCol As AttributeCollection = blkRef.AttributeCollection
For Each attId As ObjectId In attCol
' Dim attRef As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForWrite), AttributeReference)
' attRef.Tag = "COTA" ---------it repace other attribute
' attRef.TextString = attRef.Position.Z
' Dim str As String = ((vbLf & " Attribute Tag: " + attRef.Tag &
vbLf & " Attribute String: ") + attRef.TextString)
' ed.WriteMessage(str)
Next
Next
tr.Commit()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(("Exception: " + ex.Message))
Finally
tr.Dispose()
End Try
End Sub
The problem is that it replace other atribute with COTa and the value of Position Z
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
From you code, if it dificult to tell what you are trying to do. Your description is alos a bit vague. It seems that you want to add a new attribute (AttributeReference) in all existing BlockReferences, based in the same block definition, named as "DOT".
There could be 2 situation:
1. When the block references were inserted, the block definition didi not have an atribute tagged as "COTA". But now, you modified the block definition and added a new attribute definition "COTA", and you want all the corresponding block references have this new AttributeReference added by code; (you can run "AttSync" command for this, I believe).
2. Regardless the block definition having attribute "COTA" or not, you can add as many new attributereference to a block reference as you want by code.
If so, what you need is (after obtaining the BlockReference object) to simply create a new AttributeReference, and append it to the Blcokreference.AttributeCollection.
However, if you do not have a corresponding AttributeDefinition available in the BlockDefinition as template, you need to decide the AttributeReference's text properties (style, height...) and its geometric location.
Maybe, you want to clarify which situation you are in.
Norman Yuan
YEs is correct
Number 2
2. Regardless the block definition having attribute "COTA" or not, you can add as many new attributereference to a block reference as you want by code
I dont have attribute COTA and a value based on the z coodonate of same attribute i want to ad it to same block
Pleas tell me how to do that
"what you need is (after obtaining the BlockReference object) to simply create a new AttributeReference, and append it to the Blcokreference.AttributeCollection." and this
However, if you do not have a corresponding AttributeDefinition available in the BlockDefinition as template, you need to decide the AttributeReference's text properties (style, height...) and its geometric location.
How to create a new attribute referene
is this ? -
dim new_att as atrributecollection
dim new_ref as blockeference
OK, assume there is a block definition, called "TestBlock" with no attribute included; and there are a few block references of this block have already been inserted into the drawing, say, ModelSpace; now you want to make all the block referneces show an attribute tagged as "TAG1" with a given value. Here is the code to do that:
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using CadApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(AddAttrToBref.MyCadCommands))] namespace AddAttrToBref { public class MyCadCommands { [CommandMethod("AddAtt")] public static void AddAttributeToBlock() { Document dwg = CadApp.DocumentManager.MdiActiveDocument; Editor ed = dwg.Editor; try { ObjectId[] blkIds = SelectBlocks(ed, "TestBlock"); AddNewAttributeToBlocks(dwg, blkIds, "TAG1"); } catch (System.Exception ex) { ed.WriteMessage("\nError: {0}\n{1}", ex.Message, ex.StackTrace); } finally { Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt(); } } private static ObjectId[] SelectBlocks(Editor ed, string blkName) { TypedValue[] vals = new TypedValue[] { new TypedValue((int)DxfCode.BlockName,blkName) }; PromptSelectionResult res = ed.SelectAll(new SelectionFilter(vals)); if (res.Status == PromptStatus.OK) return res.Value.GetObjectIds(); else return null; } private static void AddNewAttributeToBlocks( Document dwg, ObjectId[] blkIds, string newTag) { using (var tran=dwg.TransactionManager.StartTransaction()) { int i = 0; foreach (var blkId in blkIds) { i++; AddAttToBlockReference(dwg.Database, blkId, newTag, "No. " + i, tran); } tran.Commit(); } } private static void AddAttToBlockReference( Database db, ObjectId blkId, string tagName, string tagValue, Transaction tran) { BlockReference bref = (BlockReference)tran.GetObject(blkId, OpenMode.ForWrite); AttributeReference aref = new AttributeReference(); aref.SetDatabaseDefaults(); aref.Layer = "0"; aref.TextStyleId = db.Textstyle; aref.Height = 0.5; aref.SetAttributeFromBlock(bref.BlockTransform); aref.Tag = tagName; aref.TextString = tagValue; bref.AttributeCollection.AppendAttribute(aref); tran.AddNewlyCreatedDBObject(aref, true); } } }
See attached drawing for the effect of before and after the command runs:
Before (the block references have no attribute, based on the block definition)
After:
HTH.
Norman Yuan
Hello Norman,
Good sample and well written.
Just out of curiosity, is there any particular reason why you add both Database and Transaction in AddAttToBlockReference(..).
The Transaction could being extracted from the Database argument, so what's you're story behind this?
It was just some code coming quick into my head, did not put too much thought.
At first I only had Transaction as argument. And when creating the new Attributereference, I realized that I needed to know the current TextStyle, which I can get from the Database object, thus, I quickly added Database as another argument for that method. That was it: not too much thought, just meant to show a working sample.
Norman Yuan
Can't find what you're looking for? Ask the community or share your knowledge.