I have an old set of useful VBA functions, that I will enhance by adding some ObjectARX functionality, developed with Visual Basic .NET.
Essentially it will be a VBA project that calls fast ObjectArx functions.
So I built a small objectArx test class, it just adds simple objects to the drawing. DLL is loaded into Autocad (with NETLOAD), and activated through command line. It works great.
Next step is calling the ObjectARX methods from VBA. This can be achieved in 2 ways:
- Registering DLL for COM interop.
- Exporting DLL functions.
So first tried as COM object.
I compiled the ObjectARX project for COM interop, exposing the class. The resulting DLL was added to the old VBA project as COM reference, showing the ObjectARX class successfully. The class is now visible from VBA, I can instantiate it, I can call its methods.
Now comes the issue: The ObjectARX methods that do readonly operations work at full speed. However, the ObjectARX methods that do write operations into Autocad database FAIL (throwing eLockViolation exception). Seems like VBA is locking Autocad database, so that ObjectARX methods can't write.
For example, ObjectARX methods that have lines like this will fail when called from a VBA macro:
[...] Dim btr As BlockTableRecord = tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False) [...]
(Note that this line opens a database record for write operation).
When DLL is called by exporting its functions, for accessing them with the classic
DECLARE Sub myFunc LIB "myLibrary.dll" (byval param...)...
(BTW a complex process for me, achieved thanks to great tool "ExportDLL" for .NET)
then the result is the same: Methods that do write operations to Autocad database FAIL.
So, the problem is that VBA blocks all intents of ObjectArx methods to get write permissions to Autocad database, no matter if called through COM, or DLL exporting. And only when called from VBA!
If called from Autocad command line they work, without changing any line of code.
Why does VBA lock Autocad database for writing?
Tools used:
Autocad 2012
ObjectARX for Autocad 2012
Visual Studio 2010 (VB .NET)
Thanks
Solved! Go to Solution.
Solved by owenwengerd. Go to Solution.
A bit backwards? A gigabit backwards is more accurate.
And yes, of course you are right.
To help other people, I leave this sample to materialise your answer, please correct me if wrong:
Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager Dim lock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument Dim ta As Transaction = tm.StartTransaction() Try Dim bt As BlockTable = tm.GetObject(db.BlockTableId, OpenMode.ForRead, False) Dim btr As BlockTableRecord = tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False, True) ' ... do whatever ... ta.Commit() Finally ta.Dispose() lock.Dispose() End Try
Thanks!
FYI You only have to lock the document when:
You are modifying an entity in a database and you are being called directly (not via a command.Modal) from a Modeless dialog/PaletteSet Window, ActiveX interface, a command defined by the Session attribute, JavaScript API, or any application context initiated code
Whereever possible, you should run your commands from the Modal (document) context as the session will be automatically handled by AutoCAD for you.
Can't find what you're looking for? Ask the community or share your knowledge.