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

database.SaveAs() always requires the saved drawing to be recovered.

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
richardpangburn
159 Views, 2 Replies

database.SaveAs() always requires the saved drawing to be recovered.

I have a method that opens a .dwt as a side database, edits some block attribute values in the first paperspace layout, and then saves the drawing at a location that I pass in.

 

I've tried this on my dwt which has a titleblock xref and some attribute blocks and on a totally empty brand-new drawing that has nothing in it. I've tried setting the DwgVersion to current, the version for 2010, and the version for 2013, no avail. I've used it in Map3D 2020 and basic AutoCAD 2018 and it doesn't seem to matter. My last-ditch effort was to change my .dlls from the 2020 ObjectArx to the 2017 ones and that had no effect.

 

If I open the resulting drawing, DO NOT recover, and simply save and close the drawing, the errors are gone. If I open the drawing and DO NOT recover, the Audit command returns zero errors.

 

If I open the drawing and elect to recover, the result is that 1 object is erased. I'm out of ideas so I figured I would ask here. This is the method in question. Ignore some of the weird/repetitive variable and constant names. I changed some stuff for privacy reasons and I trimmed out some of the options in my Switch/Cases to keep the post shorter.

 

My next thought is that I have to actually open the drawing in document manager and save it through the document object method. Is that worth exploring?

 

 

  public void CopyNewDWG2(string parentProjectDirectory, string dwtPath, string gobyType, string projectDescription, string projectNumber, string ProjectNum, string drawingNumber)
        {
            string saveDirectory = Path.Combine(parentProjectDirectory, gobyType);
            Directory.CreateDirectory(saveDirectory);
            string fileName = saveDirectory + "\\" + drawingNumber + ".dwg";

            Document thisDrawing = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            try
            {
                using (DocumentLock documentLock = thisDrawing.LockDocument())
                {
                    //Set up a new database as the go-by drawing
                    using (Database sideDatabase = new Database())
                    {
                        sideDatabase.ReadDwgFile(dwtPath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
                        sideDatabase.CloseInput(true);
                        HostApplicationServices.WorkingDatabase = sideDatabase;

                        using (Transaction sideTransaction = sideDatabase.TransactionManager.StartTransaction())
                        {
                            //Get the layouts
                            DBDictionary sideLayouts = (DBDictionary)sideTransaction.GetObject(sideDatabase.LayoutDictionaryId, OpenMode.ForRead);

                            //Set the layout to layout1 (first paper space layout)
                            foreach (DBDictionaryEntry layout in sideLayouts)
                            {
                                Layout destinationLayout = (Layout)sideTransaction.GetObject(layout.Value, OpenMode.ForRead);
                                if (destinationLayout.LayoutName != "Model")
                                {
                                    if (destinationLayout.TabOrder == 1)
                                    {
                                        //Access the current layout (should be paper space) and iterate through it's block table to find the blocks that will need to be updated.
                                        BlockTableRecord sidePaperSpace = sideTransaction.GetObject(destinationLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
                                        foreach (ObjectId objectId in sidePaperSpace)
                                        {
                                            RXClass blockClass = RXObject.GetClass(typeof(BlockReference));
                                            if (objectId.ObjectClass == blockClass)
                                            {
                                                BlockReference blockReference = sideTransaction.GetObject(objectId, OpenMode.ForRead) as BlockReference;
                                                if (blockReference != null && blockReference.Name != "Paper_Space")
                                                {
                                                    //Find each block and update the values for the given project information.
                                                    switch (blockReference.Name)
                                                    {
                                                        //===========Title block===========//
                                                        case Constants.BlockAndAttributeNames.TheNameOfTheBlockIWant:
                                                            AttributeCollection attributeCollectionTBLK = blockReference.AttributeCollection;
                                                            if (attributeCollectionTBLK != null && attributeCollectionTBLK.Count > 0)
                                                            {
                                                                blockReference.UpgradeOpen();
                                                                foreach (ObjectId objectId2 in attributeCollectionTBLK)
                                                                {
                                                                    AttributeReference attribute = sideTransaction.GetObject(objectId2, OpenMode.ForWrite) as AttributeReference;
                                                                    switch (attribute.Tag)
                                                                    {
                                                                        case Constants.BlockAndAttributeNames.ATTR1:
                                                                            attribute.TextString = ProjectNum;
                                                                            break;

                                                                        //Set the Facility ID Name/Project Desecription
                                                                        case Constants.BlockAndAttributeNames.ATTR2:
                                                                            attribute.TextString = projectDescription;
                                                                            break;

                                                                        //Set the DWG Number
                                                                        case Constants.BlockAndAttributeNames.ATTR3:
                                                                            attribute.TextString = drawingNumber;
                                                                            drawingNumber = attribute.TextString;
                                                                            break;
                                                                    }
                                                                }
                                                            }
                                                            break;
                                                        default:
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            //Save a copy of the now-updated goby drawing into the desired path.
                            sideTransaction.Commit();
                            HostApplicationServices.WorkingDatabase = thisDrawing.Database;
                            sideDatabase.SaveAs(fileName, true, DwgVersion.Current, thisDrawing.Database.SecurityParameters);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

 

  

2 REPLIES 2
Message 2 of 3

It looks to me that the cause of the issue is the way you create the side database. You should use the overloaded constructor that has 2 boolean argument, because you DO NOT want the constructor to build a default drawing in the side database, instead, the drawing is the side database is created by reading external drawing file (*.dwg/*.dwt). So the code should be:

 

using (Database sideDatabase = new Database(false, true))
{
  sideDatabase.ReadDwgFile(....);
  ...
}

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 3

Thank you sir!

 

You are, as usual, correct. I made the suggested change and the errors are gone. Thank you for taking the time to help me again.

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost