New Member
Posts: 2
Registered: ‎04-09-2012
Message 1 of 3 (559 Views)
Accepted Solution

.ReadDwgFile vs. Active Document

559 Views, 2 Replies
04-09-2012 06:02 AM

Hello all,


I'm trying to programmatically extra some data from a set of .DWG files. I've been trying to figure out how to do this using the ObjectArx 2010 .NET library against AutoCAD 2010.


I've been able to successfully extract the data from one file using some traversal logic based on a file that's read in starting with the following code:


Dim doc As Document = Application.DocumentManager.MdiActiveDocument         

Dim db As Database = doc.Database         

Dim ed As Editor = doc.Editor         '

Dim blockToFind As String = "(Name of a block I'm searching for)"

Dim tr As Transaction = doc.TransactionManager.StartTransaction()

From there, I basically search for the named block, if it's found, I gather a collection of the different types of "columns", then search through each record and column combination to get the data I need.


It works exactly as I need when I do it in this manner except for one problem. For this method to work, the file I'm taking the data from has to be open in AutoCAD (as in File-->Open-->File name.dwg). Since I've got a large number of files to go through, I want to extract this data as part of a loop that traverses through a directory.


In order to do this, I tried to use .ReadDwgFile to access the file's contents. The code I'm using to initialize the file access is:


Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim db As Database = New Database(FalseTrue)         

Dim ed As Editor = doc.Editor        

Dim fileName As String = "(Path to file)"         


db.ReadDwgFile(fileName, System.IO.FileShare.Read, False"")         

Catch ex As System.Exception             

ed.WriteMessage(String.Format("{0}Unable to read drawing file. Exception Message: {1}"Environment.NewLine, ex.Message))             


End Try         

'name of block to find         

Dim blockToFind As String = "(Name of a block I'm searching for)"

Dim tr As Transaction = doc.TransactionManager.StartTransaction()

In both cases, my logic starts with me getting a BlockTable object by using the document's database.BlockTableId. The name of the block I'm looking for is then used as an argument in a BlockTable.Has function. In the first set of code (when the document is manually opened in AutoCAD), the block I'm looking for is found. When the same function is used when the file is opened programmatically the .Has function returns nothing.


I notice when debugging that the size of the .ApproxNumObjects value when opening up the object using .ReadDwgFile is much, much larger than when the file is opened manually. What are some of the differences between these two access methods? Is there any clue as to why the .Has function returns nothing in the second case?

*Expert Elite*
Posts: 8,982
Registered: ‎06-29-2007
Message 2 of 3 (553 Views)

Re: .ReadDwgFile vs. Active Document

04-09-2012 07:22 AM in reply to: jfc0911



what I'm missing is the part in your two samples that show us how you get the BlockTableID and how you then use the ".Has" function.

But this statement:

Dim tr As Transaction = doc.TransactionManager.StartTransaction()

In your second version (using db.ReadDwgFile) makes me thinking you may have troubles understanding that the .ReadDwgFile-function does not create a document (does not open the DWG-file in the AutoCAD-editor), so with the "doc.Trans...." you create a transaction for the DWG-file currently opened in AutoCAD-editor, but not the DWG-file you try to access via the .ReadDwgFile-function.


Show us the part where you look for the blocktable, then we can goon.


- alfred -

Ingenieur Studio HOLLAUS ... www.hollaus.at
New Member
Posts: 2
Registered: ‎04-09-2012
Message 3 of 3 (546 Views)

Re: .ReadDwgFile vs. Active Document

04-09-2012 08:04 AM in reply to: Alfred.NESWADBA

Hello alfred,


Thank you so much for your prompt response! You actually appeared to have solved my problem.


I was a bit confused about the transaction manager but a few clues that you gave me in your response allowed me to determine what my problem was. It was simply that I was using the BlockTableId of the "active" document in both cases.


As you were correct in believing, when I manually opened the file, this was the correct BlockTableId, but when there was no file open in the editor, it was obviously not the id I needed.


So, the original BlockTable object instantiation was:

Using tr

     Dim bt As BlockTable = TryCast(tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead), BlockTable)

 in both cases.


When I changed my code to switch from manual open mode to auto open mode, I never changed this line. When using the programmatic method, it should be:

Dim bt As BlockTable = TryCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)


In hindsight, it's a pretty dumb mistake, but I'm extremely new to this API and AutoCAD so I'm trying to learn as much as a I can in a quick fashion which will invariably lead to mistakes.

Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.