<?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 Re: Copy Block From  file to file in .NET Forum</title>
    <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7486378#M29249</link>
    <description>&lt;P&gt;After several days, I can say I have reached a&lt;STRONG&gt; solution&lt;/STRONG&gt;&amp;nbsp;(yes I can say solution.... unbeliavable) suitable for my purpose.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here the code for&amp;nbsp;benefit of other.&lt;/P&gt;&lt;P&gt;I have to say the true, coding .net with Autocad is not for dummy and some of the code here is not clear to me at all (but works...)&lt;/P&gt;&lt;P&gt;In any case I leave the original code from&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/543921"&gt;@norman.yuan&lt;/a&gt;&amp;nbsp;in which I edited&amp;nbsp;and replaced with other fonts (ie: web, samples from official reference... suggestion by&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4476837"&gt;@ActivistInvestor&lt;/a&gt;,&amp;nbsp;and my guess...) and adding some comment (hope they make sense).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The code doesn't replace ATTRIBUTES (the new block has to have own ATTRIBUTES in it, as suggested by&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4476837"&gt;@ActivistInvestor&lt;/a&gt;&amp;nbsp;as faster way)&lt;/P&gt;&lt;P&gt;The code can transfer some attribute.text from the old block to th new one.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The last question:&lt;/P&gt;&lt;P&gt;Could someone explain to me how come the editor doesn't refresh the screen after each foreach operation?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;star processing new file:&lt;/P&gt;&lt;PRE&gt;ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));&lt;/PRE&gt;&lt;P&gt;...............&lt;/P&gt;&lt;P&gt;..............&lt;/P&gt;&lt;P&gt;end processing the file&lt;/P&gt;&lt;PRE&gt;ed.UpdateScreen();&lt;/PRE&gt;&lt;P&gt;but I see my screen updated just at the end of whole program... strangely enogh.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        [CommandMethod("REPBLK")]
        public static void RunDocCommand()
        {

            string pathDwgFiles = @"MAYPATH";
            string newBlockFile = @"DWGFILEWITHNEWBLOCK";
            string oldBlkName = "OLDBLOCKNAME";
            string newBlkName = "NEWBLOCKNAME";

            var workingDb = HostApplicationServices.WorkingDatabase;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;


            try
            {
                ed.WriteMessage("\nSTART BLOCK REPLACE PROCESS\n");

                string[] dwgFiles = Directory.GetFiles(pathDwgFiles, "*.dwg", SearchOption.AllDirectories);
                foreach (var dwgfile in dwgFiles)
                {
                    // Open target drawing as side database.
                    // It makes the processing a lot faster than opening
                    // drawing in Editor visibly.
                    // One can choose open the drawing in Editor, if desired.
                    ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));
                    using (var db = OpenSideDatabase(dwgfile))
                    {
                        HostApplicationServices.WorkingDatabase = db;
                        if (!ReplaceBlocks(db, oldBlkName, newBlkName, newBlockFile))
                            ed.WriteMessage("\nOld Block NOT foud in: " + Path.GetFileName(dwgfile));
                        else
                            RemoveBlockFromDb(db, oldBlkName); //remove oldBlock

                        db.RetainOriginalThumbnailBitmap = true;
                        db.SaveAs(dwgfile, true, DwgVersion.Current, null);
                    }
                    ed.UpdateScreen();
                }
            }
            catch (System.Exception ex)
            {
                CadApp.ShowAlertDialog("Error:\r\n" + ex.Message);
            }
            finally
            {
                ed.WriteMessage("\nEND BLOCK REPLACE PROCESS\n");
                HostApplicationServices.WorkingDatabase = workingDb;
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();

            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Open the DWG as Database
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="dwgFileName"&amp;gt;the dwg file name full path&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the Database&amp;lt;/returns&amp;gt;
        private static Database OpenSideDatabase(string dwgFileName)
        {
            var db = new Database(false, true);
            db.ReadDwgFile(dwgFileName, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
            return db;
        }

        private static bool ReplaceBlocks(Database db, string oldBlkName, string newBlkName, string newBlockFile)
        {
            // Find all "OldBlock" references and collect their attribute data
            // If only blockreference on certain layout is targeted, this is where
            // one can decide which layout to be excluded
            var dwgAttData = CollectOldBlockAttributeData(db, oldBlkName);
            if (dwgAttData.Count == 0)
            {
                //CadApp.ShowAlertDialog("No \"" + oldBlkName + "\" found!");
                return false;
            }

            // Make sure "NewBlock" is defined in the drawing. If not, get it from 
            // a block drawing file (Database.Insert(); or the the block definition
            // is in a drawing where many blocks are defined, use 
            // use Database.WblockCloneObjects() to bring this block definition
            // into this drawing
            var newBlkDefId = EnsureNewBlockDefinition(db, newBlkName, newBlockFile);
            if (newBlkDefId.IsNull)
            {
                CadApp.ShowAlertDialog("NewBlock definition is not found in source drawing!");
                return false;
            }

            // Replacing "OldBlock" references by
            // 1. Insert "NewBlock" at the same position/same layer
            // 2. Sych  attribute values (because both old and new blocks have the same Attrs.
            // 3. Erase "OldBlock" reference

            ReplaceOldBlocks(db, newBlkDefId, dwgAttData, newBlkName);

            return true;
        }



        #region find all "OldBlock" and their attribute information
        private static DrawingAttributeData CollectOldBlockAttributeData(Database db, string oldBlkName)
        {
            var attData = new DrawingAttributeData();
            using (var tran = db.TransactionManager.StartTransaction())
            {
                var dic = (DBDictionary)tran.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
                foreach (DBDictionaryEntry entry in dic)
                {
                    var layout = (Layout)tran.GetObject(entry.Value, OpenMode.ForRead);
                    var layoutAttData = CollectOldBlockAttributeDataOnLayout(oldBlkName, layout.BlockTableRecordId, tran);
                    if (layoutAttData.Count &amp;gt; 0)
                    {
                        attData.Add(layout.BlockTableRecordId, layoutAttData);
                    }
                }
                tran.Commit();
            }
            return attData;
        }

        private static List&amp;lt;BlockAttributeData&amp;gt; CollectOldBlockAttributeDataOnLayout(
                                                string oldBlkName, ObjectId layoutBlockId, Transaction tran)
        {
            var layoutAttData = new List&amp;lt;BlockAttributeData&amp;gt;();
            var layoutBlock = (BlockTableRecord)tran.GetObject(layoutBlockId, OpenMode.ForRead);
            foreach (ObjectId id in layoutBlock)
            {
                if (id.ObjectClass.DxfName.ToUpper() == "INSERT")
                {
                    var blk = (BlockReference)tran.GetObject(id, OpenMode.ForRead);
                    if (blk.Name.ToUpper().Contains(oldBlkName.ToUpper())) //I use contain for similar names in my list
                    {
                        var blkAttData = CollectOldBlockAttributes(blk, tran);
                        if (blkAttData.Attributes.Count &amp;gt; 0)
                        {
                            layoutAttData.Add(blkAttData);
                        }
                    }
                }
            }
            return layoutAttData;
        }

        private static BlockAttributeData CollectOldBlockAttributes(BlockReference bref, Transaction tran)
        {
            //bref.Name is the layout name.

            var blkAttData = new BlockAttributeData();
            blkAttData.BlkRefId = bref.ObjectId;
            blkAttData.Layer = bref.Layer;

            foreach (ObjectId id in bref.AttributeCollection)
            {
                var att = (AttributeReference)tran.GetObject(id, OpenMode.ForRead);
                if (att.IsConstant)
                    continue;

                if (!blkAttData.Attributes.ContainsKey(att.Tag.ToUpper()))
                {
                    blkAttData.Attributes.Add(att.Tag.ToUpper(), att.TextString);
                }
            }
            return blkAttData;
        }

        #endregion

        #region make sure "NewBlock" definition exists

        private static ObjectId EnsureNewBlockDefinition(Database db, string newBlkName, string newBlockFile)
        {
            var blkId = ObjectId.Null;

            using (var tran = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tran.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(newBlkName))
                    blkId = bt[newBlkName]; //verify if the current drawing has the new block
                tran.Commit();
            }

            if (blkId.IsNull) //if the block isn't in, get it
            {
                blkId = InsertNewBlockDefinition(db, newBlkName, newBlockFile);
            }
            return blkId;
        }

        /// &amp;lt;summary&amp;gt;
        /// Clones in db the block from the file
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="db"&amp;gt;destination database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkName"&amp;gt;block name&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkFile"&amp;gt;block's source file full path&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the block's objId&amp;lt;/returns&amp;gt;
        private static ObjectId InsertNewBlockDefinition(Database db, string blkName, string blkFile)
        {
            var blkId = ObjectId.Null;
            using (var blkDb = new Database(false, true))
            {
                blkDb.ReadDwgFile(blkFile, FileOpenMode.OpenForReadAndReadShare, false, null);

                //this Works:
                //need to crate collectionObject for wblockClone method:
                ObjectIdCollection objColl = new ObjectIdCollection();
                
                objColl.Add(GetBlkId(blkDb, blkName));
                IdMapping map = new IdMapping();
                
                //cloneObject
                blkDb.WblockCloneObjects(objColl, db.BlockTableId, map, DuplicateRecordCloning.Replace, false);
                blkId = GetBlkId(db, blkName); //keep the id of cloned block

                //if I use deepclone, as is doesn't work
                //blkDb.DeepCloneObjects(objColl, db.BlockTableId, map, false);
                
                //if I use Insert, as is doesn't work:
                //blkId = db.Insert(blkName, blkDb, false);
            }
            return blkId;
        }


        #endregion

        #region do the replacing work

        private static void ReplaceOldBlocks(Database db, ObjectId newBlkDefId,
                                             DrawingAttributeData dwgAttData, string newBlkName)
        {
            using (var tran = db.TransactionManager.StartTransaction())
            {
                foreach (var item in dwgAttData)
                {
                    //item.key is an objectId
                    var layoutBlock = (BlockTableRecord)tran.GetObject(item.Key, OpenMode.ForWrite);
                    var newBlock = (BlockTableRecord)tran.GetObject(newBlkDefId, OpenMode.ForRead);

                    //foreach layout
                    foreach (var blkData in item.Value)
                    {
                        //get the position
                        var oldBlk = (BlockReference)tran.GetObject(blkData.BlkRefId, OpenMode.ForRead);
                        var position = oldBlk.Position; 


                        CreateNewBlockReference(db, layoutBlock, newBlock, position, blkData.Layer,
                                                blkData.Attributes, tran);

                        //erase block doesn't work - i will erase later see: RemoveBlockFromDb
                        //oldBlk.UpgradeOpen();
                        //oldBlk.Erase();
                        //oldBlk.Dispose();
                    }
                }
                tran.Commit();
            }
        }

        private static void CreateNewBlockReference(Database db, BlockTableRecord layoutBlock,
                                                    BlockTableRecord newBlock, Point3d position,
                                                    string layer, Dictionary&amp;lt;string, string&amp;gt; attData,
                                                    Transaction tran)
        {
            var bref = new BlockReference(position, newBlock.ObjectId);

            bref.SetDatabaseDefaults(db);
            bref.Layer = layer;
            
            var brefId = layoutBlock.AppendEntity(bref);
            tran.AddNewlyCreatedDBObject(bref, true);
  
            SetAttributes(brefId, newBlock, attData, tran);
        }


        private static void SetAttributes(ObjectId brefId, BlockTableRecord newBlock,
                                          Dictionary&amp;lt;string, string&amp;gt; attData, Transaction tran)
        {
            var bref = (BlockReference)tran.GetObject(brefId, OpenMode.ForWrite);
            
            foreach (ObjectId id in newBlock)
            {
                //FROM .NET SAMPLE GUIDE
                DBObject dbObj = (DBObject)tran.GetObject(id, OpenMode.ForRead);
                if (dbObj is AttributeDefinition)
                {
                    AttributeDefinition attDef = dbObj as AttributeDefinition;
                    if (!attDef.Constant)
                    {
                        using (AttributeReference attRef = new AttributeReference())
                        {
                            attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);
                            if (attDef.Tag.Contains("THE TAG I WANT TO REPLACE"))
                            {
                                //replace value gets from the old block
                                attRef.TextString = attData["THE TAG I WANT TO REPLACE"];
                            }
                            else
                            {
                                //Do nothing and leave value of new block
                            }
                            bref.AttributeCollection.AppendAttribute(attRef);
                            tran.AddNewlyCreatedDBObject(attRef, true);
                        }
                    }
                }

                //OLD VERSION 
                //var attDef = tran.GetObject(id, OpenMode.ForRead) as AttributeDefinition;
                //if (attDef != null)
                //{
                //    var att = new AttributeReference();
                //    att.SetAttributeFromBlock(attDef, bref.BlockTransform);
 
                //    if (!attDef.Constant &amp;amp;&amp;amp; attData.ContainsKey("OGGETTO"))
                //    {
                //        if (attData.ContainsKey(att.Tag.ToUpper()))
                //            att.TextString = attData[att.Tag.ToUpper()];
                //    }
                //    bref.AttributeCollection.AppendAttribute(att);
                //    tran.AddNewlyCreatedDBObject(att, true);
                //}
            }
        }

        #endregion

        #region MyAdd
        /// &amp;lt;summary&amp;gt;
        /// Gets the block's ObjID from the database
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="db"&amp;gt;the Database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkName"&amp;gt;the block name&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the objID&amp;lt;/returns&amp;gt;
        public static ObjectId GetBlkId(Database db, string blkName)
        {
            ObjectId blkId = ObjectId.Null;

            if (db == null)
                return ObjectId.Null;

            if (string.IsNullOrWhiteSpace(blkName))
                return ObjectId.Null;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(blkName))
                    blkId = bt[blkName];
                else //looking for similar name...
                {
                    foreach (ObjectId item in bt)
                    {
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(item, OpenMode.ForRead);
                        if (btr.Name.ToUpper().Contains(blkName.ToUpper()))
                        {
                            blkId = item;
                            break;
                        }
                    }
                }
                tr.Commit();
            }
            return blkId;
        }

        /// &amp;lt;summary&amp;gt;
        /// Get the Value of Attribute from block
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="btrId"&amp;gt;The object database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blockName"&amp;gt;the block name&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="attbName"&amp;gt; the attribute name&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the attribute value&amp;lt;/returns&amp;gt;
        private static string GetAttribValueFromBlock(ObjectId btrId, string blockName, string attbName)
        {
            Database db = btrId.Database;
            string txtValue = string.Empty;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

                // Test each entity in the container...
                foreach (ObjectId entId in btr)
                {
                    Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
                    if (ent != null)
                    {
                        BlockReference br = ent as BlockReference;
                        if (br != null)
                        {
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

                            // ... to see whether it's a block with
                            // the name we're after
                            if (bd.Name.ToUpper() == blockName)
                            {

                                // Check each of the attributes...
                                foreach (ObjectId arId in br.AttributeCollection)
                                {
                                    DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
                                    AttributeReference ar = obj as AttributeReference;
                                    if (ar != null)
                                    {
                                        // ... to see whether it has
                                        // the tag we're 
                                        if (ar.Tag.ToUpper() == attbName)
                                            txtValue = ar.TextString;
                                    }
                                }
                            }

                            // Recurse for nested blocks
                            //doesn't needed for my block
                            //changedCount += UpdateAttributesInBlock(br.BlockTableRecord,blockName,attbName,attbValue);
                        }
                    }
                }
                tr.Commit();
            }
            return txtValue;
        }

        private static bool SetAttributeInBlock(ObjectId btrId, string blockName, string attbName, string attbValue)
        {
            Database db = btrId.Database;
            bool gotcha = false;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

                // Test each entity in the container...
                foreach (ObjectId entId in btr)
                {
                    Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
                    if (ent != null)
                    {
                        BlockReference br = ent as BlockReference;
                        if (br != null)
                        {
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

                            // ... to see whether it's a block with
                            // the name we're after
                            if (bd.Name.ToUpper() == blockName)
                            {

                                // Check each of the attributes...
                                foreach (ObjectId arId in br.AttributeCollection)
                                {
                                    DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
                                    AttributeReference ar = obj as AttributeReference;
                                    if (ar != null)
                                    {
                                        // ... to see whether it has
                                        // the tag we're 
                                        if (ar.Tag.ToUpper() == attbName)
                                        {
                                            // If so, update the value
                                            // and increment the counter
                                            ar.UpgradeOpen();
                                            ar.TextString = attbValue;
                                            ar.DowngradeOpen();
                                            gotcha = true;
                                        }
                                    }
                                }
                            }

                            // Recurse for nested blocks
                            //doesn't needed for my block
                            //changedCount += UpdateAttributesInBlock(br.BlockTableRecord,blockName,attbName,attbValue);
                        }
                    }
                }
                tr.Commit();
            }
            return gotcha;
        }


        public static void RemoveBlockFromDb(Database db, string blkName)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;


            ObjectId blkId = GetBlkId(db, blkName);
            if (!EraseBlkRefs(blkId))
                ed.WriteMessage(string.Format("\n failed to erase blockreferences for: {0}", blkId.ToString()));

            if (!EraseBlk(blkId))
                ed.WriteMessage(string.Format("\n Failed to Erase Block: {0}", blkId.ToString()));
            else
                ed.WriteMessage("\nErased" + blkId.ToString()); 

        }
        public static bool EraseBlkRefs(ObjectId blkId)
        {
            bool blkRefsErased = false;

            if (blkId.IsNull)
                return false;

            Database db = blkId.Database;
            if (db == null)
                return false;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForRead);
                var blkRefs = blk.GetBlockReferenceIds(true, true);
                if (blkRefs != null &amp;amp;&amp;amp; blkRefs.Count &amp;gt; 0)
                {
                    foreach (ObjectId blkRefId in blkRefs)
                    {
                        BlockReference blkRef = (BlockReference)tr.GetObject(blkRefId, OpenMode.ForWrite);
                        blkRef.Erase();
                    }
                    blkRefsErased = true;
                }
                tr.Commit();
            }
            return blkRefsErased;
        }
        public static bool EraseBlk(ObjectId blkId)
        {
            bool blkIsErased = false;

            if (blkId.IsNull)
                return false;

            Database db = blkId.Database;
            if (db == null)
                return false;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForRead);
                var blkRefs = blk.GetBlockReferenceIds(true, true);
                if (blkRefs == null || blkRefs.Count == 0)
                {
                    blk.UpgradeOpen();
                    blk.Erase();
                    blkIsErased = true;
                }
                tr.Commit();
            }
            return blkIsErased;
        }
        #endregion&lt;/PRE&gt;</description>
    <pubDate>Tue, 24 Oct 2017 10:12:08 GMT</pubDate>
    <dc:creator>micle.space</dc:creator>
    <dc:date>2017-10-24T10:12:08Z</dc:date>
    <item>
      <title>Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7458068#M29233</link>
      <description>&lt;P&gt;After several days of coding and researchs, i have to require an help due to the very poor results reached up to now, so here you are my frst post.&lt;BR /&gt;I have a very huge directory archive with several DWG drawings.&lt;/P&gt;&lt;P&gt;Each drawing in these directories has a block named "OldBlock" with some attributes: Attrib1, Attib2, Attrib3....(the block is always the same, the attributes TAG are always the same, the attributes values change from file to file)&lt;/P&gt;&lt;P&gt;I have to replace, in each dwg file, this "OldBlock" with a new one named "NewBlock" and put the values of attributes of he old block to the new one.&lt;/P&gt;&lt;P&gt;Other Conditions:&lt;BR /&gt;- The OldBlock is on a certain paper_space of dwg drawing so the NewBlock must have the same location and position.&lt;BR /&gt;- the OldBlock has to be delete.&lt;BR /&gt;- The NewBlock is in a dwg file named "SourceDwgFile"&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;I have very clear the steps I need for the whole routine, but I cannot recognize the right hierarchy of blockTable, how identify the attributes, how manage transction and so on...&lt;BR /&gt;&lt;BR /&gt;I would prefer coding with C# but VB could be suitble.&lt;BR /&gt;Could someone direct me to on the right road?&lt;/P&gt;</description>
      <pubDate>Fri, 13 Oct 2017 12:35:48 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7458068#M29233</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-13T12:35:48Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7458244#M29234</link>
      <description>&lt;P&gt;Not a solution, but maybe a start....&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;Database acCurDb = _document.Database;&lt;BR /&gt;&lt;BR /&gt;using (Transaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())&lt;BR /&gt;{&lt;BR /&gt; // Open the Block table record for read &lt;BR /&gt; var acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;&lt;BR /&gt; &lt;BR /&gt; // Open the Block table record Paper space for read &lt;BR /&gt; var acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;&lt;BR /&gt;&lt;BR /&gt; // Step through each object in Model space and&lt;BR /&gt; // display the type of object found &lt;BR /&gt; foreach (var acObjId in acBlkTblRec)&lt;BR /&gt; {&lt;BR /&gt; var br = acTrans.GetObject(acObjId, OpenMode.ForRead) as BlockReference;&lt;BR /&gt;&lt;BR /&gt; if (br != null)&lt;BR /&gt; {&lt;BR /&gt;// tags you are interested in...&lt;BR /&gt; var taglist = new string[] {"CAT", "CAT01", "CAT02", "CAT03"};&lt;BR /&gt; foreach (var t in taglist)&lt;BR /&gt; {&lt;BR /&gt; &lt;BR /&gt; // Your copying code....&lt;BR /&gt;&lt;BR /&gt; }&lt;BR /&gt; br.Dispose();&lt;BR /&gt; }&lt;BR /&gt; }&lt;BR /&gt; acBlkTbl.Dispose();&lt;BR /&gt; acBlkTblRec.Dispose();&lt;BR /&gt;}&lt;BR /&gt;
&lt;/PRE&gt;&lt;P&gt;Some hints at what you could do:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;_document is&amp;nbsp;Snippet&lt;/P&gt;&lt;PRE&gt;Autodesk&lt;SPAN&gt;.&lt;/SPAN&gt;AutoCAD&lt;SPAN&gt;.&lt;/SPAN&gt;ApplicationServices&lt;SPAN&gt;.&lt;/SPAN&gt;Core&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;SPAN&gt;Application&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;DocumentManager&lt;SPAN&gt;.&lt;/SPAN&gt;MdiActiveDocument&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;So have a second one for copying to.&amp;nbsp; You would have to find out how to create new or copy block references from one to the other and populate attrs in new document.&lt;/P&gt;</description>
      <pubDate>Fri, 13 Oct 2017 13:34:25 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7458244#M29234</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-10-13T13:34:25Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7459279#M29235</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;After several days of coding and researchs, i have to require an help due to the very poor results reached up to now, so here you are my frst post.&lt;BR /&gt;I have a very huge directory archive with several DWG drawings.&lt;/P&gt;&lt;P&gt;Each drawing in these directories has a block named "OldBlock" with some attributes: Attrib1, Attib2, Attrib3....(the block is always the same, the attributes TAG are always the same, the attributes values change from file to file)&lt;/P&gt;&lt;P&gt;I have to replace, in each dwg file, this "OldBlock" with a new one named "NewBlock" and put the values of attributes of he old block to the new one.&lt;/P&gt;&lt;P&gt;Other Conditions:&lt;BR /&gt;- The OldBlock is on a certain paper_space of dwg drawing so the NewBlock must have the same location and position.&lt;BR /&gt;- the OldBlock has to be delete.&lt;BR /&gt;- The NewBlock is in a dwg file named "SourceDwgFile"&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;I have very clear the steps I need for the whole routine, but I cannot recognize the right hierarchy of blockTable, how identify the attributes, how manage transction and so on...&lt;BR /&gt;&lt;BR /&gt;I would prefer coding with C# but VB could be suitble.&lt;BR /&gt;Could someone direct me to on the right road?&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;If you've attempted to write code to do this and it isn't working, you should post the code and then you might get some help with it.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 13 Oct 2017 18:52:17 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7459279#M29235</guid>
      <dc:creator>ActivistInvestor</dc:creator>
      <dc:date>2017-10-13T18:52:17Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7462257#M29236</link>
      <description>&lt;P&gt;Dear all, first of all thank you for your attention.&lt;/P&gt;&lt;P&gt;Here a frame of routine I would like to execute.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The idea is:&lt;/P&gt;&lt;P&gt;1 - store a BlockTableRecord &lt;STRONG&gt;btSource&lt;/STRONG&gt; from the new file with the new block.&lt;/P&gt;&lt;P&gt;2 - Foreach file in directories:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;find the old block (blockToBeReplaced)&lt;/LI&gt;&lt;LI&gt;keep position and attributes values from the old block and save them into &lt;STRONG&gt;btSource&lt;/STRONG&gt;&lt;/LI&gt;&lt;LI&gt;Remove from the file the old block&lt;/LI&gt;&lt;LI&gt;Store in the file the new one&lt;/LI&gt;&lt;LI&gt;Save file.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;cheers&lt;/P&gt;&lt;P&gt;M.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        [CommandMethod("BREP")]
        public void BlockReplace()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            string[] allDwgFiles = Directory.GetFiles("dwgFilesToBeReplaced", "*.dwg", SearchOption.AllDirectories);

            //set the source database
            Database sourceDb = new Database(false, true);
            sourceDb.ReadDwgFile(dwgSourcePath, System.IO.FileShare.Read, false, "");
            BlockTableRecord sourceTbr;

            using (Transaction tr = sourceDb.TransactionManager.StartOpenCloseTransaction())
            {
                //Table record
                BlockTable btSource = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
               
                foreach (ObjectId objId in btSource)
                {
                    BlockTableRecord btrSource = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForRead);
                    if (btrSource.Name == blockNew)
                    {
                        sourceTbr = (BlockTableRecord)btrSource.Clone();
                    }
                }
                tr.Commit();
            }

            //replace the block in each file
            foreach (string currDwg in allDwgFiles)
            {
                //open the file
                Database currDb = new Database(false, true);
                currDb.ReadDwgFile(dwgSourcePath, System.IO.FileShare.ReadWrite, false, "");

                using (Transaction tr = currDb.TransactionManager.StartTransaction())
                {
                    //open the block in the current file
                    BlockTable currBt = (BlockTable)tr.GetObject(currDb.BlockTableId, OpenMode.ForRead);
                    
                    //research of old block
                    foreach (ObjectId objId in currBt)
                    {
                        BlockTableRecord currBtr = (BlockTableRecord)tr.GetObject(objId, OpenMode.ForRead);
                        if (currBtr.Name == blockToBeReplaced)
                        {
                            //references from source block
                            BlockReference sourceRef = sourceTbr as BlockReference; //????

                            //fill the source database with the attributes
                            BlockReference currBlkRef = (BlockReference)objId.GetObject(OpenMode.ForRead);
                            AttributeCollection currAttColl = currBlkRef.AttributeCollection;

                            //set the position of the block
                            sourceRef.Position = currBlkRef.Position;
                            
                            //set the attributes
                            foreach (ObjectId id in currAttColl)
                            {
                                DBObject dbObj = (DBObject)tr.GetObject(id, OpenMode.ForRead);
                                AttributeReference attRef = dbObj as AttributeReference;
                                sourceRef[attRef.Tag] = attRef.TextString; //?????
                            }

                        }
                    }
                    //filled the btrSource with old values, I provide o replace the old block with the new one.
                    BlockTableRecord currBtr = (BlockTableRecord)tr.GetObject(currBt.ObjectId, OpenMode.ForWrite);
                    currBtr.RemoveOldBlock......;       //&amp;lt;&amp;lt;&amp;lt; how could I do it?
                    currBtr.AppendEntity(sourceTbr);    //Append new block ... how Could I do it?

                    //Save and close current file ---&amp;gt; how?

                    tr.Commit();

                }
            }
        }&lt;/PRE&gt;</description>
      <pubDate>Mon, 16 Oct 2017 06:49:42 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7462257#M29236</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-16T06:49:42Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7466459#M29237</link>
      <description>&lt;P&gt;new&amp;nbsp;frustration day...&amp;nbsp; zero results, I can just copy the block in the file, but cannot put it on the desidered layout...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        public static void AddNewBlock(Database dbDest, ObjectId newBlk)
        {
            using (Transaction tr = dbDest.TransactionManager.StartTransaction())
            {
                //block Table detination
                BlockTable btDest = (BlockTable)tr.GetObject(dbDest.BlockTableId, OpenMode.ForWrite);

                //blocktableSorse                
                BlockTableRecord newBtr = (BlockTableRecord)newBlk.GetObject(OpenMode.ForRead);
                Database sourceDb = newBtr.Database;

                //open a new transaction and get the blocktable
                BlockTable newBt = null;
                using (Transaction trNew = sourceDb.TransactionManager.StartTransaction())
                {
                    newBt = (BlockTable)trNew.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                    trNew.Commit();
                }
                    


                //layout of target file 
                DBDictionary layDic = (DBDictionary)tr.GetObject(dbDest.LayoutDictionaryId, OpenMode.ForRead);

                ////colection of obj to copy in the file
                ObjectIdCollection objColl = new ObjectIdCollection();

                //I want put my object in each layout of target drawing so:
                foreach (DBDictionaryEntry entry in layDic)
                {
                    if (entry.Key != "Model")
                    {
                        Layout lay = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
                        BlockTableRecord btrLay = (BlockTableRecord)tr.GetObject(lay.BlockTableRecordId, OpenMode.ForWrite);
                        BlockReference br = new BlockReference(new Point3d(0, 0, 0), newBt["CartiglioA4_Baschild_Rev1"]);                        
                        objColl.Add(br.ObjectId);
                        //btrLay.AppendEntity(br);
                        //tr.AddNewlyCreatedDBObject(br, true);
                    }
                }

                if (objColl == null)
                {
                    throw new System.Exception("Collecion Null");
                }

                //here exception for objectnull
                if (!btDest.Has(newBtr.Name)) 
                {
                    IdMapping map = new IdMapping(); 
                    sourceDb.WblockCloneObjects(objColl, btDest.ObjectId, map, DuplicateRecordCloning.Replace, false);
                }
                tr.Commit();
            }
        }&lt;/PRE&gt;&lt;P&gt;What can I do?&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2017 10:07:02 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7466459#M29237</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-17T10:07:02Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7467155#M29238</link>
      <description>&lt;P&gt;While you said you have "very clear steps", your code shown in your later post says otherwise.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In your latest posted code, you are trying to copy/place BlockReference from source drawing into BlockTable of the destination drawing, which would fail for sure.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The process itself, as you described, is not too complicated: the 2 main tasks are to identify BlockReferences to be replaced, and import/insert/identify a new block definition (BlockTableRecord) into the drawing, so that you can create new BlockReferencesto replace the existing ones.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For the first one, you can either loop through each layout to find BlockReferences with that name (if it is dynamic block, extra attention is needed, regarding its name). Or you can simply use Editor.SelectAll with proper filter to select all block refernces regardless layout (assume the drawing is opened in AutoCAD editor).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For the second task, it is not very clear fromo your description: is the source drawing a NewBlock itself, or is the NewBlock one of the block definitions stored in source drawing? If it is the former, then ut is very simple: you simply insert this drawing as block definition; if it is latter, then you indeed need to WBlockCloneObjects() this block defeinition (BlockTableRecord!) from the source drawing into destination drawing's BlockTable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So here is the pseudo-code of what you do:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For each DrawingFileName in DrawingFileNameList&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; Open the drawing in AutoCAD/Or oepn the drawing as side database&lt;/P&gt;
