<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Add a new attribute to a block, using doc.Database instead of doc.Editor if possible in .NET Forum</title>
    <link>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12324488#M6880</link>
    <description>&lt;P&gt;My main goal is to add an attribute to all blocks named 8x11General found in a drawing. I found a way to do it using doc.Editor to add the new attribute definition, but this way of doing is not optimal for me, since eventually I will need to run this code on all drawing found within a folder and it would oblige me to open each one of them.&lt;/P&gt;&lt;P&gt;So I'm wondering if there is a way to add an attribute to a block definition using only the doc.Database or anything else that would not require the use of the doc.Editor (which requires the opening of the dwg file).&lt;/P&gt;&lt;P&gt;Thank you in advance for your time.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My current code that adds an attribute using the doc.Editor:&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;private readonly List&amp;lt;string&amp;gt; _blocksToProcess = new List&amp;lt;string&amp;gt; { "8x11General"};

[CommandMethod("AddAttribute")]
public void AddAttributeToBlocks()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        var filter = new SelectionFilter(new[]
        {
            new TypedValue((int)DxfCode.Start, "INSERT")
        });

        PromptSelectionResult psr = ed.SelectAll(filter);

        if (psr.Status != PromptStatus.OK)
            return;

        foreach (SelectedObject so in psr.Value)
        {
            var br = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForWrite);

            if (_blocksToProcess.Contains(br.Name))
            {
                AddAttributeToBlock(br, db, tr);
            }
            else
            {
                // Add code here to check for nested blocks and add attributes
                ProcessNestedBlocks(br, db, tr);
            }
        }

        tr.Commit();
    }
}

private void AddAttributeToBlock(BlockReference br, Database db, Transaction tr)
{
    br.Highlight();

    // Get the block's insertion point
    Point3d blockInsertionPoint = br.Position;

    // Calculate the top-right corner of the block
    Point3d p = blockInsertionPoint + new Vector3d((br.GeometricExtents.MaxPoint.X + br.GeometricExtents.MinPoint.X) / 2,
        (br.GeometricExtents.MaxPoint.Y + br.GeometricExtents.MinPoint.Y) / 2,
        0);

    var attRef = new AttributeReference(p, "SHMURRR", "BOBBY", db.Textstyle)
    {
        Invisible = true, //Make the attribute invisible
        LockPositionInBlock = false,
    };
    br.AttributeCollection.AppendAttribute(attRef);
    tr.AddNewlyCreatedDBObject(attRef, true);
    db.TransactionManager.QueueForGraphicsFlush();
    br.Unhighlight();
}

private void ProcessNestedBlocks(BlockReference br, Database db, Transaction tr)
{
    // Retrieve the block table record of the current block
    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

    foreach (ObjectId objectId in btr)
    {
        if (objectId.ObjectClass == RXClass.GetClass(typeof(BlockReference)))
        {
            var nestedBlock = (BlockReference)tr.GetObject(objectId, OpenMode.ForWrite);

            if (_blocksToProcess.Contains(nestedBlock.Name))
            {
                AddAttributeToBlock(nestedBlock, db, tr);
            }
            else
            {
                // Recursively check for nested blocks
                ProcessNestedBlocks(nestedBlock, db, tr);
            }
        }
    }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Mon, 23 Oct 2023 14:12:15 GMT</pubDate>
    <dc:creator>bsaidiDG51</dc:creator>
    <dc:date>2023-10-23T14:12:15Z</dc:date>
    <item>
      <title>Add a new attribute to a block, using doc.Database instead of doc.Editor if possible</title>
      <link>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12324488#M6880</link>
      <description>&lt;P&gt;My main goal is to add an attribute to all blocks named 8x11General found in a drawing. I found a way to do it using doc.Editor to add the new attribute definition, but this way of doing is not optimal for me, since eventually I will need to run this code on all drawing found within a folder and it would oblige me to open each one of them.&lt;/P&gt;&lt;P&gt;So I'm wondering if there is a way to add an attribute to a block definition using only the doc.Database or anything else that would not require the use of the doc.Editor (which requires the opening of the dwg file).&lt;/P&gt;&lt;P&gt;Thank you in advance for your time.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My current code that adds an attribute using the doc.Editor:&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;private readonly List&amp;lt;string&amp;gt; _blocksToProcess = new List&amp;lt;string&amp;gt; { "8x11General"};

[CommandMethod("AddAttribute")]
public void AddAttributeToBlocks()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        var filter = new SelectionFilter(new[]
        {
            new TypedValue((int)DxfCode.Start, "INSERT")
        });

        PromptSelectionResult psr = ed.SelectAll(filter);

        if (psr.Status != PromptStatus.OK)
            return;

        foreach (SelectedObject so in psr.Value)
        {
            var br = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForWrite);

            if (_blocksToProcess.Contains(br.Name))
            {
                AddAttributeToBlock(br, db, tr);
            }
            else
            {
                // Add code here to check for nested blocks and add attributes
                ProcessNestedBlocks(br, db, tr);
            }
        }

        tr.Commit();
    }
}

