Save BlockReference to separate file

Save BlockReference to separate file

denisyukJ
Advocate Advocate
478 Views
7 Replies
Message 1 of 8

Save BlockReference to separate file

denisyukJ
Advocate
Advocate

Hi,

I have several blocks (BlockReference) in model space and I would like to save them separatly exactly like _WBLOCK command does. I've tried to play around Wblock() method of DB class, but no luck. Maybe I fed a wrong id to it or I simply dont understand how method works.

Any help or hint will be highly appreciated.

BR, Evgeniy

 

 

0 Likes
Accepted solutions (1)
479 Views
7 Replies
Replies (7)
Message 2 of 8

ActivistInvestor
Mentor
Mentor

@denisyukJ wrote:

Hi,

I have several blocks (BlockReference) in model space and I would like to save them separatly exactly like _WBLOCK command does. I've tried to play around Wblock() method of DB class, but no luck. Maybe I fed a wrong id to it or I simply dont understand how method works.

Any help or hint will be highly appreciated.

BR, Evgeniy


 

Most participants here will not endeavour to guess why your code may be not be working.

 

Post the code so that others can look at it and tell you what it is doing wrong.

 

 

 

 

Message 3 of 8

denisyukJ
Advocate
Advocate

Hi, @ActivistInvestor 

This peace of code saves block in separate file but as block reference already existing in modele space so I can not use directory includes this block as library. _WBLOCK command saves a block as block definition.

 

        static public void WblockEntity()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptSelectionResult prRes = ed.GetSelection();
            if (prRes.Status != PromptStatus.OK)
                return;

            ObjectIdCollection objIds = new ObjectIdCollection();
            ObjectId[] objIdArray = prRes.Value.GetObjectIds();

            // Copy objectIds to objectIdCollection
            foreach (ObjectId id in objIdArray)
                objIds.Add(id);

            using (Database newDb = new Database(true, false))
            {
                db.Wblock(newDb, objIds, Point3d.Origin, DuplicateRecordCloning.Ignore);
                string FileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
                newDb.SaveAs(FileName, DwgVersion.Newest);
            }
        }

 

 

 

0 Likes
Message 4 of 8

ActivistInvestor
Mentor
Mentor

Unfortunately, the docs for WBlock() are deficient, and do not go into detail on the 4 overloaded versions of that method. They only show the declarations for each and describe what one of the overloads does.

 

You need to use the overload of Wblock() that takes a single ObjectId as an argument, and returns a new Database (that you must dispose of when finished with it):

 

public Database Wblock(ObjectId blockTableRecordId)

 

You pass the ObjectId of the BlockTableRecord for the block that you want to write to the new Database.

 

 

Message 5 of 8

denisyukJ
Advocate
Advocate

@ActivistInvestor,

Thank you, I've made 2 options:

>> 1st option uses Wblock(ObjectId id) as you suggest;

>> 2nd option uses Wblock(ObjectIdCollection col, Point3d pt)

Unfortunately, both of them led me to the same result -- new file is empty.

 

Here's code:

        public void WblockEntity()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                if (acBlkTbl.Has("054010V"))
                {
                    var blkTblRecId = acBlkTbl["054010V"];
                    using (Database newDb = new Database(true, false))
                    {
                        db.Wblock(blkTblRecId);
                        string fileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
                        newDb.SaveAs(fileName, DwgVersion.Newest);
                    }
                }

                tr.Commit();
            }
        }

 

 public void WblockEntity() // ObjectId of the BlockTableRecord for the block
 {
     Document doc = Application.DocumentManager.MdiActiveDocument;
     Database db = doc.Database;

     using (Transaction tr = db.TransactionManager.StartTransaction())
     {
         BlockTable acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
         if (acBlkTbl.Has("054010V"))
         {
             ObjectIdCollection objIds = new ObjectIdCollection();

             var blkTblRecId = acBlkTbl["054010V"];
             var blkTblRec = tr.GetObject(blkTblRecId, OpenMode.ForRead) as BlockTableRecord;
             foreach (var ObjId in blkTblRec)
             {
                 objIds.Add((ObjectId)ObjId);
             }

             using (Database newDb = new Database(true, false))
             {
                 db.Wblock(objIds, new Point3d(0, 0, 0));
                 string fileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
                 newDb.SaveAs(fileName, DwgVersion.Newest);
             }
         }

         tr.Commit();
     }
 }

 

 

 

0 Likes
Message 6 of 8

ActivistInvestor
Mentor
Mentor

Look again at the the declaration for the Wblock(ObjectId) method overload I showed in my previous reply.

 

What does it return?

Message 7 of 8

denisyukJ
Advocate
Advocate

Looks like this code is working 😀 Thank you @ActivistInvestor 

public void WblockEntity()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTable acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
        if (acBlkTbl.Has("054010V"))
        {
            var blkTblRecId = acBlkTbl["054010V"];
            Database newDb = new Database(true, false);
            newDb = db.Wblock(blkTblRecId);
            string fileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
            newDb.SaveAs(fileName, DwgVersion.Newest);
        }

        tr.Commit();
    }
}

 

0 Likes
Message 8 of 8

norman.yuan
Mentor
Mentor
Accepted solution

While you got the block definition saved as block drawing, this portion of code is still problematic:

        if (acBlkTbl.Has("054010V"))
        {
            var blkTblRecId = acBlkTbl["054010V"];
            Database newDb = new Database(true, false);
            newDb = db.Wblock(blkTblRecId);
            string fileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
            newDb.SaveAs(fileName, DwgVersion.Newest);
        }

Firstly, you DO NOT create a Database instance, and then only leave/lose it in memory. Secondly, the Database instance created by db.WBlock() also needs to be disposed, as @ActivistInvestor clearly suggested. So the code should be:

        if (acBlkTbl.Has("054010V"))
        {
            var blkTblRecId = acBlkTbl["054010V"];
            using (var newDb = db.Wblock(blkTblRecId))
            {
                string fileName = "C:\\Users\\User\\OneDrive\\Desktop\\wblock.dwg";
                newDb.SaveAs(fileName, DwgVersion.Newest);
            }
        }

 

Norman Yuan

Drive CAD With Code

EESignature