enotfromthisdocument error

enotfromthisdocument error

anishkt
Contributor Contributor
2,427 Views
14 Replies
Message 1 of 15

enotfromthisdocument error

anishkt
Contributor
Contributor

Hi,

Posted below is an excerpt from my code which is much bigger. However, a "enotfromthisdocument" exception comes up while executing the code at the enlarged/underlined code statement.

Can someone assist as to how this can be sorted out.

'Start a transaction

Using tr1 As Transaction = acDoc.TransactionManager.StartTransaction()
Dim blkDb As Database = New Database(False, True)
blkDb.ReadDwgFile("C:\Base\BarChairD.dwg", IO.FileShare.ReadWrite, False, "")
Dim BlkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName("C:\Base\BarChairD.dwg")
Dim id As ObjectId = blkDb.Insert(BlkName, blkDb, True)
If id.IsNull Then
ed.WriteMessage(vbLf & "Failed to insert block")
Return
End If


'Open the Block table record Model space for write

Dim acBlkTblRecbc As BlockTableRecord = CType(tr1.GetObject(blkDb.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

Dim br As New BlockReference(p1, id)


'' Add the new object to the block table record and the transaction
acBlkTblRecbc.AppendEntity(br)
br.SetDatabaseDefaults()
tr1.AddNewlyCreatedDBObject(br, True)

tr1.Commit()

End Using

0 Likes
Accepted solutions (2)
2,428 Views
14 Replies
Replies (14)
Message 2 of 15

_gile
Consultant
Consultant

You start a transaction from the active document TransactionManager (tr1) and try to use this transaction with the newly created Database (blkDb).

You have to start the transaction from the blkdb TransactionManager.

 

Using blkDb As Database = New Database(False, True)
    blkDb.ReadDwgFile("C:\Base\BarChairD.dwg", IO.FileShare.ReadWrite, False, "")
    Using tr1 As Transaction = blkDb.TransactionManager.StartTransaction()
'do your stuff with blkDb here
End Using 'disposing the transaction End Using 'disposing the database


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 15

anishkt
Contributor
Contributor

Thank you Giles, it took care of the error message. But the block is still not inserted. Do you see any glaring reasons?

 'Start a transaction
                    Using blkDb As Database = New Database(False, True)
                        blkDb.ReadDwgFile("C:\Base\BarChairD.dwg", IO.FileShare.Read, True, "")
                        Using tr1 As Transaction = blkDb.TransactionManager.StartTransaction()

                            Dim BlkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName("C:\Base\BarChairD.dwg")
                            Dim id As ObjectId = blkDb.Insert(BlkName, blkDb, True)
                            If id.IsNull Then
                                ed.WriteMessage(vbLf & "Failed to insert block")
                                Return
                            End If


                            'Open the Block table record Model space for write

                            Dim acBlkTblRecbc As BlockTableRecord = CType(tr1.GetObject(blkDb.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                            Dim br As New BlockReference(p1, id)


                            '' Add the new object to the block table record and the transaction
                            acBlkTblRecbc.AppendEntity(br)
                            br.SetDatabaseDefaults()
                            tr1.AddNewlyCreatedDBObject(br, True)

                            tr1.Commit()

                        End Using
                    End Using

Do

0 Likes
Message 4 of 15

_gile
Consultant
Consultant

You have to save the database

 

                    Using blkDb As Database = New Database(False, True)
                        blkDb.ReadDwgFile("C:\Base\BarChairD.dwg", IO.FileShare.Read, True, "")
                        Using tr1 As Transaction = blkDb.TransactionManager.StartTransaction()

                            Dim BlkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName("C:\Base\BarChairD.dwg")
                            Dim id As ObjectId = blkDb.Insert(BlkName, blkDb, True)
                            If id.IsNull Then
                                ed.WriteMessage(vbLf & "Failed to insert block")
                                Return
                            End If


                            'Open the Block table record Model space for write

                            Dim acBlkTblRecbc As BlockTableRecord = CType(tr1.GetObject(blkDb.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                            Dim br As New BlockReference(p1, id)


                            '' Add the new object to the block table record and the transaction
                            acBlkTblRecbc.AppendEntity(br)
                            br.SetDatabaseDefaults()
                            tr1.AddNewlyCreatedDBObject(br, True)

                            tr1.Commit()

                        End Using
                        blkDb.SaveAs("C:\Base\BarChairD.dwg", DwgVersion.Current)
                    End Using


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 15

anishkt
Contributor
Contributor

Hi Giles,

Thank you very much for your time. Sorry to keep bothering you.

But the last tweak you suggested did not work. It is giving an efileerror.

Cant figure out the issue. The block  has an attribute, could that be the cause.

Anish

0 Likes
Message 6 of 15

_gile
Consultant
Consultant

You should explain what you're trying to achieve instead of posting not working code because reading more attentively your code make me se some confusion about your goal.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 15

anishkt
Contributor
Contributor

Hi,

I have a drawing with some MText,  I want to insert an external file as a block at the Mtext insertion point. the file path of the file to be inserted is specified(C:\Base\BarChairD.dwg).

The issue I am facing is the insertion of the block

 

The inserted block is an attribute and my objective is to change the attribute to match each Mtext value in the drawing on which the code is executed. I have not made the code for this part as I have not been able to insert the block successfully.

 Hope the explanation is clear. As I mentioned, this is part of a larger code and it may be confusing if I post the whole code.

Regards,

Anish

PS

the efileerror is not appearing now but the block is still not inserted.

 

0 Likes
Message 8 of 15

norman.yuan
Mentor
Mentor

According to what your described, it seems to me, you want to insert a block DWG file into another drawing file, which is not currently opened in AutoCAD editor (or it is already opened in AutoCAD editor). It sounds like there should have 2 drawings (or 2 databases) involved: one has an MTEXT in it as target drawing to be processed; and the other one as block file to be inserted into the former. However, your code logic does not indicate it is that case and only one drawing/database is dealt with by the code.

 

What your code does is:

 

1. You create an empty side database and read the file "C:\Base\BarChairD.dwg" into it. Now the question: is this database/dwg file is the one that has said MText in it and you want to insert a block into it?

 

2. The strange thing after the side database is created: you insert the side database into ITSELF(!!!) by this line of code, which also has the third parameter passed in as "True" (if a external file being inserted as Block, it should be "False")

 

Dim id As ObjectId = blkDb.Insert(BlkName, blkDb, True)

3. Eventually you save the side database back as "....\BarChairD.dwg". So is the database/file is the block file, or is the actual target drawing you want to insert a block into it?

 

So, what is you really want to do?

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 9 of 15

_gile
Consultant
Consultant

Here's a quick and dirty example to show how to insert a dwg file as block into the current space of a database.

 

        /// <summary>
        /// Inserts a dwg file as block
        /// </summary>
        /// <param name="targetDb">Database to which insert the block reference</param>
        /// <param name="fileName">Path of the dwg file to be inserted</param>
        /// <param name="blockName">Block name</param>
        /// <param name="position">Insertion point</param>
        /// <param name="attribValues">Dictionary of attribute values (tag, value pairs)</param>
        /// <returns></returns>
        private static ObjectId InsertBlockReference(Database targetDb, string fileName, string blockName, Point3d position, Dictionary<string, string> attribValues)
        {
            // import the file as block definition in the target database block table
            ObjectId btrId;
            using (var sourceDb = new Database(false, true))
            {
                sourceDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                btrId = targetDb.Insert(blockName, sourceDb, true);
            }

            // insert the block in the target database current space
            ObjectId brId;
            using (var tr = targetDb.TransactionManager.StartTransaction())
            {
                var curSpace = (BlockTableRecord)tr.GetObject(targetDb.CurrentSpaceId, OpenMode.ForWrite);
                var br = new BlockReference(position, btrId);
                brId = curSpace.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);

                // add the attribute references to the attribute collection of the block reference
                var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                var attDefclass = RXObject.GetClass(typeof(AttributeReference));
                foreach (ObjectId id in btr)
                {
                    if (id.ObjectClass == attDefclass)
                    {
                        var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                        var attRef = new AttributeReference();
                        attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                        br.AttributeCollection.AppendAttribute(attRef);
                        tr.AddNewlyCreatedDBObject(attRef, true);
                        if (attribValues.ContainsKey(attRef.Tag))
                        {
                            attRef.TextString = attribValues[attRef.Tag];
                        }
                    }
                }
                tr.Commit();
            }
            return brId;
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 10 of 15

anishkt
Contributor
Contributor

 

Hi Yuan,

All I want is to insert an external drawing into the drawing in which the code is executed. BarChairD.Dwg is the external file. It has an attribute which needs to be modified. The drawing with the Mtext is where the block needs to be inserted.

Please see my comments inserted into your text below. I have got a cue from your reply and modified the code. I will post the code including the Mtext part which was not there earlier. Now the barchairD drawing is inserted in the Mtext drawing, but it is not inserted at the specific point p1 specified separately. Now I think it is only a matter of some minor tweaks.

Regards,

Anish

'' Select profile text
                Dim prTSSet As PromptSelectionResult
                prTSSet = ed.SelectCrossingWindow(New Point3d(XprT1, YprT1, 0), New Point3d(XprT2, YprT2, 0), acSelFtrprT)
                Dim acSSetPrT As SelectionSet = prTSSet.Value
                Dim Tso As SelectedObject = acSSetPrT.Item(0)
                If prTSSet.Status = PromptStatus.OK Then


                    Using acTrans3 As Transaction = acCurDb3.TransactionManager.StartTransaction()

                       

                        Dim acBlkTblTxt As MText
                        acBlkTblTxt = CType(acTrans3.GetObject(Tso.ObjectId, OpenMode.ForRead), MText)
                        MsgBox(acBlkTblTxt.Text)

                        'Start a transaction
                        Using blkDb As Database = New Database(False, True)
                            blkDb.ReadDwgFile("C:\Base\BarChairD.dwg", IO.FileShare.Read, False, "")
                            Using tr1 As Transaction = blkDb.TransactionManager.StartTransaction()

                                Dim BlkName As String = SymbolUtilityServices.GetBlockNameFromInsertPathName("C:\Base\BarChairD.dwg")
                                Dim id As ObjectId = acCurDb3.Insert(BlkName, blkDb, False)
                                If id.IsNull Then
                                    ed.WriteMessage(vbLf & "Failed to insert block")
                                    Return
                                End If


                                'Open the Block table record Model space for write

                                Dim acBlkTblRecbc As BlockTableRecord = CType(tr1.GetObject(blkDb.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                                Dim br As New BlockReference(p1, id)

                                '' Add the new object to the block table record and the transaction
                                acBlkTblRecbc.AppendEntity(br)
                                br.SetDatabaseDefaults()
                                tr1.AddNewlyCreatedDBObject(br, True)

                                tr1.Commit()

                            End Using
                            ' blkDb.SaveAs("C:\Base\BarChairD", DwgVersion.Current)
                        End Using

                        acTrans3.Commit()
                    End Using

 

According to what your described, it seems to me, you want to insert a block DWG file into another drawing file, which is not currently opened in AutoCAD editor- The drawing with Mtext is open (or it is already opened in AutoCAD editor). It sounds like there should have 2 drawings (or 2 databases) involved: one has an MTEXT in it as target drawing to be processed; and the other one as block file to be inserted into the former-correct. However, your code logic does not indicate it is that case and only one drawing/database is dealt with by the code.

 

What your code does is:

 

1. You create an empty side database and read the file "C:\Base\BarChairD.dwg" into it. Now the question: is this database/dwg file is the one that has said MText in it and you want to insert a block into it-No, this is the block file?

 

2. The strange thing after the side database is created: you insert the side database into ITSELF(!!!) by this line of code, which also has the third parameter passed in as "True" (if a external file being inserted as Block, it should be "False")

Ok, i changed it to false, but it does not solve the problem

 

Dim id As ObjectId = blkDb.Insert(BlkName, blkDb, True)

3. Eventually you save the side database back as "....\BarChairD.dwg". So is the database/file is the block file, or is the actual target drawing you want to insert a block into it?

This was suggested by Giles when I said that the block is not getting inserted. I am not sure what it does.

 

So, what is you really want to do?

0 Likes
Message 11 of 15

anishkt
Contributor
Contributor

Thanks Gilles,

I shall modify and come back to you. Thank you so much for your kind assistance.

Regards,

Anish

0 Likes
Message 12 of 15

_gile
Consultant
Consultant
Accepted solution

Here's an example with a command to insert the block in the curent space of the active drawing.

 

        [CommandMethod("INSERTBARCHAIRD")]
        public static void InsertBarChairD()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            // select a mtext
            var options = new PromptEntityOptions("\nSelect Mtext: ");
            options.SetRejectMessage("\nselected object is not a MText.");
            options.AddAllowedClass(typeof(MText), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK) 
                return;

            string fileName = @"C:\Base\BarChairD.dwg";
            string blockName = "BarChairD";

            using (var tr = db.TransactionManager.StartTransaction())
            {
                // check if the block already exists in the block table
                ObjectId btrId;
                var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (blockTable.Has(blockName))
                {
                    btrId = blockTable[blockName];
                }
                else
                {
                    // check if the file exists
                    if (!File.Exists(fileName))
                    {
                        ed.WriteMessage("\nFile not found.");
                        return;
                    }
                    // import the file as block definition in the target database block table
                    using (var sourceDb = new Database(false, true))
                    {
                        sourceDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                        btrId = db.Insert(blockName, sourceDb, true);
                    }
                }

                // open the selected mtext
                var mtext = (MText)tr.GetObject(result.ObjectId, OpenMode.ForRead);

                // insert the block reference
                var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                var br = new BlockReference(mtext.Location, btrId);
                curSpace.AppendEntity(br);
                tr.AddNewlyCreatedDBObject(br, true);

                // add the attribute references to the attribute collection of the block reference
                var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                var attDefclass = RXObject.GetClass(typeof(AttributeDefinition));
                foreach (ObjectId id in btr)
                {
                    if (id.ObjectClass == attDefclass)
                    {
                        var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                        var attRef = new AttributeReference();
                        attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                        br.AttributeCollection.AppendAttribute(attRef);
                        tr.AddNewlyCreatedDBObject(attRef, true);
                        attRef.TextString = mtext.Text;
                    }
                }

                tr.Commit();
            }
        }

 

<EDIT: corrected code>



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 15

anishkt
Contributor
Contributor
Accepted solution

Thanks Gilles, It worked.

My code was in vb, hence has to do a bit of conversion.

Thanks for your assitance.

0 Likes
Message 14 of 15

anishkt
Contributor
Contributor

Hi,

Thanks for your help in a earlier issue. As as extension to the same, how to give values to other attribute tags within the same block.

I have a block with 5 attribute definitions.

Regards,

Anish

0 Likes
Message 15 of 15

anishkt
Contributor
Contributor

Sorry for the trouble. I got a way to do it.

0 Likes