Jump to content

need help with lisp to make a list of layouts name and specific block attribute value from each layout and save to csv


Recommended Posts

Posted (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 by aridzv
  • aridzv changed the title to need help with lisp to make a list of layouts name and specific block attribute value from each layout and save to csv
Posted

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)
         )

 

  • Thanks 1
Posted

@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

Posted (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 by aridzv
Posted

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.

Posted (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 by aridzv
Posted

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.

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...