GLAVCVS Posted May 1 Posted May 1 The main difficulty in running the code is getting it to work in drawings other than the active document from which it's run. This is something we've already seen in other topics this forum Given this, the only option is to do it from ade.arx (Map and C3D) or via objectDBX (axdb##.dll). From what I've found out, Acad2000 doesn't expose axdb15.dll. But in later versions, it does. Once this is done, the rest is more easier. Quote
SLW210 Posted May 1 Posted May 1 Thanks for looking into it, I worked a while before realizing that AutoCAD 2000i was a hurdle as well. So, I'll look more at this when I can, but I'll probably go back to the Python, C#, Office Basic, UNO, etc. and work from the OpenOffice/ LibreOffice side, I had some headway in that direction before looking into LISP, though now you have me thinking about diving into ObjectDBX. Hopefully I can dig into this on the weekend. Maybe get BricsCAD or something as well. I'm falling behind on other projects, so no guarantee on working on this issue. Quote
GLAVCVS Posted May 1 Posted May 1 (edited) It's not difficult. You just need a newer version of AutoCAD. This code works. You just need to change the two ## at the end of "ObjectDBX.AxDbDocument.##" to the version number of your axdb##.dll. (defun C:BTCalc (/ *error* abks acapp adoc adocs atts att_data blkname blockname block_name cnt col dir display drawings exc_data find fonto headers inter preferences row strvalues tmp x xlpath dbx ) ;; Error handling function (defun *error* (msg) (if (vl-position msg '("console break" "Function cancelled" "quit / exit abort") ) (princ "Error!") (princ msg) ) (vlax-release-object dbx) (vl-exit-with-value "Program bombed, sorry") ) ;; Set the file dialog (setvar "filedia" 1) ;; Collect Block Name and Directory (setq blkname (getstring T "\nEnter block name: ")) (setq dir (getfiled "* Select any drawing in a directory *" "" "dwg" 4 ) ) ;; Check if Directory is valid (if (and blkname dir) (progn (setq dir (vl-filename-directory dir)) (if (setq drawings (vl-directory-files dir "*.dwg")); (vl-directory-files "c:\\" "*.dwg") (progn ;; Initialize variables (setq exc_data nil) (alert " Be patient ...\n Wait, please...") ;; Create AutoCAD application object ;;; (setq acapp (vlax-create-object ;;; (strcat "AutoCAD.Application." ;;; (itoa (fix (atof (getvar "acadver")))) ;;; ) ;;; ) ;;; ) ;;; (vlax-put-property acapp "Visible" :vlax-true) ;;; (setq preferences (vla-get-preferences acapp)) ;;; (setq display (vla-get-display preferences)) ;;; (vlax-put-property display "MaxAutoCADWindow" :vlax-true) ;;; (setq adocs (vla-get-documents acapp)) (setq cnt 0) (setq dbx (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument.##")); CHANGE ## FOR YOUR VERSION axdb##.dll ;; Process Drawings (foreach drawing drawings (prompt (strcat "\rProcessing " drawing " ...")) (vla-Open dbx (strcat dir "\\" drawing)) (vlax-for layout (vla-get-layouts dbx) (vlax-for obj (vla-get-block layout) (if (and (eq "AcDbBlockReference" (vla-get-objectname obj) ) (eq (setq block_name (if (= (vlax-get-property obj 'IsDynamicBlock ) :vlax-true ) (vla-get-effectivename obj) (vla-get-name obj) ) ) blkname ) (eq :vlax-true (vla-get-hasattributes obj)) ) (progn (if (= cnt 0) (setq headers (append (list "Drawing Name" "Layout Name" "Handle" "Block Name" ) headers ) ) ) (setq att_data (append (list drawing (vla-get-name layout) (vla-get-handle obj) blkname ) att_data ) ) (setq atts (vlax-invoke obj 'GetAttributes)) (foreach att atts (if (= cnt 0) (setq headers (append headers (list (vla-get-tagstring att)) ) ) ) (setq att_data (append att_data (list (vla-get-textstring att)) ) ) ) (setq exc_data (append (list att_data) exc_data)) (setq att_data nil) (setq cnt (1+ cnt)) ) ) ) ) ) (vlax-release-object dbx);; Release DBX object ;(mapcar (function (lambda (x) ;(vl-catch-all-apply ;(function (lambda () ;(if x ;(vlax-release-object x) ;) ;) ;) ;) ;) ;) ;(list adocs acapp) ;) ;;=============================== CSV Export ==================================== (setq xlpath (strcat (getvar "dwgprefix") (vl-filename-base (getvar "dwgname")) ".csv" ) ) (setq file (open xlpath "w")) (defun write-csv-line (lst sep) (write-line (apply 'strcat (mapcar (function (lambda (s) (strcat "\"" s "\"" sep))) lst ) ) file ) ) ;; Write headers and data (write-csv-line headers ",") (foreach row-data exc_data (write-csv-line row-data ",")) ;; Close CSV file (close file) (alert (strcat "Data exported to:\n" xlpath "\nYou can open it with LibreOffice Calc." ) ) ;;=============================================================================== ) ;; End of drawings processing ) ;; End of directory checking ) ;; End of blkname and dir checking ) ;; End of overall if condition (gc) (gc) ;(*error* nil) (prin1) ) PS: What I haven't checked is the rest of the code that manages the blocks because I don't have drawings to test. Edited May 1 by GLAVCVS Quote
SLW210 Posted May 1 Posted May 1 Can you not download the drawings from the OPs post? Yes, that one works fine at work. I haven't tried that one at home. It's this one that had some errors. Quote
GLAVCVS Posted May 1 Posted May 1 Maybe I didn't explain myself well. I've modified this code to make it work. The original you attached didn't work. At least for me. I'll try to download some drawings. Quote
GLAVCVS Posted May 1 Posted May 1 (edited) 3 hours ago, GLAVCVS said: It's not difficult. You just need a newer version of AutoCAD. This code works. You just need to change the two ## at the end of "ObjectDBX.AxDbDocument.##" to the version number of your axdb##.dll. (defun C:BTCalc (/ *error* abks acapp adoc adocs atts att_data blkname blockname block_name cnt col dir display drawings exc_data find fonto headers inter preferences row strvalues tmp x xlpath dbx ) ;; Error handling function (defun *error* (msg) (if (vl-position msg '("console break" "Function cancelled" "quit / exit abort") ) (princ "Error!") (princ msg) ) (vlax-release-object dbx) (vl-exit-with-value "Program bombed, sorry") ) ;; Set the file dialog (setvar "filedia" 1) ;; Collect Block Name and Directory (setq blkname (getstring T "\nEnter block name: ")) (setq dir (getfiled "* Select any drawing in a directory *" "" "dwg" 4 ) ) ;; Check if Directory is valid (if (and blkname dir) (progn (setq dir (vl-filename-directory dir)) (if (setq drawings (vl-directory-files dir "*.dwg")); (vl-directory-files "c:\\" "*.dwg") (progn ;; Initialize variables (setq exc_data nil) (alert " Be patient ...\n Wait, please...") ;; Create AutoCAD application object ;;; (setq acapp (vlax-create-object ;;; (strcat "AutoCAD.Application." ;;; (itoa (fix (atof (getvar "acadver")))) ;;; ) ;;; ) ;;; ) ;;; (vlax-put-property acapp "Visible" :vlax-true) ;;; (setq preferences (vla-get-preferences acapp)) ;;; (setq display (vla-get-display preferences)) ;;; (vlax-put-property display "MaxAutoCADWindow" :vlax-true) ;;; (setq adocs (vla-get-documents acapp)) (setq cnt 0) (setq dbx (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument.##")); CHANGE ## FOR YOUR VERSION axdb##.dll ;; Process Drawings (foreach drawing drawings (prompt (strcat "\rProcessing " drawing " ...")) (vla-Open dbx (strcat dir "\\" drawing)) (vlax-for layout (vla-get-layouts dbx) (vlax-for obj (vla-get-block layout) (if (and (eq "AcDbBlockReference" (vla-get-objectname obj) ) (eq (setq block_name (if (= (vlax-get-property obj 'IsDynamicBlock ) :vlax-true ) (vla-get-effectivename obj) (vla-get-name obj) ) ) blkname ) (eq :vlax-true (vla-get-hasattributes obj)) ) (progn (if (= cnt 0) (setq headers (append (list "Drawing Name" "Layout Name" "Handle" "Block Name" ) headers ) ) ) (setq att_data (append (list drawing (vla-get-name layout) (vla-get-handle obj) blkname ) att_data ) ) (setq atts (vlax-invoke obj 'GetAttributes)) (foreach att atts (if (= cnt 0) (setq headers (append headers (list (vla-get-tagstring att)) ) ) ) (setq att_data (append att_data (list (vla-get-textstring att)) ) ) ) (setq exc_data (append (list att_data) exc_data)) (setq att_data nil) (setq cnt (1+ cnt)) ) ) ) ) ) (vlax-release-object dbx);; Release DBX object ;(mapcar (function (lambda (x) ;(vl-catch-all-apply ;(function (lambda () ;(if x ;(vlax-release-object x) ;) ;) ;) ;) ;) ;) ;(list adocs acapp) ;) ;;=============================== CSV Export ==================================== (setq xlpath (strcat (getvar "dwgprefix") (vl-filename-base (getvar "dwgname")) ".csv" ) ) (setq file (open xlpath "w")) (defun write-csv-line (lst sep) (write-line (apply 'strcat (mapcar (function (lambda (s) (strcat "\"" s "\"" sep))) lst ) ) file ) ) ;; Write headers and data (write-csv-line headers ",") (foreach row-data exc_data (write-csv-line row-data ",")) ;; Close CSV file (close file) (alert (strcat "Data exported to:\n" xlpath "\nYou can open it with LibreOffice Calc." ) ) ;;=============================================================================== ) ;; End of drawings processing ) ;; End of directory checking ) ;; End of blkname and dir checking ) ;; End of overall if condition (gc) (gc) ;(*error* nil) (prin1) ) PS: What I haven't checked is the rest of the code that manages the blocks because I don't have drawings to test. @SLW210 Edited and tested in drawing Edited May 1 by GLAVCVS Quote
BIGAL Posted May 1 Posted May 1 @SLW210 Re Bricscad I have been using for around 4 years now all my coding is done using Bricscad Pro now V25, there is a couple of things in lisp that are different to Acad, But supports full lisp not like LT, if some thing is missing or does not seem to work they actually get back to you when you do a support request. The basic version has lisp but I would go for Pro. I dont use any VLE code as that is Bricscad only. Quote
SLW210 Posted May 2 Posted May 2 If I go Bricscad, I'll also have to look how other languages work in it as well. I wouldn't be surprised if Bricscad developers would be on board with creating an inbuilt solution to work with OpenOffice/LibreOffice. I may be close with a Python/UNO/Office Basic solution, I'll have to go back and check my notes and efforts. IIRC, I first looked into using AutoCAD with LibreOffice just around the time it first came out and I switched from OpenOffice. Quote
SLW210 Posted May 5 Posted May 5 I worked on this issue a bit over the weekend, still hitting the wall on a complete LISP solution. I may soon have a working combination Python, LISP and .NET solution, still testing before making an exe. Quote
SLW210 Posted May 5 Posted May 5 Not sure how this was missed (or probably just forgotten). https://www.theswamp.org/index.php?topic=31362.msg369311#msg369311 ;;; Get OpenOffice (or LibreOffice) Calc ;;; ;;; https://www.theswamp.org/index.php?topic=31362.msg369311#msg369311 ;;; ;;; By VovKa ;;; ;;; ;;; To use the code on BricsCAD you have to change this line (toward the end of the code): ;;; Code: ;;; (vlax-safearray->list Data) ;;; Into: ;;; Code: ;;; (vlax-safearray->list (vlax-variant-value Data)) ;;; The code can also be used for Libre Office. ;;; (vl-load-com) (defun vk_GetOOCalc (FileName SheetName Range / Data oRange oEndOfUsedArea oCursor oSheet oSheets oCalcDoc oController oDesktop oServiceManager ) (and (setq FileName (findfile FileName)) (setq oServiceManager (vlax-get-or-create-object "com.sun.star.ServiceManager")) (not (vl-catch-all-error-p (setq oDesktop (vl-catch-all-apply 'vlax-invoke-method (list oServiceManager 'createInstance "com.sun.star.frame.Desktop") ) ) ) ) (not (vl-catch-all-error-p (setq oCalcDoc (vl-catch-all-apply 'vlax-invoke-method (list oDesktop 'loadComponentFromURL (strcat "file:///" (vl-string-translate "\\" "/" FileName)) "_blank" 0 (vlax-make-safearray vlax-vbObject (cons 0 0)) ) ) ) ) ) (not (vl-catch-all-error-p (setq oSheets (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'getSheets))) ) ) (if SheetName (not (vl-catch-all-error-p (setq oSheet (vl-catch-all-apply 'vlax-invoke-method (list oSheets 'getByName SheetName) ) ) ) ) (if (not (vl-catch-all-error-p (setq oController (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'getCurrentController) ) ) ) ) (not (vl-catch-all-error-p (setq oSheet (vl-catch-all-apply 'vlax-invoke-method (list oController 'getActiveSheet) ) ) ) ) ) ) (or Range (setq Range (if (and (not (vl-catch-all-error-p (setq oCursor (vl-catch-all-apply 'vlax-invoke-method (list oSheet 'createCursor) ) ) ) ) (not (vl-catch-all-error-p (vl-catch-all-apply 'vlax-invoke-method (list oCursor 'gotoEndOfUsedArea 0) ) ) ) (not (vl-catch-all-error-p (setq oEndOfUsedArea (vl-catch-all-apply 'vlax-invoke-method (list oCursor 'getRangeAddress) ) ) ) ) ) (list 0 0 (vlax-get oEndOfUsedArea 'EndColumn) (vlax-get oEndOfUsedArea 'EndRow) ) ) ) ) (not (vl-catch-all-error-p (setq oRange (vl-catch-all-apply 'vlax-invoke-method (cons oSheet (cons 'getCellRangeByPosition Range)) ) ) ) ) (not (vl-catch-all-error-p (setq Data (vl-catch-all-apply 'vlax-invoke-method (list oRange 'getDataArray))) ) ) ) ;;; (not (vl-catch-all-error-p ;;; (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'Dispose)) ;;; ) ;;; ) (and oDesktop (vlax-invoke-method oDesktop 'Terminate)) (mapcar (function (lambda (v) (and (= (type v) 'VLA-OBJECT) (not (vlax-object-released-p v)) (vlax-release-object v) ) ) ) (list oRange oEndOfUsedArea oCursor oSheet oSheets oController oCalcDoc oDesktop oServiceManager ) ) (if Data (mapcar (function (lambda (r) (mapcar 'vlax-variant-value (vlax-safearray->list (vlax-variant-value r))) ) ) (vlax-safearray->list Data) ) ) ) (setq FileName "c:\\Temp\\Book1.ods" ; or "c:\\Temp\\Book1.xls" SheetName "Sheet1" ; or nil for current sheet Range '(0 0 10 10) ; or nil for all used cells ) (vk_GetOOCalc FileName SheetName Range) I haven't tested this out yet. Quote
GLAVCVS Posted May 5 Posted May 5 (edited) 4 hours ago, SLW210 said: Not sure how this was missed (or probably just forgotten). https://www.theswamp.org/index.php?topic=31362.msg369311#msg369311 ;;; Get OpenOffice (or LibreOffice) Calc ;;; ;;; https://www.theswamp.org/index.php?topic=31362.msg369311#msg369311 ;;; ;;; By VovKa ;;; ;;; ;;; To use the code on BricsCAD you have to change this line (toward the end of the code): ;;; Code: ;;; (vlax-safearray->list Data) ;;; Into: ;;; Code: ;;; (vlax-safearray->list (vlax-variant-value Data)) ;;; The code can also be used for Libre Office. ;;; (vl-load-com) (defun vk_GetOOCalc (FileName SheetName Range / Data oRange oEndOfUsedArea oCursor oSheet oSheets oCalcDoc oController oDesktop oServiceManager ) (and (setq FileName (findfile FileName)) (setq oServiceManager (vlax-get-or-create-object "com.sun.star.ServiceManager")) (not (vl-catch-all-error-p (setq oDesktop (vl-catch-all-apply 'vlax-invoke-method (list oServiceManager 'createInstance "com.sun.star.frame.Desktop") ) ) ) ) (not (vl-catch-all-error-p (setq oCalcDoc (vl-catch-all-apply 'vlax-invoke-method (list oDesktop 'loadComponentFromURL (strcat "file:///" (vl-string-translate "\\" "/" FileName)) "_blank" 0 (vlax-make-safearray vlax-vbObject (cons 0 0)) ) ) ) ) ) (not (vl-catch-all-error-p (setq oSheets (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'getSheets))) ) ) (if SheetName (not (vl-catch-all-error-p (setq oSheet (vl-catch-all-apply 'vlax-invoke-method (list oSheets 'getByName SheetName) ) ) ) ) (if (not (vl-catch-all-error-p (setq oController (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'getCurrentController) ) ) ) ) (not (vl-catch-all-error-p (setq oSheet (vl-catch-all-apply 'vlax-invoke-method (list oController 'getActiveSheet) ) ) ) ) ) ) (or Range (setq Range (if (and (not (vl-catch-all-error-p (setq oCursor (vl-catch-all-apply 'vlax-invoke-method (list oSheet 'createCursor) ) ) ) ) (not (vl-catch-all-error-p (vl-catch-all-apply 'vlax-invoke-method (list oCursor 'gotoEndOfUsedArea 0) ) ) ) (not (vl-catch-all-error-p (setq oEndOfUsedArea (vl-catch-all-apply 'vlax-invoke-method (list oCursor 'getRangeAddress) ) ) ) ) ) (list 0 0 (vlax-get oEndOfUsedArea 'EndColumn) (vlax-get oEndOfUsedArea 'EndRow) ) ) ) ) (not (vl-catch-all-error-p (setq oRange (vl-catch-all-apply 'vlax-invoke-method (cons oSheet (cons 'getCellRangeByPosition Range)) ) ) ) ) (not (vl-catch-all-error-p (setq Data (vl-catch-all-apply 'vlax-invoke-method (list oRange 'getDataArray))) ) ) ) ;;; (not (vl-catch-all-error-p ;;; (vl-catch-all-apply 'vlax-invoke-method (list oCalcDoc 'Dispose)) ;;; ) ;;; ) (and oDesktop (vlax-invoke-method oDesktop 'Terminate)) (mapcar (function (lambda (v) (and (= (type v) 'VLA-OBJECT) (not (vlax-object-released-p v)) (vlax-release-object v) ) ) ) (list oRange oEndOfUsedArea oCursor oSheet oSheets oController oCalcDoc oDesktop oServiceManager ) ) (if Data (mapcar (function (lambda (r) (mapcar 'vlax-variant-value (vlax-safearray->list (vlax-variant-value r))) ) ) (vlax-safearray->list Data) ) ) ) (setq FileName "c:\\Temp\\Book1.ods" ; or "c:\\Temp\\Book1.xls" SheetName "Sheet1" ; or nil for current sheet Range '(0 0 10 10) ; or nil for all used cells ) (vk_GetOOCalc FileName SheetName Range) I haven't tested this out yet. I've tried testing it but ServiceManager doesn't seem to work. Maybe I need to modify something in my LibreOffice installation. Edited May 6 by GLAVCVS Quote
BIGAL Posted May 6 Posted May 6 I posted open Libre Calc about page 2 like theswamp code. The one problem I found, maybe you have a solution was to create a Blank Calc worksheet, the only way I got around this was to open existing "Blank.OSD". Its been a while since I looked at Libre Calc I know got it Get & Put cell values, may look at what else I can get, you posted some code it has getusedrange etc which is very handy. I added get columnwidth and merge cells range to my Excel code I will see if they work with Libre Calc handy when making a table to match Calc. Quote
SLW210 Posted May 6 Posted May 6 I didn't have a chance to check anything at home yesterday. I had this LISP opening a Calc sheet at home, before I realized AutoCAD 2000i was an issue. AutoCAD use LibreOffice instead of Excel - Page 4 - AutoLISP, Visual LISP & DCL - AutoCAD Forums Ran out of time over the weekend and had to download Visual Studio as well as other work, didn't get a chance to download Bricscad. I did get my thumb drive loaded and brought to work, maybe get a chance to review notes. I thought something similar was posted, but this thread is getting long. I posted for the information on Bricscad in the header mainly, might need it. ;;; To use the code on BricsCAD you have to change this line (toward the end of the code): ;;; Code: ;;; (vlax-safearray->list Data) ;;; Into: ;;; Code: ;;; (vlax-safearray->list (vlax-variant-value Data)) Posted earlier. https://wiki.documentfoundation.org/Documentation/DevGuide/Professional_UNO#Automation_Bridge I think going down the mixed programs is the more automated way to do this, too many hurdles with LISP only to automate. So far I have LISP for exporting and importing the Attribute Values, Python/Tkinter (Tkinter provides an interface like a user form/DCL) with Pyautocad for AutoCAD and for Calc UNO or (maybe this, I need to look more into it)... LibrePythonista is an extension for LibreOffice Calc. The extension allows Interactive Python code to be run directly in a spreadsheet, and VB.NET for updating the revisions for the .CSVs and .DWGs (still working on that), might go to C# again, but I found some examples in VB.NET. Quote
SLW210 Posted May 6 Posted May 6 11 hours ago, GLAVCVS said: I've tried testing it but ServiceManager doesn't seem to work. Maybe I need to modify something in my LibreOffice installation. Can you post any error codes? I haven't read that entire thread from the swamp in a while, might look through the comments. Quote
BIGAL Posted May 6 Posted May 6 (edited) I tested with Bricscad and used the Service manager approach, could get and set cells that is about as far as I went. See page 2. Need an existing ODS as opens that file. Edited May 7 by BIGAL Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.