Insert block in multiple documents

Insert block in multiple documents

will.wydock
Advocate Advocate
683 Views
4 Replies
Message 1 of 5

Insert block in multiple documents

will.wydock
Advocate
Advocate

Hi,

I am trying to create a routine for inserting a block (ie. Record Stamp) into multiple dwg files. I thought I have all the information but I can not get the routine to run. I have tried getting the documents and adding a lock and it still does not seem to make a difference. Is there something that i am missing in my code to do this, or is this even possible?

 

Thanks in Advance

 

private static Document _document;
        private static Editor _commandLine;
        [CommandMethod("gcs-MultiDocInsertBlock")]
        public void MultiDocInsertBlock()
        {
            _document = CADApplication.DocumentManager.MdiActiveDocument;
            _commandLine = _document.Editor;
            BlockFileDialog().ShowDialog();
            var blockFileName = BlockFileDialog().FileName;
            var blockName = Path.GetFileName(blockFileName);
            if (FileDialog().ShowDialog() != DialogResult.OK) 
                return;
            var insPt = SetPoint();
            foreach (var file in FileDialog().FileNames)
            {
                _commandLine.WriteMessage("file is "+ file);
                try
                {
                    using (var database = new Database(false, true))
                    {
                        Document document =  CADApplication.DocumentManager.GetDocument(database);

                        using(document.LockDocument())
                        {
                            database.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, true, null);
                            using (var transaction = database.TransactionManager.StartOpenCloseTransaction())
                            {
                                var blockTable = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
                                if (blockTable.Has(blockName))
                                {
                                    _commandLine.WriteMessage("block does exist!");
                                    return;
                                }

                                _commandLine.WriteMessage("block does not exist!");
                                using (var sourceDb = new Database(false, true))
                                {
                                    sourceDb.ReadDwgFile(blockFileName, FileOpenMode.OpenForReadAndAllShare, true, "");
                                    database.Insert(blockName, sourceDb, true);
                                }

                                using (var blockReference = new BlockReference(insPt, blockTable[blockName]))
                                {
                                    var space = (BlockTableRecord)transaction.GetObject(database.CurrentSpaceId,
                                        OpenMode.ForWrite);
                                    space.AppendEntity(blockReference);
                                    transaction.AddNewlyCreatedDBObject(blockReference, true);
                                }

                                transaction.Commit();
                            }
                            database.SaveAs(file, DwgVersion.Current);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _commandLine.WriteMessage($"\n{file}: {ex}");
                }
            }
        }
private static Point3d SetPoint()
        {
            var promptPointOptions = new PromptPointOptions("")
            {
                Message = "\nEnter the start point of the line: "
            };
            var promptPointResult = _commandLine.GetPoint(promptPointOptions);
            var point3d = promptPointResult.Value;
            return point3d;
        }

        private static OpenFileDialog FileDialog()
        {
            var openFileDialog = new OpenFileDialog
            {
                InitialDirectory = "c:\\",
                Filter = @"DWG Files (*.dwg)|*.dwg",
                FilterIndex = 2,
                RestoreDirectory = true,
                Multiselect = true,
                Title = @"Select CAD files to update"
            };
            return openFileDialog;
        }
        private static OpenFileDialog BlockFileDialog()
        {
            var openFileDialog = new OpenFileDialog
            {
                InitialDirectory = "c:\\",
                Filter = @"DWG Files (*.dwg)|*.dwg",
                FilterIndex = 2,
                RestoreDirectory = true,
                Multiselect = false,
                Title = @"Select block file to insert"
            };
            return openFileDialog;
        }

 

0 Likes
Accepted solutions (1)
684 Views
4 Replies
Replies (4)
Message 2 of 5

_gile
Consultant
Consultant

Hi,

 

I think the first problem is here:

Document document =  CADApplication.DocumentManager.GetDocument(database);

While using a 'side database' (i.e. new Database & ReadDwgFile) you cannot access to the document of this database (and most of the time you not need to).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 5

will.wydock
Advocate
Advocate
The document and document lock was a new add as I could not get it working on just the database. It looks like I went the wrong direction in solving this.
0 Likes
Message 4 of 5

will.wydock
Advocate
Advocate
Thank you, I was able to solve my multiple document issue.

When I am running my routine, I am always getting the following errors.

eHadMultipleReaders
at Autodesk.AutoCAD.DatabaseServices.Database.Insert(String blockName, Database dataBase, Boolean preserveSourceDatabase)
at software.Common.BlockInsert.MultiDocInsertBlock() in \\Software\Common\BlockInsert.cs:line 56

from what I have been reading that means that the database has been open and not closed. It does not matter whether I have used an old file or a brand new file that I have created. I am still getting the same error. How do you close a database to make sure that this error doesn't occur?

Thanks,
0 Likes
Message 5 of 5

_gile
Consultant
Consultant
Accepted solution


eHadMultipleReaders is probably due to the using of an OpenCloseTransaction instead of a standard transaction.

This seems to work.

 

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var ed = doc.Editor;
            if (blockFileDialog.ShowDialog() != DialogResult.OK)
                return;
            if (targetFilesDialog.ShowDialog() != DialogResult.OK)
                return;
            var pointResult = ed.GetPoint("\nEnter the start point of the line: ");
            if (pointResult.Status != PromptStatus.OK)
                return;
            string blockName = Path.GetFileNameWithoutExtension(blockFileDialog.FileName);
            var insPoint = pointResult.Value.TransformBy(ed.CurrentUserCoordinateSystem);
            using (var sourceDb = new Database(false, true))
            {
                sourceDb.ReadDwgFile(blockFileDialog.FileName, FileOpenMode.OpenForReadAndReadShare, true, null);
                foreach (string targetFile in targetFilesDialog.FileNames)
                {
                    using (var targetDb = new Database(false, true))
                    {
                        targetDb.ReadDwgFile(targetFile, FileOpenMode.OpenForReadAndAllShare, true, null);
                        using (var tr = targetDb.TransactionManager.StartTransaction())
                        {
                            var blockTable = (BlockTable)tr.GetObject(targetDb.BlockTableId, OpenMode.ForRead);
                            if (!blockTable.Has(blockName))
                            {
                                var space = (BlockTableRecord)tr.GetObject(targetDb.CurrentSpaceId, OpenMode.ForWrite);
                                var id = targetDb.Insert(blockName, sourceDb, true);
                                var br = new BlockReference(insPoint, id);
                                space.AppendEntity(br);
                                tr.AddNewlyCreatedDBObject(br, true);
                                targetDb.SaveAs(targetFile, DwgVersion.Current);
                            }
                            tr.Commit();
                        }
                    }
                }
            }
        }

        private static OpenFileDialog targetFilesDialog = new OpenFileDialog
        {
            InitialDirectory = "c:\\",
            Filter = @"DWG Files (*.dwg)|*.dwg",
            FilterIndex = 2,
            RestoreDirectory = true,
            Multiselect = true,
            Title = @"Select CAD files to update"
        };

        private static OpenFileDialog blockFileDialog = new OpenFileDialog
        {
            InitialDirectory = "c:\\",
            Filter = @"DWG Files (*.dwg)|*.dwg",
            FilterIndex = 2,
            RestoreDirectory = true,
            Multiselect = false,
            Title = @"Select block file to insert"
        };

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes