Replace Block - not working with Forms

Replace Block - not working with Forms

yoitsarun
Advocate Advocate
300 Views
2 Replies
Message 1 of 3

Replace Block - not working with Forms

yoitsarun
Advocate
Advocate

the below code is working fine without form. It is just running with Form but block is not replacing. no error no crash.

private void BtnApply_Click(object sender, EventArgs e)
        {
            var dwg = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;
            var fileNames = GetFileNames();
            if (fileNames is null)
            {
                ed.WriteMessage("\n*Cancel*");
                return;
            }
            ProcessDwgs(fileNames);
            return;
        }

        private IEnumerable<string> GetFileNames()
        {
            IEnumerable<string> files = null;
            using (var dialog = new OpenFileDialog()
            {
                DefaultExt = ".dwg",
                Multiselect = true,
                Filter = "dwg files|*.dwg"
            })
            {
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    files = dialog.FileNames;
                }
            }
            return files;
        }

        private void ProcessDwgs(IEnumerable<string> dwgFiles)
        {
            var dwgCol = CadApp.DocumentManager;
            foreach (var dwgFile in dwgFiles)
            {
                var dwg = dwgCol.Open(dwgFile, false, null);
                using (var lck = dwg.LockDocument())

                {
                    ImportBlocks();
                }
                string prefix = "Acad-";
                string newFileName = Path.Combine(Path.GetDirectoryName(dwg.Name), prefix + Path.GetFileName(dwg.Name));
                dwg.Database.SaveAs(newFileName, true, DwgVersion.Current, default);
                dwg.CloseAndDiscard();
            }
        }
        public static void ImportBlocks()
        {
            DocumentCollection dm = Application.DocumentManager;
            string filename = @"C:\new block\new block.dwg";
            Database destDb = dm.MdiActiveDocument.Database;
            try
            {
                var ids = new ObjectIdCollection();
                using (var sourceDb = new Database(false, true))
                {
                    sourceDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, false, null);
                    using (var tr = sourceDb.TransactionManager.StartTransaction())
                    {
                        var bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                        foreach (ObjectId id in bt)
                        {
                            var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
                            if (!btr.IsAnonymous && !btr.IsLayout)
                                ids.Add(id);
                        }
                        tr.Commit();
                    }
                    var mapping = new IdMapping();
                    destDb.WblockCloneObjects(ids, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                }
                GC.Collect(); // <- forces a garbage collection
                AcAp.ShowAlertDialog("Blocks importation succeeded");
            }
            catch (System.Exception ex)
            {
                AcAp.ShowAlertDialog(ex.Message);
            }
        }
0 Likes
Accepted solutions (1)
301 Views
2 Replies
Replies (2)
Message 2 of 3

_gile
Consultant
Consultant
Accepted solution

Hi,

Why not also using side databases for batch processing the files?

 

Here's a way using a generic BatchProcess method.

        private void BtnApply_Click(object sender, EventArgs e)
        {
            var fileNames = GetFileNames();
            if (fileNames is null)
            {
                return;
            }
            BatchProcess(fileNames, ImportBlocks);
        }

        private string[] GetFileNames()
        {
            using (var dialog = new System.Windows.Forms.OpenFileDialog()
            {
                DefaultExt = ".dwg",
                Multiselect = true,
                Filter = "dwg files|*.dwg"
            })
            {
                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    return dialog.FileNames;
                }
            }
            return null;
        }

        public static void BatchProcess(IEnumerable<string> fileNames, Action<Database> action)
        {
            foreach (string fileName in fileNames)
            {
                try
                {
                    using (var db = new Database(false, true))
                    {
                        db.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                        action(db);
                        db.SaveAs(fileName, DwgVersion.Current);
                    }
                }
                catch (System.Exception ex)
                {
                    var ed = Application.DocumentManager.MdiActiveDocument.Editor;
                    ed.WriteMessage($"\nError with '{fileName}': {ex.Message}");
                }
            }
        }

        public static void ImportBlocks(Database destDb)
        {
            string filename = @"C:\new block\new block.dwg";
            try
            {
                var ids = new ObjectIdCollection();
                using (var sourceDb = new Database(false, true))
                {
                    sourceDb.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, false, null);
                    using (var tr = sourceDb.TransactionManager.StartTransaction())
                    {
                        var bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                        foreach (ObjectId id in bt)
                        {
                            var btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
                            if (!btr.IsAnonymous && !btr.IsLayout)
                                ids.Add(id);
                        }
                        tr.Commit();
                    }
                    var mapping = new IdMapping();
                    destDb.WblockCloneObjects(ids, destDb.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                }
                AcAp.ShowAlertDialog("Blocks importation succeeded");
            }
            catch (System.Exception ex)
            {
                AcAp.ShowAlertDialog(ex.Message);
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 3

yoitsarun
Advocate
Advocate

Thanks _gile . You are awesome.

0 Likes