Jump to content

Read csv file then plot to PDF


kleber

Recommended Posts

Hi all,  my lisp knowledge is very limited so I was hoping someone could help mw with this.  I have a lisp which I copied from a Autodesk forum (https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/export-to-pdf-lisp-routine/td-p/5704455) and tweaked a little to suit my needs. It basically plot all layout tabs to PDF (with revision letter at the end of the pdf name). It works just fine.

Now, what I want it to do is to instead of printing all layouts, read a csv file "title_block.csv" and only plot to PDF layouts named in that csv file (column B) starting from cell B2. It would be similar to what Lee Mac's UpdateTitleBlockV1-9 does to update title blocks. Any help would be much appreciated😉

 

Cheers

#(vl-load-com)
(defun c:demo (/ hms:get_atts filename hnd lst lst1 name otab path ss)

  (defun hms:get_atts (enm / att obj)
    (if (or (and (eq (type enm) 'ENAME)
                 (setq obj (vlax-ename->vla-object enm))
                 (eq (vla-get-hasattributes obj) :vlax-true)
            )
            (and (eq (type enm) 'VLA-OBJECT)
                 (setq obj enm)
                 (eq (vla-get-hasattributes obj) :vlax-true)
            )
        )
      (mapcar
        '(lambda (att)
           (cons (vla-get-TagString att) (vla-get-TextString att))
         )
        (vlax-invoke obj "GetAttributes")
      )
    )
  )

  ;;(cond ((setq path (acet-ui-pickdir "Select directory" (getvar "dwgprefix")))

  ; check that pdf directory exists
  (cond ((setq dwgpre (strcat (getvar "dwgprefix") "PDF"))
	 (if (= (vl-file-directory-p dwgpre) nil)
	 (vl-mkdir dwgpre)
	)
	 (setq pdfname (strcat (vl-filename-base (getvar "dwgname"))))
;-----------------------------------------------------------------------
	 
         (setq otab (getvar 'CTAB))
         (foreach layt (layoutlist)
           (setvar 'CTAB layt)
           (if (setq ss (ssget "_X" (list '(0 . "INSERT") '(2 . "A1 TITLE NCL - new logo") '(66 . 1) (cons 410 (getvar 'CTAB)))))
             (progn
               (setq hnd  (ssname ss 0)
                     lst  (hms:get_atts hnd)
		     ;lst1 '("DRAWING_NUMBER" "SHEET_NUMBER" "REVISION_NUMBER" "SHEET_SIZE")
                     lst1 '("RV")
                     name ""
               )
               (foreach n lst1
                 (if (setq a (assoc n lst))
                   (setq name (strcat name "-" (cdr a)))
                 )
               )
	       (setq sht (strcat(getvar "ctab")))
               (setq filename (strcat dwgpre "\\" pdfname "-" sht " Rev " (vl-string-left-trim "-" name) ".pdf"))
               ;(command "_.-export" "_PDF" "_C" "_YES" "ISO full bleed A3 (420.00 x 297.00 MM)" "_M" "_L" "1:2" "_YES" "A3.ctb" "_YES" filename)
	       (command "_.-PLOT"
	"Y"									;Detailed plot configuration? [yes/no]
	Layt									;Enter Layout name or [?],layout1:
	"Dwg To PDF.pc3"							;Enter an output device name
	"ISO full bleed A3 (420.00 x 297.00 MM)"				;Enter paper size 	
	"M"									;Paper units: "M" for mm
	"L"									;Enter drawing orientation: "L" for Landscaping
	"N"									;Upside down? "N"
	"E"									;"E" for extents
	"1:2"									;Plot scale: Custom "1:2"
	"C"									;Counter "c"
	"Y"									;Plot Style? "y"
	"A3.ctb"								;Enter plot style: "A3.ctb"
	"Y"									;Plot line  weights?
	"N"									;plot line scaling?
	"N"									;Paper space first?
	"N"									;Hide? 
	filename								;Directory to save
	"N"									;save changes to page setup?
	"Y"									;proceed with plot?
     ); command
             )
           )
         )
         (setvar 'CTAB otab)
        )
  )
  (princ)
)#

 

Link to comment
Share on other sites

Hey BIGAL, thanks for suggestion. I'll have a look at them and see if I can come up with something out of it.

Cheers

Link to comment
Share on other sites

  • 2 weeks later...

Hi,

 

Today I had a little extra time so I tried to work on it. I Think I made some progress but this lisp still doesn't achieve what I intend. I used Lee Mac's code/functions to read a csv file in the same folder as the .dwg (title_block.csv) which has only one set of data in column 1. (layout to be ploted, eg: row1 "Layout" row2 "200" row3 "300"). However it doesn't send the command "_.-PLOT" and I get erros like: Unknown command "PC3".  Press F1 for help. Unknown command "00 X 297.00 MM)".  Press F1 for help.... etc

Would someone be able to tell me what is wrong with it?

#(defun c:PDF ( / data file )
  (command "MODEL")
  (setq cmd (getvar 'cmdecho)) (setvar 'cmdecho 0)
  
  ; check that pdf directory exists
	(setq dwgpre (strcat (getvar "dwgprefix") "PDF"))
  ;if doesn't exist create one
	(if (= (vl-file-directory-p dwgpre) nil)
		(vl-mkdir dwgpre)
	)
	(setq pdfname (strcat (vl-filename-base (getvar "dwgname"))))

    (if
        (and
            (setq file (findfile "title_block.csv"))
	    (setq data (cdr(LM:readcsv file)))
        )
        (progn
	  
            ;(princ "\n(")
            (foreach layout (list data)
	        ;(princ "\n    ")  (prin1 layout)
		;(princ "\n)")
	      	(command
	"_.-PLOT"
	"Y"									;Detailed plot configuration? [yes/no]
	Layout									;Enter Layout name or [?],layout1:
	"Dwg To PDF.pc3"							;Enter an output device name
	"ISO full bleed A3 (420.00 x 297.00 MM)"				;Enter paper size 	
	"M"									;Paper units: "M" for mm
	"L"									;Enter drawing orientation: "L" for Landscaping
	"N"									;Upside down? "N"
	"E"									;"E" for extents
	"1:2"									;Plot scale: Custom "1:2"
	"C"									;Counter "c"
	"Y"									;Plot Style? "y"
	"A3.ctb"								;Enter plot style: "A3.ctb"
	"Y"									;Plot line  weights?
	"N"									;plot line scaling?
	"N"									;Paper space first?
	"N"									;Hide? 
	(strcat dwgpre "\\" pdfname "-" (getvar "ctab") ".pdf")			;Directory to save
	"N"									;save changes to page setup?
	"Y"									;proceed with plot?

	                
		    );command
	      	(prompt "\nSuccessfully Plot.....")
		;(princ "\n)")
            )
        );progn
    )
    (princ)
)
(princ)
;; Read CSV  -  Lee Mac
;; Parses a CSV file into a matrix list of cell values.
;; csv - [str] filename of CSV file to read
 
(defun LM:readcsv ( csv / des lst sep str )
    (if (setq des (open csv "r"))
        (progn
            (setq sep (cond ((vl-registry-read "HKEY_CURRENT_USER\\Control Panel\\International" "sList")) (",")))
            (while (setq str (read-line des))
                (setq lst (cons (LM:csv->lst str sep 0) lst))
            )
            (close des)
        )
    )
    (reverse lst)
)

;; CSV -> List  -  Lee Mac
;; Parses a line from a CSV file into a list of cell values.
;; str - [str] string read from CSV file
;; sep - [str] CSV separator token
;; pos - [int] initial position index (always zero)
 
(defun LM:csv->lst ( str sep pos / s )
    (cond
        (   (not (setq pos (vl-string-search sep str pos)))
            (if (wcmatch str "\"*\"")
                (list (LM:csv-replacequotes (substr str 2 (- (strlen str) 2))))
                (list str)
            )
        )
        (   (or (wcmatch (setq s (substr str 1 pos)) "\"*[~\"]")
                (and (wcmatch s "~*[~\"]*") (= 1 (logand 1 pos)))
            )
            (LM:csv->lst str sep (+ pos 2))
        )
        (   (wcmatch s "\"*\"")
            (cons
                (LM:csv-replacequotes (substr str 2 (- pos 2)))
                (LM:csv->lst (substr str (+ pos 2)) sep 0)
            )
        )
        (   (cons s (LM:csv->lst (substr str (+ pos 2)) sep 0)))
    )
)

(defun LM:csv-replacequotes ( str / pos )
    (setq pos 0)
    (while (setq pos (vl-string-search  "\"\"" str pos))
        (setq str (vl-string-subst "\"" "\"\"" str pos)
              pos (1+ pos)
        )
    )
    str
)#

 

Edited by kleber
Link to comment
Share on other sites

I understand. Well, maybe I didn't explain it properly. I created a excel spreadsheet which is used as a drawing register. Basically, user click in a button to extract all attributes from all title blocks from all .dwg in a folder which then populate the table in the sheet. Then after editing the table the user can update all drawing with a click of a button. The third button would call the command plot to PDF for every Layout listed in the table. Therefore I want to be flexible enough so it does not print all layouts in the drawing.

Currently my lisp uses (layoutlist) function and loops through all layouts and plots PDF. But I want to create a list  (layout)  from the csv file and only plot those without prompting the user for which layout number to be plotted.

 

Link to comment
Share on other sites

Unless there are layouts named '200' and '300' the CSV seems strange.

 

The main issue I think is the data variable.

It is already a list (containing sublists) here:

(setq data (cdr (LM:readcsv file)))

So this cannot work:

(foreach layout (list data)

Assuming the first column contains the layout names, maybe this will:

(foreach layout (mapcar 'car data)

 

BTW: It is always a good idea to keep CMDECHO switched on while debugging code.

Link to comment
Share on other sites

Hi Roy,

 

That's right, the layouts are named "200", "201", etc... You suggestion did the trick!

Thank you so much! 

Link to comment
Share on other sites

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