aridzv Posted May 1 Posted May 1 (edited) Hi. I need help with lisp to make a list of layouts name and specific block attribute value and save to csv. I found this code and it is working. I try to add a second column to put a value from a specific block attribute that exist in each layout. I get this error: ; ----- LISP : Call Stack ----- ; [0]...C:EXPORTLAYOUTSTOCSV <<-- ; ; ----- Error around expression ----- ; '((0 . "INSERT") (2 . "framenumber") (410 . LAYOUT)) ; in file : ; C:\Temp\ExportLayoutsToCSV.lsp ; here is the code I use: ;;;;;;;;;;;;;;;;;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-script-to-generate-list-of-all-layouts-table-of-contents-as/td-p/13203001;;;;;;;;;;;;;;;;;;;;; (defun c:ExportLayoutsToCSV (/ doc doc-path doc-name toc-folder csv-file-name layout-list csv-file-path file-handle ss blkname att frmatt frmtag frmval frametxtobj layout lyt) (if (not (vl-load-com)) (vl-load-com)) ; Load COM support if not already loaded ;; Get the full path of the active document (setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object))) (setq doc-path (vlax-get-property doc 'Path)) (setq doc-name (vlax-get-property doc 'Name)) ;; Ensure the document path exists (if doc-path (progn ;; Construct the "table of contents" folder path (setq toc-folder (strcat doc-path "\\table of contents")) ;; Check if folder exists, if not create it (if (not (vl-file-directory-p toc-folder)) (vl-mkdir toc-folder) ) ;; Construct the CSV file path (setq csv-file-name (strcat "Table of Contents - " (vl-filename-base doc-name) ".csv")) (setq csv-file-path (strcat toc-folder "\\" csv-file-name)) ;; Get the list of layout names (setq layout-list (layoutlist)) ;; Open file for writing (setq file-handle (open csv-file-path "w")) (if file-handle (progn (write-line "layout,name" file-handle) ;; Write the layout names to the file (foreach layout (layoutlist) (if(setq ss (ssget "X" '((0 . "INSERT") (2 . "framenumber") (410 . layout)))) (progn (setq blkname (ssname ss 0)) (setq frmatt (vlax-invoke (vlax-ename->vla-object blkname) 'getattributes)) (foreach att frmatt (setq frmtag (vla-get-tagstring att)) (princ frmtag) (setq frmval (vla-get-textstring att)) (if (= frmtag "FRAMENUM") (progn (setq frametxtobj frmval) (setq lyt layout) ) (setq frametxtobj "-") );if );foreach );progn );if ;(princ frametxtobj) (setq writeln (strcat layout "," frametxtobj)) (write-line writeln file-handle) ) (princ (strcat "\nLayout names exported to: " csv-file-path)) (close file-handle) ) (princ "\nError: Unable to open file for writing.") ) ) (princ "\nError: Unable to determine the document path.") ) (princ) ; Suppress return value in the command line ) see attached sample drawing and a csv file show the needed result. thanks, aridzv. export.dwg export.csv Edited May 1 by aridzv Quote
Steven P Posted May 1 Posted May 1 Not sure if this would work for you? https://lee-mac.com/macatt.html Quote
aridzv Posted May 1 Author Posted May 1 40 minutes ago, Steven P said: Not sure if this would work for you? https://lee-mac.com/macatt.html no, but thanks. Quote
SLW210 Posted May 1 Posted May 1 I didn't check the original at the link. Maybe, seems to work for me. ;;;;;;;;;;;;;;;;;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-script-to-generate-list-of-all-layouts-table-of-contents-as/td-p/13203001;;;;;;;;;;;;;;;;;;;;; (defun c:ExportLayoutsToCSV (/ doc doc-path doc-name toc-folder csv-file-name layout-list csv-file-path file-handle ss blkname att frmatt frmtag frmval frametxtobj layout lyt) (if (not (vl-load-com)) (vl-load-com)) ; Load COM support if not already loaded ;; Get the full path of the active document (setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object))) (setq doc-path (vlax-get-property doc 'Path)) (setq doc-name (vlax-get-property doc 'Name)) ;; Ensure the document path exists (if doc-path (progn ;; Construct the "table of contents" folder path (setq toc-folder (strcat doc-path "\\table of contents")) ;; Check if folder exists, if not create it (if (not (vl-file-directory-p toc-folder)) (vl-mkdir toc-folder) ) ;; Construct the CSV file path (setq csv-file-name (strcat "Table of Contents - " (vl-filename-base doc-name) ".csv")) (setq csv-file-path (strcat toc-folder "\\" csv-file-name)) ;; Get the list of layout names (setq layout-list (layoutlist)) ;; Open file for writing (setq file-handle (open csv-file-path "w")) (if file-handle (progn (write-line "layout,name" file-handle) ;; Write the layout names to the file ;; Redid this part ------------------------------------------------------------ (foreach layout layout-list (setq frametxtobj "-") ; default if nothing found (if (and layout (setq ss (ssget "X" (list '(0 . "INSERT") '(2 . "framenumber") (cons 410 layout))))) (progn (setq blkname (ssname ss 0)) (setq frmatt (vlax-invoke (vlax-ename->vla-object blkname) 'getattributes)) (foreach att frmatt (setq frmtag (vla-get-tagstring att)) (setq frmval (vla-get-textstring att)) (if (= frmtag "FRAMENUM") (setq frametxtobj frmval) ) ) ) ) (setq writeln (strcat layout "," frametxtobj)) (write-line writeln file-handle) ) ;;------------------------------------------------------------------------- (princ (strcat "\nLayout names exported to: " csv-file-path)) (close file-handle) ) (princ "\nError: Unable to open file for writing.") ) ) (princ "\nError: Unable to determine the document path.") ) (princ) ; Suppress return value in the command line ) What you had... (foreach layout (layoutlist) (if(setq ss (ssget "X" '((0 . "INSERT") (2 . "framenumber") (410 . layout)))) (progn (setq blkname (ssname ss 0)) (setq frmatt (vlax-invoke (vlax-ename->vla-object blkname) 'getattributes)) (foreach att frmatt (setq frmtag (vla-get-tagstring att)) (princ frmtag) (setq frmval (vla-get-textstring att)) (if (= frmtag "FRAMENUM") (progn (setq frametxtobj frmval) (setq lyt layout) ) (setq frametxtobj "-") );if );foreach );progn );if ;(princ frametxtobj) (setq writeln (strcat layout "," frametxtobj)) (write-line writeln file-handle) ) 1 Quote
aridzv Posted May 1 Author Posted May 1 @SLW210 Thanks!!! why the "and" here: (if (and layout (setq ss (ssget "X" (list '(0 . "INSERT") '(2 . "framenumber") (cons 410 layout))))) was the solution? again - many thanks!! aridzv Quote
aridzv Posted May 1 Author Posted May 1 (edited) I turned the attribute extraction part to function. but when there is a block with more then one attribute it only bring one and ignore any others. see the code: ;;;;;;;;;;;;;;;;;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-script-to-generate-list-of-all-layouts-table-of-contents-as/td-p/13203001;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;https://www.cadtutor.net/forum/topic/97663-need-help-with-lisp-to-make-a-list-of-layouts-name-and-specific-block-attribute-value-from-each-layout-and-save-to-csv/; (defun c:ExportLayoutsToCSV1 (/ doc doc-path doc-name toc-folder csv-file-name layout-list csv-file-path file-handle flnm ss blkname att frmatt frmtag frmval frametxtobj layout lyt drwnm drwdt) (if (not (vl-load-com)) (vl-load-com)) ; Load COM support if not already loaded ;; Get the full path of the active document (setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object))) (setq doc-path (vlax-get-property doc 'Path)) (setq doc-name (vlax-get-property doc 'Name)) ;; Ensure the document path exists (if doc-path (progn ;; Construct the "Layouts list" folder path (setq toc-folder (strcat doc-path "\\Layouts list")) ;; Check if folder exists, if not create it (if (not (vl-file-directory-p toc-folder)) (vl-mkdir toc-folder) ) ;; Construct the CSV file path (setq csv-file-name (strcat "Layouts list - " (vl-filename-base doc-name) ".csv")) (setq csv-file-path (strcat toc-folder "\\" csv-file-name)) ;; Get the list of layout names (setq layout-list (layoutlist)) (setq flnm (getvar "DWGNAME")) (setq flnm (substr flnm 1 (- (strlen flnm) 4))) ;; Open file for writing (setq file-handle (open csv-file-path "w")) (if file-handle (progn (write-line "Sheet Name,drawing Name,Frame Name,Date" file-handle) ;; Write the layout names to the file ;; Redid this part ------------------------------------------------------------ (foreach layout layout-list (setq frametxtobj "-") ; default if nothing found (setq drwnm "-") ; default if nothing found (setq drwdt "-") ; default if nothing found (setq frametxtobj (getatt layout "framenumber" "FRAMENUM")) (setq drwdt (getatt layout "test" "DATE")) (setq drwnm (getatt layout "test" "FILENAME")) (princ drwnm) (if (= frametxtobj nil) (setq frametxtobj "-") ) (if (= drwnm nil) (setq drwnm "X") ) (if (= drwdt nil) (setq drwdt "Y") ) (setq writeln (strcat flnm "-" layout ".pdf" "," drwnm "," frametxtobj "," drwdt)) (write-line writeln file-handle) ) ;;------------------------------------------------------------------------- (princ (strcat "\nLayout names exported to: " csv-file-path)) (close file-handle) ) (princ "\nError: Unable to open file for writing.") ) ) (princ "\nError: Unable to determine the document path.") ) (princ) ; Suppress return value in the command line ) ;;;;;;;;;;;;;;defun c:ExportLayoutsToCSV1;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun getatt (ly blk attnm / ss blknm frmatt att frmtag frmval frmtxtobj) (if (and ly (setq ss (ssget "X" (list '(0 . "INSERT") (cons 2 blk) (cons 410 ly))))) (progn (setq blknm (ssname ss 0)) (setq frmatt (vlax-invoke (vlax-ename->vla-object blknm) 'getattributes)) (foreach att frmatt (setq frmtag (vla-get-tagstring att)) (setq frmval (vla-get-textstring att)) (if (= frmtag attnm) (setq frmtxtobj frmval) ) ) ) ) ) and a sample drawing and CSV result. any help will be appreciated... thanks, aridzv. Drawing1.dwg Layouts list - Drawing1.csv Edited May 1 by aridzv Quote
BIGAL Posted May 1 Posted May 1 Do you want the data to go straight to Excel ? Can be done no need for a CSV. A bonus can set the width of the columns to match size of text. Quote
aridzv Posted May 2 Author Posted May 2 (edited) 4 hours ago, BIGAL said: Do you want the data to go straight to Excel ? Can be done no need for a CSV. A bonus can set the width of the columns to match size of text. not at this time. CSV is enough for now. here is the code using function named "getatt" to get the attribute value: ;;;;;;;;;;;;;;;;;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/lisp-script-to-generate-list-of-all-layouts-table-of-contents-as/td-p/13203001;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;https://www.cadtutor.net/forum/topic/97663-need-help-with-lisp-to-make-a-list-of-layouts-name-and-specific-block-attribute-value-from-each-layout-and-save-to-csv/; (defun c:ExportLayoutsToCSV (/ doc doc-path doc-name toc-folder csv-file-name layout-list csv-file-path file-handle flnm ss blkname att frmatt frmtag frmval frametxtobj drwnm drwdt layout lyt) (vl-load-com) ;; Get the full path of the active document (setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object))) (setq doc-path (vlax-get-property doc 'Path)) (setq doc-name (vlax-get-property doc 'Name)) ;; Ensure the document path exists (if doc-path (progn ;; Construct the "Layouts list" folder path (setq toc-folder (strcat doc-path "\\Layouts list")) ;; Check if folder exists, if not create it (if (not (vl-file-directory-p toc-folder)) (vl-mkdir toc-folder) ) ;; Construct the CSV file path (setq csv-file-name (strcat "Layouts list - " (vl-filename-base doc-name) ".csv")) (setq csv-file-path (strcat toc-folder "\\" csv-file-name)) ;; Get the list of layout names (setq layout-list (layoutlist)) (setq flnm (getvar "DWGNAME")) (setq flnm (substr flnm 1 (- (strlen flnm) 4))) ;; Open file for writing (setq file-handle (open csv-file-path "w")) (if file-handle (progn (write-line "Sheet Name,drawing name,Frame Name,Drawing update" file-handle) ;; Write the layout names to the file ;; Redid this part ------------------------------------------------------------ (foreach layout layout-list (setq frametxtobj nil) (setq drwnm nil) (setq drwdt nil) (setq frametxtobj(getatt layout "framenumber" "FRAMENUM")) (setq drwnm (getatt layout "Project_Title2" "DRAWING_NAME")) (setq drwdt (getatt layout "Project_Title2" "DATE")) (if (or (= frametxtobj nil) (= frametxtobj "")) (setq frametxtobj "-") ) (if (or (= drwnm nil) (= drwnm "")) (setq drwnm "-") ) (if (or (= drwdt nil) (= drwdt "")) (setq drwdt "-") ) (setq writeln (strcat flnm "-" layout ".pdf" "," drwnm "," frametxtobj "," drwdt)) (write-line writeln file-handle) ) ;;------------------------------------------------------------------------- (princ (strcat "\nLayout names exported to: " csv-file-path)) (close file-handle) ) (princ "\nError: Unable to open file for writing.") ) ) (princ "\nError: Unable to determine the document path.") ) (princ) ; Suppress return value in the command line ) ;;;;;;;;;;;;;;;;;;;;;;;;;; (defun getatt(ly bl at / sss blknm frmattx frmtagx frmvalx frametxtobjx) (if (and ly (setq sss (ssget "X" (list '(0 . "INSERT") (cons 2 bl) (cons 410 ly))))) (progn (setq blknm (ssname sss 0)) (setq frmattx (vlax-invoke (vlax-ename->vla-object blknm) 'getattributes)) (foreach attx frmattx (setq frmtagx (vla-get-tagstring attx)) (setq frmvalx (vla-get-textstring attx)) (if (= frmtagx at) (setq frametxtobjx frmvalx) );if );foreach );progn );if frametxtobjx );defun Edited May 2 by aridzv Quote
SLW210 Posted May 2 Posted May 2 I look later today if I have time. I fixed your first one by debugging it. If you use the VLIDE to debug, have a look at Debugging Code with the Visual LISP IDE | Lee Mac Programming For the Blade Debugging BLADE Debugging LISP with Steve Johnson - “BricsCAD® Unplugged” Visual Studio Code 1 Quote
BIGAL Posted May 2 Posted May 2 If you go direct to Excel you can add multiple dwg details. From Cad can find last row used so can add new dwg details. below existing. 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.