&lt;P&gt;&amp;nbsp; Test if the NewBlock definition exists.&lt;/P&gt;
&lt;P&gt;&amp;nbsp; If NewBlock definition is ot found Then&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; Database.Insert()/SourceDatabase.WblockCloneObjects() //depending on the source drawing&lt;/P&gt;
&lt;P&gt;&amp;nbsp; End&lt;/P&gt;
&lt;P&gt;&amp;nbsp; Search drawing/DB for the OldBlock to get a list of ObjectId (of the OldBlock references&lt;/P&gt;
&lt;P&gt;&amp;nbsp; For each oldBlock Id in olbBlockIds&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; Open the oldBlockrefernce to obtain attribute values, keyed by attribute tags, and its position&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; Insert blockreferences of NewBlock at the position, set its attributes&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; Delete the pldBlock reference&lt;/P&gt;
&lt;P&gt;&amp;nbsp; Next&lt;/P&gt;
&lt;P&gt;&amp;nbsp; Savethe drawing/DB, and close it&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2017 13:25:07 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7467155#M29238</guid>
      <dc:creator>norman.yuan</dc:creator>
      <dc:date>2017-10-17T13:25:07Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7470836#M29239</link>
      <description>&lt;P&gt;Thank you Norman, you are right, I'm bit confuse (due to the low knoweledge of hierarchy autocad class) , this is my first program and it is not my job... but I would like to socceed.&lt;/P&gt;&lt;P&gt;in these days with a bit of your suggestions and a bit other researchs on the web I got some results but the routine is not working properly yet.&lt;/P&gt;&lt;P&gt;I wonder if could be possible have the same approach of your suggestion&amp;nbsp;and research by layout.&lt;/P&gt;&lt;P&gt;Following the pseudo-code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For each DrawingFileName in DrawingFileNameList&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; Open the drawing in AutoCAD/Or oepn the drawing as side database&lt;/P&gt;&lt;P&gt;&amp;nbsp; Test if the NewBlock definition exists.&lt;/P&gt;&lt;P&gt;&amp;nbsp; If NewBlock definition is not found Then&amp;nbsp; &lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;This search has to be done for each Layout (not for Model_Space)&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; Database.Insert()/SourceDatabase.WblockCloneObjects() //depending on the source drawing&lt;/P&gt;&lt;P&gt;&amp;nbsp; End&lt;/P&gt;&lt;P&gt;&amp;nbsp; Search drawing/DB for the OldBlock to get a list of ObjectId (of the OldBlock references&lt;/P&gt;&lt;P&gt;&amp;nbsp; For each oldBlock Id in olbBlockIds&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; Open the oldBlockrefernce to obtain attribute values, keyed by attribute tags, and its position&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; Insert blockreferences of NewBlock at the position, set its attributes&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; Delete the pldBlock reference&lt;/P&gt;&lt;P&gt;&amp;nbsp; Next&lt;/P&gt;&lt;P&gt;&amp;nbsp; Savethe drawing/DB, and close it&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks in advance for supports and advices.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Oct 2017 14:03:43 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7470836#M29239</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-18T14:03:43Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7472793#M29240</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;
&lt;P&gt;Thank you Norman, you are right, I'm bit confuse (due to the low knoweledge of hierarchy autocad class) , this is my first program and it is not my job... but I would like to socceed.&lt;/P&gt;
&lt;P&gt;in these days with a bit of your suggestions and a bit other researchs on the web I got some results but the routine is not working properly yet.&lt;/P&gt;
&lt;P&gt;I wonder if could be possible have the same approach of your suggestion&amp;nbsp;and research by layout.&lt;/P&gt;
&lt;P&gt;Following the pseudo-code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For each DrawingFileName in DrawingFileNameList&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; ......&lt;/P&gt;
&lt;P&gt;&amp;nbsp; If NewBlock definition is not found Then&amp;nbsp; &lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;This search has to be done for each Layout (not for Model_Space)&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; Database.Insert()/SourceDatabase.WblockCloneObjects() //depending on the source drawing&lt;/P&gt;
&lt;P&gt;&amp;nbsp; End&lt;/P&gt;
&lt;P&gt;&amp;nbsp; ......&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Block definition (BlockTableRecord) is "per database" (per drawing), not "per layout"!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It is the next step (searching "OldBlock" references to be replaced where you may want to limit the search on specific layout.&lt;/P&gt;</description>
      <pubDate>Thu, 19 Oct 2017 01:17:37 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7472793#M29240</guid>
      <dc:creator>norman.yuan</dc:creator>
      <dc:date>2017-10-19T01:17:37Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7473008#M29241</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/543921"&gt;@norman.yuan&lt;/a&gt; wrote:&lt;BR /&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;Thank you Norman, you are right, I'm bit confuse (due to the low knoweledge of hierarchy autocad class) , this is my first program and it is not my job... but I would like to socceed.&lt;/P&gt;&lt;P&gt;in these days with a bit of your suggestions and a bit other researchs on the web I got some results but the routine is not working properly yet.&lt;/P&gt;&lt;P&gt;I wonder if could be possible have the same approach of your suggestion&amp;nbsp;and research by layout.&lt;/P&gt;&lt;P&gt;Following the pseudo-code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For each DrawingFileName in DrawingFileNameList&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ......&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;FONT color="#FF0000"&gt; If NewBlock definition is not found Then&amp;nbsp; &lt;STRONG&gt;&amp;nbsp;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;This search has to be done for each Layout (not for Model_Space)&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; Database.Insert()/SourceDatabase.WblockCloneObjects() //depending on the source drawing&lt;/P&gt;&lt;P&gt;&amp;nbsp; End&lt;/P&gt;&lt;P&gt;&amp;nbsp; ......&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Next&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Block definition (BlockTableRecord) is "per database" (per drawing), not "per layout"!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It is the next step (searching "OldBlock" references to be replaced where you may want to limit the search on specific layout.&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;You can get the ObjectIds of all insertions of a block in a drawing from the BlockTableRecord's &lt;A href="https://forums.autodesk.com/t5/forums/searchpage/tab/message?advanced=false&amp;amp;allow_punctuation=false&amp;amp;filter=location&amp;amp;location=forum-board%3A152&amp;amp;q=GetBlockReferenceIds" target="_blank"&gt;GetBlockReferenceIds&lt;/A&gt;() method.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 19 Oct 2017 04:33:56 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7473008#M29241</guid>
      <dc:creator>ActivistInvestor</dc:creator>
      <dc:date>2017-10-19T04:33:56Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7474304#M29242</link>
      <description>&lt;P&gt;I happened to have a bit time, so, I put together a chunk of code that works in following condition:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1. 2 target drawings to be processed. Each has a few block references named as "OldBlock" inserted on various layouts. The "OldBlock" has a few attributes"; and the block is not dynamic block (so, when searching block references, the code only compare BlockReference.Name is equal "OldBlock" or not).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;2. The block used to replace "OldBlock" references existing in target drawings is named as "NewBlock", which has the same set of attributes (i.e. the attributes have the same tags); "NewBlock" is not defined in target drawings; "NewBlock" exists as a block drawing file.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;3. The code open the target drawing as side database (not opening it in AutoCAD editor visibly).&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;4. To find existing "OldBlock" references, I simply loop through all Layout blocks. It can also be done in other ways, such as firstly find the "OldBlock" definition, and call its GetBlockReferenceIds(), and then traces back to the block reference's owner block, thus the layout...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is the code that works well:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(ReplaceBlocks.MyCommands))]

namespace ReplaceBlocks
{
    internal class BlockAttributeData
    {
        public ObjectId BlkRefId { set; get; }
        public string Layer { set; get; }
        public Dictionary&amp;lt;string, string&amp;gt; Attributes { private set; get; }

        internal BlockAttributeData()
        {
            BlkRefId = ObjectId.Null;
            Attributes = new Dictionary&amp;lt;string, string&amp;gt;();
        }
    }

    internal class DrawingAttributeData : Dictionary&amp;lt;ObjectId, IEnumerable&amp;lt;BlockAttributeData&amp;gt;&amp;gt;
    {

    }

    public class MyCommands
    {
        [CommandMethod("ReplaceBlk")]
        public static void RunDocCommand()
        {
            string[] dwgFiles = new string[]
            {
                @"C:\Users\norman.yuan\Documents\Visual Studio 2017\Projects\AutoCAD2017\ReplaceBlocks\TestDwgs\TestDrawingA.dwg",
                @"C:\Users\norman.yuan\Documents\Visual Studio 2017\Projects\AutoCAD2017\ReplaceBlocks\TestDwgs\TestDrawingB.dwg"
            };

            string newBlockFile = 
                @"C:\Users\norman.yuan\Documents\Visual Studio 2017\Projects\AutoCAD2017\ReplaceBlocks\TestDwgs\NewBlock.dwg";

            var workingDb = HostApplicationServices.WorkingDatabase;
            
            try
            {
                foreach (var dwgfile in dwgFiles)
                {
                    // Open target drawing as side database.
                    // It makes the processing a lot faster than opening
                    // drawing in Editor visibly.
                    // One can choose open the drawing in Editor, if desired.
                    using (var db = OpenSideDatabase(dwgfile))
                    {
                        HostApplicationServices.WorkingDatabase = db;
                        ReplaceBlocks(db, "OldBlock", "NewBlock", newBlockFile);
                        db.SaveAs(dwgfile, true, DwgVersion.Current, null);
                    }
                }
            }
            catch (System.Exception ex)
            {
                CadApp.ShowAlertDialog("Error:\r\n" + ex.Message);
            }
            finally
            {
                HostApplicationServices.WorkingDatabase = workingDb;
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
            }
        }

        private static Database OpenSideDatabase(string dwgFileName)
        {
            var db = new Database(false, true);
            db.ReadDwgFile(
                dwgFileName, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
            return db;
        }

        private static void ReplaceBlocks(
            Database db, string oldBlkName, string newBlkName, string newBlockFile)
        {
            // Find all "OldBlock" references and collect their attribute data
            // If only blockreference on certain layout is targeted, this is where
            // one can decide which layout to be excluded
            var dwgAttData = CollectOldBlockAttributeData(db, oldBlkName);
            if (dwgAttData.Count==0)
            {
                CadApp.ShowAlertDialog("No \"" + oldBlkName + "\" found!");
                return;
            }

            // Make sure "NewBlock" is defined in the drawing. If not, get it from 
            // a block drawing file (Database.Insert(); or the the block definition
            // is in a drawing where many blocks are defined, use 
            // use Database.WblockCloneObjects() to bring this block definition
            // into this drawing
            var newBlkDefId = EnsureNewBlockDefinition(db, newBlkName, newBlockFile);
            if (newBlkDefId.IsNull)
            {
                CadApp.ShowAlertDialog(
                    "NewBlock definition is not found in source drawing!");
                return;
            }

            // Replacing "OldBlock" references by
            // 1. Insert "NewBlock" at the same position/same layer
            // 2. Sych  attribute values (because both old and new blocks have the same Attrs.
            // 3. Erase "OldBlock" reference
            ReplaceOldBlocks(db, newBlkDefId, dwgAttData);

        }

        #region find all "OldBlock" and their attribute information
        private static DrawingAttributeData CollectOldBlockAttributeData(
            Database db, string oldBlkName)
        {
            var attData = new DrawingAttributeData();

            using (var tran = db.TransactionManager.StartTransaction())
            {
                var dic = (DBDictionary)tran.GetObject(
                    db.LayoutDictionaryId, OpenMode.ForRead);
                foreach (DBDictionaryEntry entry in dic)
                {
                    var layout = (Layout)tran.GetObject(entry.Value, OpenMode.ForRead);
                    var layoutAttData = CollectOldBlockAttributeDataOnLayout(
                        oldBlkName, layout.BlockTableRecordId, tran);
                    if (layoutAttData.Count &amp;gt; 0)
                    {
                        attData.Add(layout.BlockTableRecordId, layoutAttData);
                    }
                }

                tran.Commit();
            }
            
            return attData;
        }

        private static List&amp;lt;BlockAttributeData&amp;gt; CollectOldBlockAttributeDataOnLayout(
            string oldBlkName, ObjectId layoutBlockId, Transaction tran)
        {
            var layoutAttData = new List&amp;lt;BlockAttributeData&amp;gt;();

            var layoutBlock = (BlockTableRecord)tran.GetObject(layoutBlockId, OpenMode.ForRead);
            foreach (ObjectId id in layoutBlock)
            {
                if (id.ObjectClass.DxfName.ToUpper()=="INSERT")
                {
                    var blk = (BlockReference)tran.GetObject(id, OpenMode.ForRead);
                    if (blk.Name.ToUpper()==oldBlkName.ToUpper())
                    {
                        var blkAttData = CollectOldBlockAttributes(blk, tran);
                        if (blkAttData.Attributes.Count &amp;gt; 0)
                        {
                            layoutAttData.Add(blkAttData);
                        }
                    }
                }
            }

            return layoutAttData;
        }

        private static BlockAttributeData CollectOldBlockAttributes(
            BlockReference bref, Transaction tran)
        {
            var blkAttData = new BlockAttributeData();
            blkAttData.BlkRefId = bref.ObjectId;
            blkAttData.Layer = bref.Layer;

            foreach (ObjectId id in bref.AttributeCollection)
            {
                var att = (AttributeReference)tran.GetObject(id, OpenMode.ForRead);
                if (att.IsConstant) continue;

                if (!blkAttData.Attributes.ContainsKey(att.Tag.ToUpper()))
                {
                    blkAttData.Attributes.Add(att.Tag.ToUpper(), att.TextString);
                }
            }

            return blkAttData;
        }

        #endregion

        #region make sure "NewBlock" definition exists

        private static ObjectId EnsureNewBlockDefinition(
            Database db, string newBlkName, string newBlockFile)
        {
            var blkId = ObjectId.Null;

            using (var tran=db.TransactionManager.StartTransaction())
            {
                var bt = 
                    (BlockTable)tran.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(newBlkName)) blkId = bt[newBlkName];
                tran.Commit();
            }

            if (blkId.IsNull)
            {
                blkId = InsertNewBlockDefinition(db, newBlkName, newBlockFile);
            }

            return blkId;
        }

        private static ObjectId InsertNewBlockDefinition(
            Database db, string blkName, string blkFile)
        {
            var blkId = ObjectId.Null;
            using (var blkDb = new Database(false, true))
            {
                blkDb.ReadDwgFile(
                    blkFile, FileOpenMode.OpenForReadAndReadShare, false, null);
                blkId = db.Insert(blkName, blkDb, false);
            }
            return blkId;
        }

        #endregion

        #region do the replacing work

        private static void ReplaceOldBlocks(
            Database db, ObjectId newBlkDefId, 
            DrawingAttributeData dwgAttData)
        {
            using (var tran = db.TransactionManager.StartTransaction())
            {
                foreach (var item in dwgAttData)
                {
                    var layoutBlock = 
                        (BlockTableRecord)tran.GetObject(item.Key, OpenMode.ForWrite);
                    var newBlock = 
                        (BlockTableRecord)tran.GetObject(newBlkDefId, OpenMode.ForRead);

                    foreach (var blkData in item.Value)
                    {
                        var oldBlk = 
                            (BlockReference)tran.GetObject(blkData.BlkRefId, OpenMode.ForRead);
                        var position = oldBlk.Position;

                        CreateNewBlockReference(
                            db, layoutBlock, newBlock, 
                            position, blkData.Layer, 
                            blkData.Attributes, tran);

                        oldBlk.UpgradeOpen();
                        oldBlk.Erase();
                    }
                }

                tran.Commit();
            }
        }

        private static void CreateNewBlockReference(
            Database db, BlockTableRecord layoutBlock, 
            BlockTableRecord newBlock, Point3d position, 
            string layer, Dictionary&amp;lt;string, string&amp;gt; attData, 
            Transaction tran)
        {
            var bref = new BlockReference(position, newBlock.ObjectId);
            bref.SetDatabaseDefaults(db);
            bref.Layer = layer;

            var brefId = layoutBlock.AppendEntity(bref);
            tran.AddNewlyCreatedDBObject(bref, true);

            SetAttributes(brefId, newBlock, attData, tran);
        }

        private static void SetAttributes(
            ObjectId brefId, BlockTableRecord newBlock, 
            Dictionary&amp;lt;string, string&amp;gt; attData, Transaction tran)
        {
            var bref = (BlockReference)tran.GetObject(brefId, OpenMode.ForWrite);

            foreach (ObjectId id in newBlock)
            {
                var attDef = tran.GetObject(id, OpenMode.ForRead) as AttributeDefinition;
                if (attDef!=null)
                {
                    var att = new AttributeReference();
                    att.SetAttributeFromBlock(attDef, bref.BlockTransform);
                    if (!attDef.Constant)
                    {
                        if (attData.ContainsKey(att.Tag.ToUpper()))
                        {
                            att.TextString = attData[att.Tag.ToUpper()];
                        }
                    }

                    bref.AttributeCollection.AppendAttribute(att);
                    tran.AddNewlyCreatedDBObject(att, true);
                }
            }
        }

        #endregion
    }
}&lt;/PRE&gt;
&lt;P&gt;HTH&lt;/P&gt;</description>
      <pubDate>Thu, 19 Oct 2017 13:51:04 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7474304#M29242</guid>
      <dc:creator>norman.yuan</dc:creator>
      <dc:date>2017-10-19T13:51:04Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7474522#M29243</link>
      <description>&lt;P&gt;belive it or not, tomorrow is my birthday and for sure this is the best present.&lt;/P&gt;&lt;P&gt;Thanks Norman, I guess to learn it and test it within this week and I will give you a response quickly!&lt;/P&gt;</description>
      <pubDate>Thu, 19 Oct 2017 14:37:14 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7474522#M29243</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-19T14:37:14Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7477921#M29244</link>
      <description>&lt;P&gt;happy birthday!&lt;/P&gt;</description>
      <pubDate>Fri, 20 Oct 2017 13:58:48 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7477921#M29244</guid>
      <dc:creator>fieldguy</dc:creator>
      <dc:date>2017-10-20T13:58:48Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7478990#M29245</link>
      <description>&lt;P&gt;Thanks for wishes!&lt;/P&gt;&lt;P&gt;Concerning the prg posted by Norman, I can say it works well although didn't start at first run.&lt;/P&gt;&lt;P&gt;The misurandestending is in:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;db.insert(...)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        private static ObjectId InsertNewBlockDefinition(
            Database db, string blkName, string blkFile)
        {
            var blkId = ObjectId.Null;
            using (var blkDb = new Database(false, true))
            {
                blkDb.ReadDwgFile(
                    blkFile, FileOpenMode.OpenForReadAndReadShare, false, null);
                blkId = db.Insert(blkName, blkDb, false);
            }
            return blkId;
        }&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I had to change with "&lt;SPAN style="line-height: 140%;"&gt;WblockCloneObjects&lt;/SPAN&gt;" method in order to avoid an exception.&lt;/P&gt;&lt;P&gt;The matter is easy to solve and than the routine works well (thanks Norman again).&lt;/P&gt;&lt;P&gt;cheers and...... to the next week!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 20 Oct 2017 18:33:39 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7478990#M29245</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-20T18:33:39Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7480870#M29246</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;Thanks for wishes!&lt;/P&gt;&lt;P&gt;Concerning the prg posted by Norman, I can say it works well although didn't start at first run.&lt;/P&gt;&lt;P&gt;The misurandestending is in:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;db.insert(...)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        private static ObjectId InsertNewBlockDefinition(
            Database db, string blkName, string blkFile)
        {
            var blkId = ObjectId.Null;
            using (var blkDb = new Database(false, true))
            {
                blkDb.ReadDwgFile(
                    blkFile, FileOpenMode.OpenForReadAndReadShare, false, null);
                blkId = db.Insert(blkName, blkDb, false);
            }
            return blkId;
        }&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I had to change with "&lt;SPAN style="line-height: 140%;"&gt;WblockCloneObjects&lt;/SPAN&gt;" method in order to avoid an exception.&lt;/P&gt;&lt;P&gt;The matter is easy to solve and than the routine works well (thanks Norman again).&lt;/P&gt;&lt;P&gt;cheers and...... to the next week!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;After seeing the code&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/543921"&gt;@norman.yuan&lt;/a&gt;&amp;nbsp;posted, I think I should mention that you can also just redefine the block definition in the drawings in which you need to replace the block references, rather than replace the block references and add another block definition. If you need to modify the attributes and they have the same number and tags as the block that's being replaced, you can do that after the fact, by just modifying the existing insertions and their attributes, rather than replacing them.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have written quite a bit of code that does batch replacement of block definitions, by just redefining the block in each target drawing, because that's essentially the same as replacing the references with references to another newly-inserted block. If need be, the modified block definition's name can be changed to name of the block that is to replace it. What you end up with is essentially the same thing, but without having to replace all of the block references.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;If you want to change the block that an existing block insertion references, you can just set the BlockReference's BlockTableRecord property to the ObjectId of the BlockTableRecord representing the block that it should reference. That preserves all of the existing insertions, attributes, and their properties (Norman's code only replicates the Layer and Insertion point).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, if attributes had been edited and moved from their default positions, replacing the block reference and its attributes with a new BlockReference and new attributes would not preserve any changes made to the existing attributes of the insertion that's being replaced.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Another mistake&amp;nbsp;that a lot of code I see that does batch processing of drawing files without opening them in the editor, is that merely calling&amp;nbsp;SaveAs() causes the resulting&amp;nbsp;DWG file to loose its thumbnail preview, unless you first set the Database's &lt;A href="http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_Database_RetainOriginalThumbnailBitmap" target="_blank"&gt;RetainOriginalThumbnailBitmap&lt;/A&gt;&amp;nbsp;property to true.&lt;/P&gt;</description>
      <pubDate>Sat, 21 Oct 2017 20:46:28 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7480870#M29246</guid>
      <dc:creator>ActivistInvestor</dc:creator>
      <dc:date>2017-10-21T20:46:28Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7481259#M29247</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4476837"&gt;@ActivistInvestor&lt;/a&gt;, thank you for your time, for sure you point out some question could be worthwhile to examine in depth, however without detracting anything to the frame written by &lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/543921"&gt;@norman.yuan&lt;/a&gt;, it remains a good start and useful for my purpose.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;From your post:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;"I have written quite a bit of code that does batch replacement of block definitions, ...."&lt;BR /&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;Could you provide a sample or where to find it?&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;"&lt;EM&gt;...That preserves all of the existing insertions, attributes, and their properties..." &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;Is this true also for fields?&lt;/STRONG&gt;&lt;/FONT&gt; (please thake a look to: &lt;A href="https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-1B6DD22B-10D1-44ED-BAA2-E6D79FE52327-htm.html" target="_blank"&gt;https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-1B6DD22B-10D1-44ED-BAA2-E6D79FE52327-htm.html&lt;/A&gt; in order to understand what I mean). The routine loses fields of old block in the new one.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;"For example, if attributes had been edited and moved from their default positions, replacing the block reference and its attributes with a new BlockReference and new attributes would not preserve any changes made to the existing attributes of the insertion that's being replaced."&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#0000FF"&gt;Yes it,s true, and for this reason I was going to replace only some fields and avoid the copy from old block to new one of those are in common and same.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;&lt;FONT color="#000000"&gt;"....calling&amp;nbsp;SaveAs() causes the resulting&amp;nbsp;DWG file to loose its thumbnail preview, unless you first set the Database's &lt;A href="http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_Database_RetainOriginalThumbnailBitmap" target="_blank" rel="nofollow noopener noreferrer"&gt;RetainOriginalThumbnailBitmap&lt;/A&gt;&amp;nbsp;property to true"&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;Interesting, I noted it (thinking just to a bug), I will try to set it to true.&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000000"&gt;Cheers&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000000"&gt;M.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 22 Oct 2017 08:25:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7481259#M29247</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-22T08:25:06Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7481815#M29248</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;Could you provide a sample or where to find it?&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Unfortunately, most of that code was written under contract, which means I'm not able&amp;nbsp;to distribute it as-is. Other code I do have which is not subject to that restriction has a great number of dependencies on other code that would make it difficult to provide as a 'sample', without a lot of baggage. If I can find something that shows the basic concept and doesn't have too many dependencies, I will post it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;"&lt;EM&gt;...That preserves all of the existing insertions, attributes, and their properties..." &lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000FF"&gt;&lt;STRONG&gt;Is this true also for fields?&lt;/STRONG&gt;&lt;/FONT&gt; (please thake a look to: &lt;A href="https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-1B6DD22B-10D1-44ED-BAA2-E6D79FE52327-htm.html" target="_blank"&gt;https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-Core/files/GUID-1B6DD22B-10D1-44ED-BAA2-E6D79FE52327-htm.html&lt;/A&gt; in order to understand what I mean). The routine loses fields of old block in the new one.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Yes, because you're not deleting an existing BlockReference and replacing it with a new one, so everything that exists, including fields remains intact, but only if you don't modify the existing attributes. If you have to modify the attributes and they contain fields, then it becomes a bit more complicated.&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;"For example, if attributes had been edited and moved from their default positions, replacing the block reference and its attributes with a new BlockReference and new attributes would not preserve any changes made to the existing attributes of the insertion that's being replaced."&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#0000FF"&gt;Yes it,s true, and for this reason I was going to replace only some fields and avoid the copy from old block to new one of those are in common and same.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Regarding fields, it depends on whether a field has a reference to other objects in the drawing. If they do, the fields can't be simply be copied from the source database to the new one, without doing&amp;nbsp;a deep-clone operation that also includes the object(s) that are referenced by the fields. So, how complicated it can be depends on the nature and type of fields used. For example, if fields reference custom DWG properties (a fairly-typical&amp;nbsp;use case), the custom DWG properties must exist in the destination database.&lt;/P&gt;</description>
      <pubDate>Sun, 22 Oct 2017 18:18:54 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7481815#M29248</guid>
      <dc:creator>ActivistInvestor</dc:creator>
      <dc:date>2017-10-22T18:18:54Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7486378#M29249</link>
      <description>&lt;P&gt;After several days, I can say I have reached a&lt;STRONG&gt; solution&lt;/STRONG&gt;&amp;nbsp;(yes I can say solution.... unbeliavable) suitable for my purpose.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here the code for&amp;nbsp;benefit of other.&lt;/P&gt;&lt;P&gt;I have to say the true, coding .net with Autocad is not for dummy and some of the code here is not clear to me at all (but works...)&lt;/P&gt;&lt;P&gt;In any case I leave the original code from&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/543921"&gt;@norman.yuan&lt;/a&gt;&amp;nbsp;in which I edited&amp;nbsp;and replaced with other fonts (ie: web, samples from official reference... suggestion by&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4476837"&gt;@ActivistInvestor&lt;/a&gt;,&amp;nbsp;and my guess...) and adding some comment (hope they make sense).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The code doesn't replace ATTRIBUTES (the new block has to have own ATTRIBUTES in it, as suggested by&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4476837"&gt;@ActivistInvestor&lt;/a&gt;&amp;nbsp;as faster way)&lt;/P&gt;&lt;P&gt;The code can transfer some attribute.text from the old block to th new one.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The last question:&lt;/P&gt;&lt;P&gt;Could someone explain to me how come the editor doesn't refresh the screen after each foreach operation?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;star processing new file:&lt;/P&gt;&lt;PRE&gt;ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));&lt;/PRE&gt;&lt;P&gt;...............&lt;/P&gt;&lt;P&gt;..............&lt;/P&gt;&lt;P&gt;end processing the file&lt;/P&gt;&lt;PRE&gt;ed.UpdateScreen();&lt;/PRE&gt;&lt;P&gt;but I see my screen updated just at the end of whole program... strangely enogh.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;        [CommandMethod("REPBLK")]
        public static void RunDocCommand()
        {

            string pathDwgFiles = @"MAYPATH";
            string newBlockFile = @"DWGFILEWITHNEWBLOCK";
            string oldBlkName = "OLDBLOCKNAME";
            string newBlkName = "NEWBLOCKNAME";

            var workingDb = HostApplicationServices.WorkingDatabase;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;


            try
            {
                ed.WriteMessage("\nSTART BLOCK REPLACE PROCESS\n");

                string[] dwgFiles = Directory.GetFiles(pathDwgFiles, "*.dwg", SearchOption.AllDirectories);
                foreach (var dwgfile in dwgFiles)
                {
                    // Open target drawing as side database.
                    // It makes the processing a lot faster than opening
                    // drawing in Editor visibly.
                    // One can choose open the drawing in Editor, if desired.
                    ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));
                    using (var db = OpenSideDatabase(dwgfile))
                    {
                        HostApplicationServices.WorkingDatabase = db;
                        if (!ReplaceBlocks(db, oldBlkName, newBlkName, newBlockFile))
                            ed.WriteMessage("\nOld Block NOT foud in: " + Path.GetFileName(dwgfile));
                        else
                            RemoveBlockFromDb(db, oldBlkName); //remove oldBlock

                        db.RetainOriginalThumbnailBitmap = true;
                        db.SaveAs(dwgfile, true, DwgVersion.Current, null);
                    }
                    ed.UpdateScreen();
                }
            }
            catch (System.Exception ex)
            {
                CadApp.ShowAlertDialog("Error:\r\n" + ex.Message);
            }
            finally
            {
                ed.WriteMessage("\nEND BLOCK REPLACE PROCESS\n");
                HostApplicationServices.WorkingDatabase = workingDb;
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();

            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Open the DWG as Database
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="dwgFileName"&amp;gt;the dwg file name full path&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the Database&amp;lt;/returns&amp;gt;
        private static Database OpenSideDatabase(string dwgFileName)
        {
            var db = new Database(false, true);
            db.ReadDwgFile(dwgFileName, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
            return db;
        }

        private static bool ReplaceBlocks(Database db, string oldBlkName, string newBlkName, string newBlockFile)
        {
            // Find all "OldBlock" references and collect their attribute data
            // If only blockreference on certain layout is targeted, this is where
            // one can decide which layout to be excluded
            var dwgAttData = CollectOldBlockAttributeData(db, oldBlkName);
            if (dwgAttData.Count == 0)
            {
                //CadApp.ShowAlertDialog("No \"" + oldBlkName + "\" found!");
                return false;
            }

            // Make sure "NewBlock" is defined in the drawing. If not, get it from 
            // a block drawing file (Database.Insert(); or the the block definition
            // is in a drawing where many blocks are defined, use 
            // use Database.WblockCloneObjects() to bring this block definition
            // into this drawing
            var newBlkDefId = EnsureNewBlockDefinition(db, newBlkName, newBlockFile);
            if (newBlkDefId.IsNull)
            {
                CadApp.ShowAlertDialog("NewBlock definition is not found in source drawing!");
                return false;
            }

            // Replacing "OldBlock" references by
            // 1. Insert "NewBlock" at the same position/same layer
            // 2. Sych  attribute values (because both old and new blocks have the same Attrs.
            // 3. Erase "OldBlock" reference

            ReplaceOldBlocks(db, newBlkDefId, dwgAttData, newBlkName);

            return true;
        }



        #region find all "OldBlock" and their attribute information
        private static DrawingAttributeData CollectOldBlockAttributeData(Database db, string oldBlkName)
        {
            var attData = new DrawingAttributeData();
            using (var tran = db.TransactionManager.StartTransaction())
            {
                var dic = (DBDictionary)tran.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
                foreach (DBDictionaryEntry entry in dic)
                {
                    var layout = (Layout)tran.GetObject(entry.Value, OpenMode.ForRead);
                    var layoutAttData = CollectOldBlockAttributeDataOnLayout(oldBlkName, layout.BlockTableRecordId, tran);
                    if (layoutAttData.Count &amp;gt; 0)
                    {
                        attData.Add(layout.BlockTableRecordId, layoutAttData);
                    }
                }
                tran.Commit();
            }
            return attData;
        }

        private static List&amp;lt;BlockAttributeData&amp;gt; CollectOldBlockAttributeDataOnLayout(
                                                string oldBlkName, ObjectId layoutBlockId, Transaction tran)
        {
            var layoutAttData = new List&amp;lt;BlockAttributeData&amp;gt;();
            var layoutBlock = (BlockTableRecord)tran.GetObject(layoutBlockId, OpenMode.ForRead);
            foreach (ObjectId id in layoutBlock)
            {
                if (id.ObjectClass.DxfName.ToUpper() == "INSERT")
                {
                    var blk = (BlockReference)tran.GetObject(id, OpenMode.ForRead);
                    if (blk.Name.ToUpper().Contains(oldBlkName.ToUpper())) //I use contain for similar names in my list
                    {
                        var blkAttData = CollectOldBlockAttributes(blk, tran);
                        if (blkAttData.Attributes.Count &amp;gt; 0)
                        {
                            layoutAttData.Add(blkAttData);
                        }
                    }
                }
            }
            return layoutAttData;
        }

        private static BlockAttributeData CollectOldBlockAttributes(BlockReference bref, Transaction tran)
        {
            //bref.Name is the layout name.

            var blkAttData = new BlockAttributeData();
            blkAttData.BlkRefId = bref.ObjectId;
            blkAttData.Layer = bref.Layer;

            foreach (ObjectId id in bref.AttributeCollection)
            {
                var att = (AttributeReference)tran.GetObject(id, OpenMode.ForRead);
                if (att.IsConstant)
                    continue;

                if (!blkAttData.Attributes.ContainsKey(att.Tag.ToUpper()))
                {
                    blkAttData.Attributes.Add(att.Tag.ToUpper(), att.TextString);
                }
            }
            return blkAttData;
        }

        #endregion

        #region make sure "NewBlock" definition exists

        private static ObjectId EnsureNewBlockDefinition(Database db, string newBlkName, string newBlockFile)
        {
            var blkId = ObjectId.Null;

            using (var tran = db.TransactionManager.StartTransaction())
            {
                var bt = (BlockTable)tran.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(newBlkName))
                    blkId = bt[newBlkName]; //verify if the current drawing has the new block
                tran.Commit();
            }

            if (blkId.IsNull) //if the block isn't in, get it
            {
                blkId = InsertNewBlockDefinition(db, newBlkName, newBlockFile);
            }
            return blkId;
        }

        /// &amp;lt;summary&amp;gt;
        /// Clones in db the block from the file
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="db"&amp;gt;destination database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkName"&amp;gt;block name&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkFile"&amp;gt;block's source file full path&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the block's objId&amp;lt;/returns&amp;gt;
        private static ObjectId InsertNewBlockDefinition(Database db, string blkName, string blkFile)
        {
            var blkId = ObjectId.Null;
            using (var blkDb = new Database(false, true))
            {
                blkDb.ReadDwgFile(blkFile, FileOpenMode.OpenForReadAndReadShare, false, null);

                //this Works:
                //need to crate collectionObject for wblockClone method:
                ObjectIdCollection objColl = new ObjectIdCollection();
                
                objColl.Add(GetBlkId(blkDb, blkName));
                IdMapping map = new IdMapping();
                
                //cloneObject
                blkDb.WblockCloneObjects(objColl, db.BlockTableId, map, DuplicateRecordCloning.Replace, false);
                blkId = GetBlkId(db, blkName); //keep the id of cloned block

                //if I use deepclone, as is doesn't work
                //blkDb.DeepCloneObjects(objColl, db.BlockTableId, map, false);
                
                //if I use Insert, as is doesn't work:
                //blkId = db.Insert(blkName, blkDb, false);
            }
            return blkId;
        }


        #endregion

        #region do the replacing work

        private static void ReplaceOldBlocks(Database db, ObjectId newBlkDefId,
                                             DrawingAttributeData dwgAttData, string newBlkName)
        {
            using (var tran = db.TransactionManager.StartTransaction())
            {
                foreach (var item in dwgAttData)
                {
                    //item.key is an objectId
                    var layoutBlock = (BlockTableRecord)tran.GetObject(item.Key, OpenMode.ForWrite);
                    var newBlock = (BlockTableRecord)tran.GetObject(newBlkDefId, OpenMode.ForRead);

                    //foreach layout
                    foreach (var blkData in item.Value)
                    {
                        //get the position
                        var oldBlk = (BlockReference)tran.GetObject(blkData.BlkRefId, OpenMode.ForRead);
                        var position = oldBlk.Position; 


                        CreateNewBlockReference(db, layoutBlock, newBlock, position, blkData.Layer,
                                                blkData.Attributes, tran);

                        //erase block doesn't work - i will erase later see: RemoveBlockFromDb
                        //oldBlk.UpgradeOpen();
                        //oldBlk.Erase();
                        //oldBlk.Dispose();
                    }
                }
                tran.Commit();
            }
        }

        private static void CreateNewBlockReference(Database db, BlockTableRecord layoutBlock,
                                                    BlockTableRecord newBlock, Point3d position,
                                                    string layer, Dictionary&amp;lt;string, string&amp;gt; attData,
                                                    Transaction tran)
        {
            var bref = new BlockReference(position, newBlock.ObjectId);

            bref.SetDatabaseDefaults(db);
            bref.Layer = layer;
            
            var brefId = layoutBlock.AppendEntity(bref);
            tran.AddNewlyCreatedDBObject(bref, true);
  
            SetAttributes(brefId, newBlock, attData, tran);
        }


        private static void SetAttributes(ObjectId brefId, BlockTableRecord newBlock,
                                          Dictionary&amp;lt;string, string&amp;gt; attData, Transaction tran)
        {
            var bref = (BlockReference)tran.GetObject(brefId, OpenMode.ForWrite);
            
            foreach (ObjectId id in newBlock)
            {
                //FROM .NET SAMPLE GUIDE
                DBObject dbObj = (DBObject)tran.GetObject(id, OpenMode.ForRead);
                if (dbObj is AttributeDefinition)
                {
                    AttributeDefinition attDef = dbObj as AttributeDefinition;
                    if (!attDef.Constant)
                    {
                        using (AttributeReference attRef = new AttributeReference())
                        {
                            attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);
                            if (attDef.Tag.Contains("THE TAG I WANT TO REPLACE"))
                            {
                                //replace value gets from the old block
                                attRef.TextString = attData["THE TAG I WANT TO REPLACE"];
                            }
                            else
                            {
                                //Do nothing and leave value of new block
                            }
                            bref.AttributeCollection.AppendAttribute(attRef);
                            tran.AddNewlyCreatedDBObject(attRef, true);
                        }
                    }
                }

                //OLD VERSION 
                //var attDef = tran.GetObject(id, OpenMode.ForRead) as AttributeDefinition;
                //if (attDef != null)
                //{
                //    var att = new AttributeReference();
                //    att.SetAttributeFromBlock(attDef, bref.BlockTransform);
 
                //    if (!attDef.Constant &amp;amp;&amp;amp; attData.ContainsKey("OGGETTO"))
                //    {
                //        if (attData.ContainsKey(att.Tag.ToUpper()))
                //            att.TextString = attData[att.Tag.ToUpper()];
                //    }
                //    bref.AttributeCollection.AppendAttribute(att);
                //    tran.AddNewlyCreatedDBObject(att, true);
                //}
            }
        }

        #endregion

        #region MyAdd
        /// &amp;lt;summary&amp;gt;
        /// Gets the block's ObjID from the database
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="db"&amp;gt;the Database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blkName"&amp;gt;the block name&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the objID&amp;lt;/returns&amp;gt;
        public static ObjectId GetBlkId(Database db, string blkName)
        {
            ObjectId blkId = ObjectId.Null;

            if (db == null)
                return ObjectId.Null;

            if (string.IsNullOrWhiteSpace(blkName))
                return ObjectId.Null;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(blkName))
                    blkId = bt[blkName];
                else //looking for similar name...
                {
                    foreach (ObjectId item in bt)
                    {
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(item, OpenMode.ForRead);
                        if (btr.Name.ToUpper().Contains(blkName.ToUpper()))
                        {
                            blkId = item;
                            break;
                        }
                    }
                }
                tr.Commit();
            }
            return blkId;
        }

        /// &amp;lt;summary&amp;gt;
        /// Get the Value of Attribute from block
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="btrId"&amp;gt;The object database&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="blockName"&amp;gt;the block name&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="attbName"&amp;gt; the attribute name&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;the attribute value&amp;lt;/returns&amp;gt;
        private static string GetAttribValueFromBlock(ObjectId btrId, string blockName, string attbName)
        {
            Database db = btrId.Database;
            string txtValue = string.Empty;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

                // Test each entity in the container...
                foreach (ObjectId entId in btr)
                {
                    Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
                    if (ent != null)
                    {
                        BlockReference br = ent as BlockReference;
                        if (br != null)
                        {
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

                            // ... to see whether it's a block with
                            // the name we're after
                            if (bd.Name.ToUpper() == blockName)
                            {

                                // Check each of the attributes...
                                foreach (ObjectId arId in br.AttributeCollection)
                                {
                                    DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
                                    AttributeReference ar = obj as AttributeReference;
                                    if (ar != null)
                                    {
                                        // ... to see whether it has
                                        // the tag we're 
                                        if (ar.Tag.ToUpper() == attbName)
                                            txtValue = ar.TextString;
                                    }
                                }
                            }

                            // Recurse for nested blocks
                            //doesn't needed for my block
                            //changedCount += UpdateAttributesInBlock(br.BlockTableRecord,blockName,attbName,attbValue);
                        }
                    }
                }
                tr.Commit();
            }
            return txtValue;
        }

        private static bool SetAttributeInBlock(ObjectId btrId, string blockName, string attbName, string attbValue)
        {
            Database db = btrId.Database;
            bool gotcha = false;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

                // Test each entity in the container...
                foreach (ObjectId entId in btr)
                {
                    Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity;
                    if (ent != null)
                    {
                        BlockReference br = ent as BlockReference;
                        if (br != null)
                        {
                            BlockTableRecord bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);

                            // ... to see whether it's a block with
                            // the name we're after
                            if (bd.Name.ToUpper() == blockName)
                            {

                                // Check each of the attributes...
                                foreach (ObjectId arId in br.AttributeCollection)
                                {
                                    DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
                                    AttributeReference ar = obj as AttributeReference;
                                    if (ar != null)
                                    {
                                        // ... to see whether it has
                                        // the tag we're 
                                        if (ar.Tag.ToUpper() == attbName)
                                        {
                                            // If so, update the value
                                            // and increment the counter
                                            ar.UpgradeOpen();
                                            ar.TextString = attbValue;
                                            ar.DowngradeOpen();
                                            gotcha = true;
                                        }
                                    }
                                }
                            }

                            // Recurse for nested blocks
                            //doesn't needed for my block
                            //changedCount += UpdateAttributesInBlock(br.BlockTableRecord,blockName,attbName,attbValue);
                        }
                    }
                }
                tr.Commit();
            }
            return gotcha;
        }


        public static void RemoveBlockFromDb(Database db, string blkName)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;


            ObjectId blkId = GetBlkId(db, blkName);
            if (!EraseBlkRefs(blkId))
                ed.WriteMessage(string.Format("\n failed to erase blockreferences for: {0}", blkId.ToString()));

            if (!EraseBlk(blkId))
                ed.WriteMessage(string.Format("\n Failed to Erase Block: {0}", blkId.ToString()));
            else
                ed.WriteMessage("\nErased" + blkId.ToString()); 

        }
        public static bool EraseBlkRefs(ObjectId blkId)
        {
            bool blkRefsErased = false;

            if (blkId.IsNull)
                return false;

            Database db = blkId.Database;
            if (db == null)
                return false;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForRead);
                var blkRefs = blk.GetBlockReferenceIds(true, true);
                if (blkRefs != null &amp;amp;&amp;amp; blkRefs.Count &amp;gt; 0)
                {
                    foreach (ObjectId blkRefId in blkRefs)
                    {
                        BlockReference blkRef = (BlockReference)tr.GetObject(blkRefId, OpenMode.ForWrite);
                        blkRef.Erase();
                    }
                    blkRefsErased = true;
                }
                tr.Commit();
            }
            return blkRefsErased;
        }
        public static bool EraseBlk(ObjectId blkId)
        {
            bool blkIsErased = false;

            if (blkId.IsNull)
                return false;

            Database db = blkId.Database;
            if (db == null)
                return false;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForRead);
                var blkRefs = blk.GetBlockReferenceIds(true, true);
                if (blkRefs == null || blkRefs.Count == 0)
                {
                    blk.UpgradeOpen();
                    blk.Erase();
                    blkIsErased = true;
                }
                tr.Commit();
            }
            return blkIsErased;
        }
        #endregion&lt;/PRE&gt;</description>
      <pubDate>Tue, 24 Oct 2017 10:12:08 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7486378#M29249</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-24T10:12:08Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7487657#M29250</link>
      <description>&lt;P&gt;&amp;nbsp;See the line I added to your code below (highlighted in red):&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/5201989"&gt;@micle.space&lt;/a&gt; wrote:&lt;BR /&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The last question:&lt;/P&gt;&lt;P&gt;Could someone explain to me how come the editor doesn't refresh the screen after each foreach operation?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;star processing new file:&lt;/P&gt;&lt;PRE&gt;ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));&lt;/PRE&gt;&lt;P&gt;...............&lt;/P&gt;&lt;P&gt;..............&lt;/P&gt;&lt;P&gt;end processing the file&lt;/P&gt;&lt;PRE&gt;ed.UpdateScreen();&lt;/PRE&gt;&lt;P&gt;but I see my screen updated just at the end of whole program... strangely enogh.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;                string[] dwgFiles = Directory.GetFiles(pathDwgFiles, "*.dwg", SearchOption.AllDirectories);
                foreach (var dwgfile in dwgFiles)
                {
                    // Open target drawing as side database.
                    // It makes the processing a lot faster than opening
                    // drawing in Editor visibly.
                    // One can choose open the drawing in Editor, if desired.
                    ed.WriteMessage("\nProcessing: " + Path.GetFileName(dwgfile));&lt;BR /&gt;                    &lt;FONT color="#FF0000"&gt;System.Windows.Forms.Application.DoEvents();&lt;/FONT&gt;
                    using (var db = OpenSideDatabase(dwgfile))
                    {
                        HostApplicationServices.WorkingDatabase = db;
                        if (!ReplaceBlocks(db, oldBlkName, newBlkName, newBlockFile))
                            ed.WriteMessage("\nOld Block NOT foud in: " + Path.GetFileName(dwgfile));
                        else
                            RemoveBlockFromDb(db, oldBlkName); //remove oldBlock

                        db.RetainOriginalThumbnailBitmap = true;
                        db.SaveAs(dwgfile, true, DwgVersion.Current, null);
                    }
                    ed.UpdateScreen();
                }
            }
            catch (System.Exception ex)
            {
                CadApp.ShowAlertDialog("Error:\r\n" + ex.Message);
            }
            finally
            {
                ed.WriteMessage("\nEND BLOCK REPLACE PROCESS\n");
                HostApplicationServices.WorkingDatabase = workingDb;
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();

            }
        }

&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Tue, 24 Oct 2017 16:48:12 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7487657#M29250</guid>
      <dc:creator>ActivistInvestor</dc:creator>
      <dc:date>2017-10-24T16:48:12Z</dc:date>
    </item>
    <item>
      <title>Re: Copy Block From  file to file</title>
      <link>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7489183#M29251</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="doh.png" style="width: 490px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/417388i755CA60C663D8B79/image-size/large?v=v2&amp;amp;px=999" role="button" title="doh.png" alt="doh.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 25 Oct 2017 07:39:37 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/copy-block-from-file-to-file/m-p/7489183#M29251</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2017-10-25T07:39:37Z</dc:date>
    </item>
  </channel>
</rss>

