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

add atribute tag and value to autocad block

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
imagination_s
968 Views, 7 Replies

add atribute tag and value to autocad block

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

7 REPLIES 7
Message 2 of 8
norman.yuan
in reply to: imagination_s

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

Drive CAD With Code

EESignature

Message 3 of 8
imagination_s
in reply to: 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

Message 4 of 8
norman.yuan
in reply to: imagination_s

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)

 Before.png

 

 

 After:

 

After.png

 

 

 

 

HTH.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 8
SENL1362
in reply to: 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?

Message 6 of 8
norman.yuan
in reply to: SENL1362

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

Drive CAD With Code

EESignature

Message 7 of 8
SENL1362
in reply to: norman.yuan

ok. Thanks for the explanation.
Message 8 of 8
imagination_s
in reply to: norman.yuan

Norman ,your the best! 🙂

Good code

Thankyou so much for your efforts

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

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report