Author Topic: Help with sorting lists and using "cons" to add multiple lists.  (Read 8224 times)

0 Members and 1 Guest are viewing this topic.

0john0

  • Guest
Help with sorting lists and using "cons" to add multiple lists.
« on: January 10, 2019, 11:48:22 AM »
Hello, I'm back for more help as I'm starting to get myself tied in knots  :opps:

I'm still tinkering with my batch plotting code from here: http://www.theswamp.org/index.php?topic=54582.0

I'm trying to add the option to select which sheets to plot, rather than just plotting the entire list (often 20+ sheets).

I haven't started coding the input side of things, as I think I'll be ok with that.

The code was working (thanks to Ron for the help), and I understood how it worked (mostly). I have tried to change a little bit at a time and use vl-remove-if-not to process the existing list containing the variable that are passed to my plot function, and remove any element that doesn't match the sheet selection.

I can get vl-remove-if-not to pull out the required element from the list, but I can't seem to figure out to get the results back into a format that is accepted by the plot function. I thought that using cons looked like the way to do it, but alas no joy.

The only way I can get it to work at the moment is by nesting a couple of foreach which looks ugly, and is doing a lot of redundant processing.

This is my code as it stands (with the nested foreach for processing the drawing border blocks into a list containing the sheet number, print window coordinates, and PDF file path.

Code: [Select]
;;;################################ Block Processing Function ################################;;;
(defun blockproc (dwgname path   pltyp  plsize /     ss
  i hnd scl    lst    at     ax     shtno
  file dest llpt   urpt   mn     mx     tb
  plst shts nlst
)
  (cond
    ((setq
       ss (ssget "_X"
'((0 . "INSERT") (2 . "*A*BORD*") (410 . "MODEL"))
  )
     )
     (repeat (setq i (sslength ss))
       (setq hnd (ssname ss (setq i (1- i)))
     scl (cdr (assoc 41 (entget hnd)))
       )
       (setq at (entnext hnd)
     ax (entget at)
       )
       (while
(/= "SEQEND" (cdr (assoc 0 ax)))
  (if
    (= "SHEETNO" (cdr (assoc 2 ax)))
     (progn (setq shtno (cdr (assoc 1 ax)))
     )
  )
  (setq at (entnext at)
ax (entget at)
  )
       ) ;_while
       (setq dest
      (strcat path "\\" (strcat dwgname "_SHEET_" shtno ".pdf"))
       )
       (vla-getboundingbox (vlax-ename->vla-object hnd) 'mn 'mx)
; get min and max points of block envelope and set lower left/upper right
       (setq llpt (vlax-safearray->list mn)
     urpt (vlax-safearray->list mx)
       )

       (setq lst (cons (list shtno llpt urpt dest) lst))
; construct list for sorting by sheet no
       (princ "\nL")
       (princ lst)
     ) ;_repeat

     (setq shts (list "1" "3")) ; test values for selecting which pages to print
     (foreach n shts
       (setq
plst (vl-remove-if-not '(lambda (x) (vl-position n x)) lst) ; remove elements from [b]lst[/b] which do not match [b]shts[/b] list
       )
       (princ "\nP")
       (princ plst)

       (setq nlst (cons plst nlst)) ; construct [b]nlst[/b] from output of vl-remove-if-not
;     ) ;_foreach n ; commented out to nest[b] tb[/b]
     (princ "\nN")
(princ nlst)
     (foreach tb
      (vl-sort plst ;
       '(lambda (a b) (< (atoi (car a)) (atoi (car b))))  ; sort is redundant but won't work without it
      )
;(princ tb)
;     (setq test (cadr tb))
;     (princ test)
       (mainplot pltyp
plsize
(cadr tb)
(caddr tb)
plstyle
(last tb)
scl
       )
     ) ;_foreach tb
) ;_foreach n NEST
    )
    (t
     (setq alrtmsgbrd
    (strcat
      dwgname
      ": No drawing borders found.\nScreenshot this message and contact: john \nCannot continue. Exiting... "
    )
     )
     (alert
       alrtmsgbrd
     )
     (exit)
    )
  ) ;_cond
  (princ)
) ;_blockproc


Mainplot code:
Code: [Select]
(defun mainplot
(pltyp plsize llpt urpt plstyle dest
scl / lenx leny nurpt furpt
scx
)

  (setq lenx (- (cadr urpt) (cadr llpt)) ; calculate length of X
scx  (/ lenx scl)
  ) ; convert to 1:1 scale
;;;  (princ scl)
;;;  (princ "\n")
;;;  (princ lenx)
;;;  (princ "\n")
;;;  (princ scx)
;;; conditional check of block height to allow a tolerance for scaled blocks, and apply paper size multiplier to set length of Y
  (cond ((and (>= scx 160)
      (<= scx 235)
      (setq leny (fix (* 1.482 lenx)))
)
)
((and (>= scx 250)
      (<= scx 340)
      (setq leny (fix (* 1.467 lenx)))
)
)
((and (>= scx 350)
      (<= scx 485)
      (setq leny (fix (* 1.454 lenx)))
)
)
((and (>= scx 520)
      (<= scx 710)
      (setq leny (fix (* 1.443 lenx)))
)
)
((and (>= scx 720)
      (<= scx 1020)
      (setq leny (fix (* 1.429 lenx)))
)
)
(t
(setq alrtmsgscl
(strcat
  dwgname
  ": Scale out of bounds.\nScreenshot this message and contact: john.stewart@smd.co.uk \nCannot continue. Exiting... "
)
)
(alert
   alrtmsgscl
)
(exit)
)
  ) ;_cond

  (setq nurpt (list leny lenx) ; set local new upper right for block
furpt (mapcar '+ llpt nurpt) ; add lower left to set global final upper right for block
  )

  (if (= pltyp "DWG to PDF.pc3") ; If PDF. Run PDF plot. Else run paper plot
    (command "-plot"    "Y"   "Model" pltyp  plsize "M"
     "L"    "N"    "W"   llpt furpt "F"    "C"    "Y"
     plstyle    "Y"   "A" dest "N"    "Y"
    ) ;_command

;;;## Test Code ##   
;;;    (progn
;;;      (princ "PAPER\n")
;;;      (princ llpt)
;;;      (princ urpt)
;;;    )

    (command "-plot"    "Y"   "Model" pltyp  plsize "M"
     "L"    "N"    "W"   llpt furpt "F"    "C"    "Y"
     plstyle    "Y"   "A" "N" "N"    "Y"
    ) ;_command
  ) ;_if

)

I can see that cons is creating nlist but with additional parentheses closing the entire list, and causes mainplot to fail at the
Code: [Select]
setq lenx
I've been trying to get my head around it all day, and I've got myself a bit tied up  :nerdyembarassed:

Any help/advice is greatlyappreciated as always.

Cheers,

John



0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #1 on: January 10, 2019, 11:51:33 AM »
Full code if it's needed for explantion:

Code: [Select]
(defun C:X-PLOT
       (/ dcl_id fn fname status plsize pltyp plstyle userclick)



  (vl-load-com)
  (or op1 (setq op1 "r1"))
  (or op2 (setq op2 ""))
  (or op3 (setq op3 ""))
  (setvar "CMDECHO" 0) ; Turn echo OFF
  (setq dwgname (strcat (vl-filename-base (getvar "dwgname"))))
; get drawing number from filename
  (vl-mkdir "C:\\PDF") ; create PDF directory
  (setq path (strcat "C:\\PDF\\" dwgname))
  (x-plot_dialog) ; set path using drawing number
  (setq dcl_id
(load_dialog fname)
; load .DCL code GUI
  )
;;;############################### DCL Dialog Box Handling ##############################;;;
  (cond
    ((>= dcl_id 0)
     (cond
       ((new_dialog "xplot" dcl_id)
(set_tile "rb1" "1")
(setq plstyle "standard.ctb")
(set_tile "rb5" "1")
(setq op1 "rb5")
(setq op2 "")
(setq op3 "")
(setq plsize "ISO A0 (841.00 x 1189.00 MM)")
(setq pltyp "DWG to PDF.pc3")

;;;################################ Plot Style Selection ################################;;;
(action_tile
  "rb1"
  "(setq plstyle \"standard.ctb\")"
)

(action_tile
  "rb2"
  "(setq plstyle \"hyd circuit.ctb\")"
)

(action_tile
  "rb3"
  "(setq plstyle \"colour assy.ctb\")"
)

;;;############################# Size and Output Selection #############################;;;
(action_tile
  "op1"
  "(progn
    (set_tile op3 \"0\")
                              (setq op1 $value op3 \"\")
            (set_tile op2 \"0\")
                              (setq op1 $value op2 \"\")
            )"
)

(action_tile
  "op2"
  "(progn
    (set_tile op1 \"0\")
                              (setq op2 $value op1 \"\")
    (set_tile op3 \"0\")
                              (setq op2 $value op3 \"\")
            )"
)

(action_tile
  "op3"
  "(progn
    (set_tile op2 \"0\")
                              (setq op3 $value op2 \"\")
            (set_tile op1 \"0\")
                              (setq op3 $value op1 \"\")
            )"
)
(set_tile "op1" op1)
(set_tile "op2" op2)
(set_tile "op3" op3)

;;;################################ OK/Cancel Selection ################################;;;
(action_tile
  "cancel"
  "(done_dialog)(setq userclick nil)"
)
(action_tile
  "accept"
  "(done_dialog) (setq userclick T)"
)

(setq status (start_dialog))
(unload_dialog dcl_id)
       )
     ) ;_cond
    )
  ) ;_cond
;;;############################# Processing Print Selection #############################;;;
  (if userclick
    (cond

;;;#################################### A0 PDF Print ####################################;;;
      ((= op1 "rb5")
       (setq plsize "ISO expand A0 (841.00 x 1189.00 MM)")
; set paper size
       (setq pltyp "DWG to PDF.pc3") ; set plotter type
       (vl-mkdir path) ; make PDF output directory based on drawing number
       (blockproc dwgname path pltyp plsize)
; call blockproc function and pass variables
       (startapp "explorer" path) ; open file explorer to PDF output directory
      )

;;;#################################### A1 PDF Print ####################################;;;
      ((= op1 "rb6")
       (setq plsize "ISO expand A1 (841.00 x 594.00 MM)")
       (setq pltyp "DWG to PDF.pc3")
       (vl-mkdir path)
       (blockproc dwgname path pltyp plsize)
       (startapp "explorer" path)
      )

;;;#################################### A2 PDF Print ####################################;;;
      ((= op1 "rb7")
       (setq plsize "ISO expand A2 (594.00 x 420.00 MM)")
       (setq pltyp "DWG to PDF.pc3")
       (vl-mkdir path)
       (blockproc dwgname path pltyp plsize)
       (startapp "explorer" path)
      )

;;;#################################### A3 PDF Print ####################################;;;
      ((= op1 "rb8")
       (setq plsize "ISO expand A3 (420.00 x 297.00 MM)")
       (setq pltyp "DWG to PDF.pc3")
       (vl-mkdir path)
       (blockproc dwgname path pltyp plsize)
       (startapp "explorer" path)
      )

;;;#################################### A4 PDF Print ####################################;;;
      ((= op1 "rb9")
       (setq plsize "ISO expand A4 (297.00 x 210.00 MM)")
       (setq pltyp "DWG to PDF.pc3")
       (vl-mkdir path)
       (blockproc dwgname path pltyp plsize)
       (startapp "explorer" path)
      )

;;;#################################### A3 O1D Paper Print ####################################;;;
      ((= op2 "rb10")
       (setq plsize "A3")
       (setq pltyp "\\\\TW3\\Office 1 Downstairs Printer")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A4 O1D Paper Print ####################################;;;
      ((= op2 "rb11")
       (setq plsize "A4")
       (setq pltyp "\\\\TW3\\Office 1 Downstairs Printer")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A3 O1U Paper Print ####################################;;;
      ((= op2 "rb12")
       (setq plsize "A3")
       (setq pltyp "\\\\TW3\\Office 2")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A4 O1U Paper Print ####################################;;;
      ((= op2 "rb13")
       (setq plsize "A4")
       (setq pltyp "\\\\TW3\\Office 2")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A3 i19 Paper Print ####################################;;;
      ((= op3 "rb14")
       (setq plsize "A3")
       (setq pltyp "\\\\TT2\\i19DOWNSTAIRS")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A4 i19 Paper Print ####################################;;;
      ((= op3 "rb15")
       (setq plsize "A4")
       (setq pltyp "\\\\TT2\\i19DOWNSTAIRS")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A3 O3 Paper Print ####################################;;;
      ((= op3 "rb16")
       (setq plsize "A3")
       (setq pltyp "\\\\TW3\\Office 3")
       (blockproc dwgname path pltyp plsize)
      )

;;;#################################### A4 O3 Paper Print ####################################;;;
      ((= op3 "rb17")
       (setq plsize "A4")
       (setq pltyp "\\\\TW3\\Office 3")
       (blockproc dwgname path pltyp plsize)
      )
    ) ;_cond
  ) ;_if
  (princ)
) ;_C:X-PLOT

;;;################################ Block Processing Function ################################;;;
(defun blockproc (dwgname path   pltyp  plsize /     ss
  i hnd scl    lst    at     ax     shtno
  file dest llpt   urpt   mn     mx     tb
  plst shts nlst
)
  (cond
    ((setq
       ss (ssget "_X"
'((0 . "INSERT") (2 . "*A*BORD*") (410 . "MODEL"))
  )
     )
     (repeat (setq i (sslength ss))
       (setq hnd (ssname ss (setq i (1- i)))
     scl (cdr (assoc 41 (entget hnd)))
       )
       (setq at (entnext hnd)
     ax (entget at)
       )
       (while
(/= "SEQEND" (cdr (assoc 0 ax)))
  (if
    (= "SHEETNO" (cdr (assoc 2 ax)))
     (progn (setq shtno (cdr (assoc 1 ax)))
     )
  )
  (setq at (entnext at)
ax (entget at)
  )
       ) ;_while
       (setq dest
      (strcat path "\\" (strcat dwgname "_SHEET_" shtno ".pdf"))
       )
       (vla-getboundingbox (vlax-ename->vla-object hnd) 'mn 'mx)
; get min and max points of block envelope and set lower left/upper right
       (setq llpt (vlax-safearray->list mn)
     urpt (vlax-safearray->list mx)
       )

       (setq lst (cons (list shtno llpt urpt dest) lst))
; construct list for sorting by sheet no
       (princ "\nL")
       (princ lst)
     ) ;_repeat

     (setq shts (list "1" "3"))
     (foreach n shts
       (setq
plst (vl-remove-if-not '(lambda (x) (vl-position n x)) lst)
       )
       (princ "\nP")
       (princ plst)
; (setq nlst (cons plst nlst))
       (setq nlst (list plst nlst))
  ;   ) ;_foreach n
     (princ "\nN")
(princ nlst)
     (foreach tb
      (vl-sort nlst
       '(lambda (a b) (< (atoi (car a)) (atoi (car b))))
      )
;(princ tb)
;     (setq test (cadr tb))
;     (princ test)
       (mainplot pltyp
plsize
(cadr tb)
(caddr tb)
plstyle
(last tb)
scl
       )
     ) ;_foreach tb
) ;_foreach n
    )
    (t
     (setq alrtmsgbrd
    (strcat
      dwgname
      ": No SMD drawing borders found.\nScreenshot this message and contact: john.stewart@smd.co.uk \nCannot continue. Exiting... "
    )
     )
     (alert
       alrtmsgbrd
     )
     (exit)
    )
  ) ;_cond
  (princ)
) ;_blockproc

;;;################### Plot Function ####################;;;

(defun mainplot
(pltyp plsize llpt urpt plstyle dest
scl / lenx leny nurpt furpt
scx
)

  (setq lenx (- (cadr urpt) (cadr llpt)) ; calculate length of X
scx  (/ lenx scl)
  ) ; convert to 1:1 scale
;;;  (princ scl)
;;;  (princ "\n")
;;;  (princ lenx)
;;;  (princ "\n")
;;;  (princ scx)
;;; conditional check of block height to allow a tolerance for scaled blocks, and apply paper size multiplier to set length of Y
  (cond ((and (>= scx 160)
      (<= scx 235)
      (setq leny (fix (* 1.482 lenx)))
)
)
((and (>= scx 250)
      (<= scx 340)
      (setq leny (fix (* 1.467 lenx)))
)
)
((and (>= scx 350)
      (<= scx 485)
      (setq leny (fix (* 1.454 lenx)))
)
)
((and (>= scx 520)
      (<= scx 710)
      (setq leny (fix (* 1.443 lenx)))
)
)
((and (>= scx 720)
      (<= scx 1020)
      (setq leny (fix (* 1.429 lenx)))
)
)
(t
(setq alrtmsgscl
(strcat
  dwgname
  ": Scale out of bounds.\nScreenshot this message and contact: john.stewart@smd.co.uk \nCannot continue. Exiting... "
)
)
(alert
   alrtmsgscl
)
(exit)
)
  ) ;_cond

  (setq nurpt (list leny lenx) ; set local new upper right for block
furpt (mapcar '+ llpt nurpt) ; add lower left to set global final upper right for block
  )

  (if (= pltyp "DWG to PDF.pc3") ; If PDF. Run PDF plot. Else run paper plot
    (command "-plot"    "Y"   "Model" pltyp  plsize "M"
     "L"    "N"    "W"   llpt furpt "F"    "C"    "Y"
     plstyle    "Y"   "A" dest "N"    "Y"
    ) ;_command

;;;## Test Code ##   
;;;    (progn
;;;      (princ "PAPER\n")
;;;      (princ llpt)
;;;      (princ urpt)
;;;    )

    (command "-plot"    "Y"   "Model" pltyp  plsize "M"
     "L"    "N"    "W"   llpt furpt "F"    "C"    "Y"
     plstyle    "Y"   "A" "N" "N"    "Y"
    ) ;_command
  ) ;_if

) ;_mainplot


(defun x-plot_dialog ()

  (setq fname (vl-filename-mktemp "dcl.dcl"))

  (setq fn (open fname "w"))

  (write-line
    (strcat

      "xplot : dialog {
    label = \"Plot a Load of Sheet - V1.0\";
: row {

     : boxed_radio_column {
      label = \"Plot Style :\";
        : radio_button { label = \"Standard\"; key = \"rb1\";}
        : radio_button { label = \"Hydraulic\"; key = \"rb2\";}
        : radio_button { label = \"Colour\"; key = \"rb3\";}
     }
     
: boxed_row {
label = \"Output Format :\";
: radio_column {
   key = \"op1\";
      label = \"Plot to PDF :\";
        : radio_button : tile { label = \"A&0 -  1189 x 841\"; key = \"rb5\"; value = \"1\";}
        : radio_button : tile { label = \"A&1 -   841 x 594\"; key = \"rb6\";}
        : radio_button : tile { label = \"A&2 -   594 x 420\"; key = \"rb7\";}
        : radio_button : tile { label = \"A&3 -   420 x 297\"; key = \"rb8\";}
        : radio_button : tile { label = \"A&4 -   297 x 210\"; key = \"rb9\";}   
     }
     
: boxed_radio_row {
label = \"Plot to Paper :\";
: radio_column {
   key = \"op2\";
        : radio_button : tile { label = \"A3 - Office 1 Dn\"; key = \"rb10\"; value = \"0\";}
        : radio_button : tile { label = \"A4 - Office 1 Dn\"; key = \"rb11\";}
        : radio_button : tile { label = \"A3 - Office 2 Dn\"; key = \"rb12\";}
        : radio_button : tile { label = \"A4 - Office 2 Dn\"; key = \"rb13\";}     
     }
     
: radio_column {
   key = \"op3\";
        : radio_button : tile { label = \"A3 - i19\"; key = \"rb14\"; value = \"0\";}
        : radio_button : tile { label = \"A4 - i19\"; key = \"rb15\";}
        : radio_button : tile { label = \"A3 - Office 3\"; key = \"rb16\";}
        : radio_button : tile { label = \"A4 - Office 3\"; key = \"rb17\";}   
     }
}
}
}
      ok_cancel ; 

               : paragraph {
               : text_part {
                   label = \"Hacked and Cobbled Together in AutoLISP and DCL by John Stewart\";
                 }
                 : text_part {
                   label = \"For Issues and Support Contact: john.stewart@smd.co.uk\";
                 }
               }"
    )
    fn
  )

  (write-line
    (strcat
      "             
             : row  {
             children_fixed_height = true;
             children_alignment = bottom;
             : image {
             height = 2;
             color = 10;
             }
             : image {
             height = 2;
             color = 20;
             }
             : image {
             height = 2;
             color = 30;
             }
             : image {
             height = 2;
             color = 40;
             }
             : image {
             height = 2;
             color = 50;
             }             
             : image {
             height = 2;
             color = 60;
             }
             : image {
             height = 2;
             color = 70;
             }
             : image {
             height = 2;
             color = 80;
             }
             : image {
             height = 2;
             color = 90;
             }
             : image {
             height = 2;
             color = 100;
             }
             : image {
             height = 2;
             color = 110;
             }
             : image {
             height = 2;
             color = 120;
             }
             : image {
             height = 2;
             color = 130;
             }
             : image {
             height = 2;
             color = 140;
             }
             : image {
             height = 2;
             color = 150;
             }
             : image {
             height = 2;
             color = 160;
             }
             : image {
             height = 2;
             color = 170;
             }
             : image {
             height = 2;
             color = 180;
             }
             : image {
             height = 2;
             color = 190;
             }
             : image {
             height = 2;
             color = 200;
             }
             : image {
             height = 2;
             color = 210;
             }
             : image {
             height = 2;
             color = 220;
             }
             : image {
             height = 2;
             color = 230;
             }
             : image {
             height = 2;
             color = 240;
             }
             }
}"
    )
    fn
  )

  (close fn)

) ;defun

(princ)
;;;####################### Old .PC3 file code - not used ######################

;;; (setq pltyp "Office 3.pc3")
;;; (setq pltyp "i19DOWNSTAIRS.pc3")
;;; (setq pltyp "Office 1 Upstairs Printer.pc3")
;;; (setq pltyp "Office 1 Downstairs Printer Colour.pc3")

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #2 on: January 10, 2019, 12:28:42 PM »
If I understand what you're asking, give this a try:
Code - Auto/Visual Lisp: [Select]
  1. ;;;################################ Block Processing Function ################################;;;
  2. (defun blockproc (dwgname       path   pltyp  plsize /      ss     i      hnd    scl    lst
  3.                   at     ax     shtno  file   dest   llpt   urpt   mn     mx     tb     plst
  4.                   shts   nlst
  5.                  )
  6.   (cond ((setq ss (ssget "_X" '((0 . "INSERT") (2 . "*A*BORD*") (410 . "MODEL"))))
  7.          (repeat (setq i (sslength ss))
  8.            (setq hnd (ssname ss (setq i (1- i)))
  9.                  scl (cdr (assoc 41 (entget hnd)))
  10.            )
  11.            (setq at (entnext hnd)
  12.                  ax (entget at)
  13.            )
  14.            (while (/= "SEQEND" (cdr (assoc 0 ax)))
  15.              (if (= "SHEETNO" (cdr (assoc 2 ax)))
  16.                (progn (setq shtno (cdr (assoc 1 ax))))
  17.              )
  18.              (setq at (entnext at)
  19.                    ax (entget at)
  20.              )
  21.            ) ;_while
  22.            (setq dest (strcat path "\\" (strcat dwgname "_SHEET_" shtno ".pdf")))
  23.            (vla-getboundingbox (vlax-ename->vla-object hnd) 'mn 'mx)
  24.                                         ; get min and max points of block envelope and set lower left/upper right
  25.            (setq llpt (vlax-safearray->list mn)
  26.                  urpt (vlax-safearray->list mx)
  27.            )
  28.            (setq lst (cons (list shtno llpt urpt dest) lst))
  29.                                         ; construct list for sorting by sheet no
  30.            (princ "\nL")
  31.            (princ lst)
  32.          ) ;_repeat
  33.          (setq shts '("1" "3"))         ; test values for selecting which pages to print
  34.          (setq plst (vl-remove-if-not '(lambda (x) (vl-position (car x) shts)) lst)
  35.                                         ; remove elements from [b]lst[/b] which do not match [b]shts[/b] list
  36.          )
  37.          (foreach tb (vl-sort plst      ;
  38.                               '(lambda (a b) (< (atoi (car a)) (atoi (car b))))
  39.                                         ; sort is redundant but won't work without it
  40.                      )                  ;(princ tb)
  41.                                         ;     (setq test (cadr tb))
  42.                                         ;     (princ test)
  43.            (mainplot pltyp plsize (cadr tb) (caddr tb) plstyle (last tb) scl)
  44.          ) ;_foreach tb
  45. ;;;      (foreach n shts
  46. ;;;        (setq plst (vl-remove-if-not '(lambda (x) (vl-position n x)) lst)
  47. ;;;                                     ; remove elements from [b]lst[/b] which do not match [b]shts[/b] list
  48. ;;;        )
  49. ;;;        (princ "\nP")
  50. ;;;        (princ plst)
  51. ;;;        (setq nlst (cons plst nlst)) ; construct [b]nlst[/b] from output of vl-remove-if-not
  52. ;;;                                     ;     ) ;_foreach n ; commented out to nest[b] tb[/b]
  53. ;;;        (princ "\nN")
  54. ;;;        (princ nlst)
  55. ;;;        (foreach tb (vl-sort plst    ;
  56. ;;;                             '(lambda (a b) (< (atoi (car a)) (atoi (car b))))
  57. ;;;                                     ; sort is redundant but won't work without it
  58. ;;;                    )                ;(princ tb)
  59. ;;;                                     ;     (setq test (cadr tb))
  60. ;;;                                     ;     (princ test)
  61. ;;;          (mainplot pltyp plsize (cadr tb) (caddr tb) plstyle (last tb) scl)
  62. ;;;        ) ;_foreach tb
  63. ;;;      ) ;_foreach n NEST
  64.         )
  65.         (t
  66.          (setq alrtmsgbrd
  67.                 (strcat
  68.                   dwgname
  69.                   ": No drawing borders found.\nScreenshot this message and contact: john \nCannot continue. Exiting... "
  70.                 )
  71.          )
  72.          (alert alrtmsgbrd)
  73.          (exit)
  74.         )
  75.   ) ;_cond
  76.   (princ)
  77. ) ;_blockproc

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #3 on: January 10, 2019, 03:51:26 PM »
If I understand what you're asking, give this a try:
Code - Auto/Visual Lisp: [Select]
  1. ;;;################################ Block Processing Function ################################;;;
  2. (defun blockproc (dwgname       path   pltyp  plsize /      ss     i      hnd    scl    lst
  3.                   at     ax     shtno  file   dest   llpt   urpt   mn     mx     tb     plst
  4.                   shts   nlst
  5.                  )
  6.   (cond ((setq ss (ssget "_X" '((0 . "INSERT") (2 . "*A*BORD*") (410 . "MODEL"))))
  7.          (repeat (setq i (sslength ss))
  8.            (setq hnd (ssname ss (setq i (1- i)))
  9.                  scl (cdr (assoc 41 (entget hnd)))
  10.            )
  11.            (setq at (entnext hnd)
  12.                  ax (entget at)
  13.            )
  14.            (while (/= "SEQEND" (cdr (assoc 0 ax)))
  15.              (if (= "SHEETNO" (cdr (assoc 2 ax)))
  16.                (progn (setq shtno (cdr (assoc 1 ax))))
  17.              )
  18.              (setq at (entnext at)
  19.                    ax (entget at)
  20.              )
  21.            ) ;_while
  22.            (setq dest (strcat path "\\" (strcat dwgname "_SHEET_" shtno ".pdf")))
  23.            (vla-getboundingbox (vlax-ename->vla-object hnd) 'mn 'mx)
  24.                                         ; get min and max points of block envelope and set lower left/upper right
  25.            (setq llpt (vlax-safearray->list mn)
  26.                  urpt (vlax-safearray->list mx)
  27.            )
  28.            (setq lst (cons (list shtno llpt urpt dest) lst))
  29.                                         ; construct list for sorting by sheet no
  30.            (princ "\nL")
  31.            (princ lst)
  32.          ) ;_repeat
  33.          (setq shts '("1" "3"))         ; test values for selecting which pages to print
  34.          (setq plst (vl-remove-if-not '(lambda (x) (vl-position (car x) shts)) lst)
  35.                                         ; remove elements from [b]lst[/b] which do not match [b]shts[/b] list
  36.          )
  37.          (foreach tb (vl-sort plst      ;
  38.                               '(lambda (a b) (< (atoi (car a)) (atoi (car b))))
  39.                                         ; sort is redundant but won't work without it
  40.                      )                  ;(princ tb)
  41.                                         ;     (setq test (cadr tb))
  42.                                         ;     (princ test)
  43.            (mainplot pltyp plsize (cadr tb) (caddr tb) plstyle (last tb) scl)
  44.          ) ;_foreach tb
  45. ;;;      (foreach n shts
  46. ;;;        (setq plst (vl-remove-if-not '(lambda (x) (vl-position n x)) lst)
  47. ;;;                                     ; remove elements from [b]lst[/b] which do not match [b]shts[/b] list
  48. ;;;        )
  49. ;;;        (princ "\nP")
  50. ;;;        (princ plst)
  51. ;;;        (setq nlst (cons plst nlst)) ; construct [b]nlst[/b] from output of vl-remove-if-not
  52. ;;;                                     ;     ) ;_foreach n ; commented out to nest[b] tb[/b]
  53. ;;;        (princ "\nN")
  54. ;;;        (princ nlst)
  55. ;;;        (foreach tb (vl-sort plst    ;
  56. ;;;                             '(lambda (a b) (< (atoi (car a)) (atoi (car b))))
  57. ;;;                                     ; sort is redundant but won't work without it
  58. ;;;                    )                ;(princ tb)
  59. ;;;                                     ;     (setq test (cadr tb))
  60. ;;;                                     ;     (princ test)
  61. ;;;          (mainplot pltyp plsize (cadr tb) (caddr tb) plstyle (last tb) scl)
  62. ;;;        ) ;_foreach tb
  63. ;;;      ) ;_foreach n NEST
  64.         )
  65.         (t
  66.          (setq alrtmsgbrd
  67.                 (strcat
  68.                   dwgname
  69.                   ": No drawing borders found.\nScreenshot this message and contact: john \nCannot continue. Exiting... "
  70.                 )
  71.          )
  72.          (alert alrtmsgbrd)
  73.          (exit)
  74.         )
  75.   ) ;_cond
  76.   (princ)
  77. ) ;_blockproc

Hi Ron - and thanks again!

It looks like you've understood, having had a quick look at your code on my phone.   I haven't had chance to test it yet. Late evening here, and doing battle with a very tired toddler fighting sleep at bedtime! I'll try and have a go later, or will test  it in the morning when I'm back at work.

And then try and figure out where I was going wrong! My debugging skills (amongst other things) need a bit of improvement!

Cheers,

John

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #4 on: January 12, 2019, 06:10:28 AM »
I'm happy to report that, unsurprisingly, your code works! So thanks again.

Now embarking on building up some code to act like the MS Word print page range options  :nerdystraight:

Thanks to Lee Mac I've got it parsing for the comma delimiter, and I've got an idea on how to parse for the hyphen delimiter to build page ranges.

Slowly getting my head around the complexities of lambda, mapcar etc. I'll no doubt be posting more questions/problems very soon!!

Cheers!

BIGAL

  • Swamp Rat
  • Posts: 1396
  • 40 + years of using Autocad
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #5 on: January 12, 2019, 06:55:19 PM »
This is a plot layout range for pdf's includes a merge pdfs, plots to a subdirectory under dwg location.

A man who never made a mistake never made anything

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #6 on: January 14, 2019, 09:06:10 AM »
I'm happy to report that, unsurprisingly, your code works! So thanks again.

Now embarking on building up some code to act like the MS Word print page range options  :nerdystraight:

Thanks to Lee Mac I've got it parsing for the comma delimiter, and I've got an idea on how to parse for the hyphen delimiter to build page ranges.

Slowly getting my head around the complexities of lambda, mapcar etc. I'll no doubt be posting more questions/problems very soon!!

Cheers!
Glad you're getting things sorted! :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #7 on: January 14, 2019, 09:29:40 AM »
This is a plot layout range for pdf's includes a merge pdfs, plots to a subdirectory under dwg location.

Thanks for sharing  :-) The mergepdfs would be very useful. I'll look into the viability of using Ghostscript.

The way our drawings are done is a little backward - all drawings sheets are on one modelspace page, and are defined by a block which is the drawing border titleblock.

I've got my code to pick out each drawing border from its insertion point, and then plot a window view based on the paper size of the border titleblock. I've currently got the PDF plotting to dump into a separate directory (C:\PDF) as it's easier for housekeeping - navigating the Vault $workingfolder to clean up PDFs would be a pain.

I can get it to print selected pages based on comma separated string input into a DCL edit box - thanks to Lee Mac's String to List  :-)

Ideally I'dlike to have the plot range input to be similar to MS Office etc, i.e. Comma seprated for indvidual sheets, and hyphen separated for a range. All in the same string from the edit box. Although my head just isn't in it at the moment  :grumpy: Settling for different edit boxes might be more realistic for the time being.

I've found some Python code that does exactly what I need in a few lines - and I've got a rough idea of how it should be done in LISP, just need to get my confidence up to tackle it  :idiot2:

Cheers,

John

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #8 on: January 14, 2019, 10:11:50 AM »
Use wcmatch for your rangees / individual sheets. This will print pages 1 to 9 and 12. :)
Code: [Select]
(wcmatch "5" "[1-9],12")
Quote
The way our drawings are done is a little backward - all drawings sheets are on one modelspace page, and are defined by a block which is the drawing border titleblock.
It's too bad your company operates like this, if anything that has progressed with AutoCAD ease of printing is definitely one of them ( Sheet Set Manager, Publish ).
« Last Edit: January 14, 2019, 10:19:04 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #9 on: January 14, 2019, 04:04:53 PM »
Use wcmatch for your rangees / individual sheets. This will print pages 1 to 9 and 12. :)
Code: [Select]
(wcmatch "5" "[1-9],12")
Quote
The way our drawings are done is a little backward - all drawings sheets are on one modelspace page, and are defined by a block which is the drawing border titleblock.
It's too bad your company operates like this, if anything that has progressed with AutoCAD ease of printing is definitely one of them ( Sheet Set Manager, Publish ).

Thanks again for the help  :-) I'll try and look into it again in the morning - hopefully I'll be in a better frame of mind! Just couldn't get a start today and only got more frustrated with myself the more I stared at the screen!

The sheet layout etc isn't ideal, I've been there 9 years and made various attempts to change the way we do it. We had a failed (and expensive) experimentation with AutoCAD Electrical a few years ago which has reinforced the resistance to change.

I enjoy learning and tinkering about with Lisp while we're a bit quiet - at least I do when I'm not getting frustrated with myself!

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #10 on: January 15, 2019, 10:47:17 AM »
Use wcmatch for your rangees / individual sheets. This will print pages 1 to 9 and 12. :)
Code: [Select]
(wcmatch "5" "[1-9],12")


I've started paying around with wcmatch - thanks you very much for the pointer Ron  :-)

I've come across a slight issue with the way the [ - ] range operator handles double figures  :?

It only works single figures - so [1-15] would only pull out 1 & 5. Not 1 thru 15.

Quote from: AutoDesk
All characters enclosed in brackets ([ . . . ]) are read literally, so there is no need to escape them, with the following exceptions: the tilde character (~) is read literally only when it is not the first bracketed character (as in "[A~BC]"); otherwise, it is read as the negation character, meaning that wcmatch should match all characters except those following the tilde (as in "[~ABC]"). The dash character (-) is read literally only when it is the first or last bracketed character (as in "[-ABC]" or "[ABC-]") or when it follows a leading tilde (as in "[~-ABC]"). Otherwise, the dash character (-) is used within brackets to specify a range of values for a specific character. The range works only for single characters, so "STR[1-38]" matches STR1, STR2, STR3, and STR8, and "[A-Z]" matches any single uppercase letter.

I've managed to hack this function together which takes pages from a DCL edit box, and runs through a while loop based on sht_tot which is the total number of drawing borders inserted.

Code - Auto/Visual Lisp: [Select]
  1. ;;;################### PageParse Function ####################;;;
  2. (defun pageparse (pages / z)
  3.  
  4.   (setq z 1)
  5.  
  6.   (while (< z (+ sht_tot 1))
  7.     (if (wcmatch (itoa z) pages)
  8.  
  9.  
  10.       (setq pglst (reverse (cons (itoa z) pglst)))
  11.     )
  12.  
  13.     (setq z (+ z 1))
  14.   ) ;_while
  15.  
  16.  
  17. ) ;_defun pageparse

It works for comma separated values of any amount, but gets a bit screwy with the bracketed ranges that extend to double figures.

It's probably a bit scrappy, and there will be neater/more efficient ways to do it, but at least I've got the basic functionality working - much better than yesterdays attempts!
« Last Edit: January 15, 2019, 11:33:13 AM by 0john0 »

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #11 on: January 15, 2019, 11:23:24 AM »
You are correct it does get a bit wonky with pages that have 2 digits. If you're parsing one by one, vl-remove-if-not would work nicely for this:
Code - Auto/Visual Lisp: [Select]
  1. (setq i 0)
  2. (setq pages nil)
  3. (setq keep '(1 4 8 9 12 15))
  4. (repeat 50 (setq pages (cons (setq i (1+ i)) pages)))
  5. (vl-remove-if-not '(lambda (x) (member x keep)) (reverse pages))
  6.  
« Last Edit: January 15, 2019, 11:30:33 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #12 on: January 15, 2019, 11:54:03 AM »
You are correct it does get a bit wonky with pages that have 2 digits. If you're parsing one by one, vl-remove-if-not would work nicely for this:
Code - Auto/Visual Lisp: [Select]
  1. (setq i 0)
  2. (setq pages nil)
  3. (setq keep '(1 4 8 9 12 15))
  4. (repeat 50 (setq pages (cons (setq i (1+ i)) pages)))
  5. (vl-remove-if-not '(lambda (x) (member x keep)) (reverse pages))
  6.  

Thanks Ron. I think the one-by-one parsing is working ok just using the comma delimiter and wcmatch  :-) It's when I try to enter a page range that extends into double figures that I run into problems:

Entering 1,3,4,[12-25] into the DCL edit box as the page range (similar to how you would for MS Word etc) only results in pages 1, 2, 3, 4, 5 being printed, and not 1, 3, 4, 12 thru 25.   :tickedoff:

Is it possible to get wcmatch to process double digits in the way I'm wanting to? I'm struggling to think of a way that the DCL edit box input could be processed to work with wcmatch

EDIT:

Attached my Lisp file, and a test .DWG to show the border layout etc :-)

EDIT (the return):

Thanks for the code snippet - might try and tidy the function up with a repeat rather than a while
« Last Edit: January 15, 2019, 12:07:11 PM by 0john0 »

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #13 on: January 16, 2019, 04:38:20 PM »
You could try something like this to get the pages in a defined range:
Code - Auto/Visual Lisp: [Select]
  1. (defun _range (str / a b c d i r x)
  2.   (cond ((and (setq i (vl-string-search "[" str))
  3.               (setq a (fix (atof (setq d (substr str (+ 2 i))))))
  4.               (setq i (vl-string-search "-" d))
  5.               (setq b (fix (atof (substr d (+ 2 i)))))
  6.          )
  7.          (setq c (apply 'min (list a b)))
  8.          (repeat (1+ (abs (- a b))) (setq r (cons c r)) (setq c (1+ c)))
  9.          (reverse r)
  10.         )
  11.   )
  12. )
  13. (_range "1,3,4,[12-25]")
  14. ;; Returns
  15. (12 13 14 15 16 17 18 19 20 21 22 23 24 25)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

0john0

  • Guest
Re: Help with sorting lists and using "cons" to add multiple lists.
« Reply #14 on: January 18, 2019, 12:41:11 PM »
Excellent - thanks Ron! That works like a charm!

I could figure out what the function needed to do - I just had no idea where to start with writing it!

I've spent a bit of time figuring out how yours works so I'll have a better understanding for integrating it so I can process comma separated values in the same string (hopefully!).

Thanks again for the patience and assistance  :-)