private void AddAttributeToBlock(BlockReference br, Database db, Transaction tr)
{
    br.Highlight();

    // Get the block's insertion point
    Point3d blockInsertionPoint = br.Position;

    // Calculate the top-right corner of the block
    Point3d p = blockInsertionPoint + new Vector3d((br.GeometricExtents.MaxPoint.X + br.GeometricExtents.MinPoint.X) / 2,
        (br.GeometricExtents.MaxPoint.Y + br.GeometricExtents.MinPoint.Y) / 2,
        0);

    var attRef = new AttributeReference(p, "SHMURRR", "BOBBY", db.Textstyle)
    {
        Invisible = true, //Make the attribute invisible
        LockPositionInBlock = false,
    };
    br.AttributeCollection.AppendAttribute(attRef);
    tr.AddNewlyCreatedDBObject(attRef, true);
    db.TransactionManager.QueueForGraphicsFlush();
    br.Unhighlight();
}

private void ProcessNestedBlocks(BlockReference br, Database db, Transaction tr)
{
    // Retrieve the block table record of the current block
    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

    foreach (ObjectId objectId in btr)
    {
        if (objectId.ObjectClass == RXClass.GetClass(typeof(BlockReference)))
        {
            var nestedBlock = (BlockReference)tr.GetObject(objectId, OpenMode.ForWrite);

            if (_blocksToProcess.Contains(nestedBlock.Name))
            {
                AddAttributeToBlock(nestedBlock, db, tr);
            }
            else
            {
                // Recursively check for nested blocks
                ProcessNestedBlocks(nestedBlock, db, tr);
            }
        }
    }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 23 Oct 2023 14:12:15 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12324488#M6880</guid>
      <dc:creator>bsaidiDG51</dc:creator>
      <dc:date>2023-10-23T14:12:15Z</dc:date>
    </item>
    <item>
      <title>Re: Add a new attribute to a block, using doc.Database instead of doc.Editor if possible</title>
      <link>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12324675#M6881</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;It looks like your adding an attribute reference to inserted block references without adding an attribute definition to the block definition. Doing so, all newly inserted blocks won't have this attribute and any attribute synchronization (ATTSYNC command) will erase the attribute references.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A better practice would be adding an attribute definition to the block definition and 'synchronize' all already inserted block references.&lt;/P&gt;
&lt;P&gt;Here's a simple example you can start from:&lt;/P&gt;
&lt;LI-CODE lang="csharp"&gt;        /// &amp;lt;summary&amp;gt;
        /// Adds an attribute definition to the block definition
        /// and synchronizes all inserted references.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="db"&amp;gt;Database the block belongs to.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blockName"&amp;gt;Name of the block.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="position"&amp;gt;Position of the attribute definition in the block definition.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="value"&amp;gt;Default value of the attribute.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="tag"&amp;gt;Tag of the attribute.&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="prompt"&amp;gt;Prompt of the attribute.&amp;lt;/param&amp;gt;
        public static void AddAttributeToBlock(
            Database db, string blockName, Point3d position, string value, string tag, string prompt)
        {
            using (var tr = db.TransactionManager.StartTransaction())
            {
                // Get the block definition
                var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!blockTable.Has(blockName))
                    return;
                var blockDefinition = (BlockTableRecord)tr.GetObject(blockTable[blockName], OpenMode.ForWrite);

                // Add an attribute definition to the block definition
                var attributeDefinition = new AttributeDefinition(position, value, tag, prompt, db.TextStyleTableId);
                blockDefinition.AppendEntity(attributeDefinition);
                tr.AddNewlyCreatedDBObject(attributeDefinition, true);

                // Get  all the inserted refrences to append the new attribute reference
                foreach (ObjectId id in blockDefinition.GetBlockReferenceIds(true, false))
                {
                    var blockReference = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                    var attributeReference = new AttributeReference();
                    attributeReference.SetAttributeFromBlock(attributeDefinition, blockReference.BlockTransform);
                    blockReference.AttributeCollection.AppendAttribute(attributeReference);
                    tr.AddNewlyCreatedDBObject(attributeReference, true);
                }
                tr.Commit();
            }
        }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 23 Oct 2023 15:18:51 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12324675#M6881</guid>
      <dc:creator>_gile</dc:creator>
      <dc:date>2023-10-23T15:18:51Z</dc:date>
    </item>
    <item>
      <title>Re: Add a new attribute to a block, using doc.Database instead of doc.Editor if possible</title>
      <link>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12325287#M6882</link>
      <description>Thank you boss.</description>
      <pubDate>Mon, 23 Oct 2023 19:13:47 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/add-a-new-attribute-to-a-block-using-doc-database-instead-of-doc/m-p/12325287#M6882</guid>
      <dc:creator>bsaidiDG51</dc:creator>
      <dc:date>2023-10-23T19:13:47Z</dc:date>
    </item>
  </channel>
</rss>

