Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Posts: 4
Registered: ‎05-09-2013
Message 1 of 2 (3,374 Views)

AE12 Component User Post Lisp Modification

3374 Views, 1 Replies
05-14-2013 01:59 PM

What I'm looking to do has essentially already been written in the wirefrm2.lsp user post routine by filtering INST attributes which only displays the desired outputs on the report.


What I would like to do is use the same concept of this sorting routine on sort FAMILY attributes in the COMPONENT schematic report. Below are screen shots to walk through the steps of how far I've gotten. I will also post my code along with the issues I've confronted.



Step 1: This is what I'm trying to accomplish with the component report.



Step 2: Sorting on these attributes, click user post.



Step 3: Modified the comp.dcl file to add menu selection 



Step 4:  The routine finds the family codes in the report displayed on this selection window. 



Step 5: Once it returns to the report it appears as though the attributes aren't released from the array?  Stuck here!



Here is the code I have been working on.  I think the issue is somewhere in the very last loop.  Does anyone have any imput on this sort of modification to a lisp routine?  Thank you and I appreciate any input!


; ---------  C O M P . L S P  -----------------------------
; Post-process schematic component report. 
; This routine is called from AutoCAD Electrical's "User post" button on the
; schem component report dialog display. Report data is passed to this
; routine in AutoLISP variable called "wd_rdata". This utility can
; then operate on this report data, reformat it into a new list of
; report data "rtrn" and then pass it back to AutoCAD Electrical's report dialog 
; through a call to (c:wd_rtrn_2wd rtrn) shown at the end of this file.

; Each item in the first list (the "(car wd_rdata)" part of the data) is itself a 
  ; sublist with the following elements:
  ; nth 0=ITEM
  ; nth 1=TAGNAME
  ; nth 2=CNT
  ; nth 3=UNITS 
  ; nth 4=SUBQTY (*n)
  ; nth 5=MFG
  ; nth 6=CAT
  ; nth 7=DESC1
  ; nth 8=DESC2
  ; nth 9=DESC3
  ; nth 10=REF
  ; nth 11=INST
  ; nth 12=LOC
  ; nth 13=RATING1
  ; nth 14=RATING2
  ; nth 15=RATING3
  ; nth 16=RATING4
  ; nth 17=RATING5
  ; nth 18=RATING6
  ; nth 19=RATING7
  ; nth 20=RATING8
  ; nth 21=RATING9
  ; nth 22=RATING10
  ; nth 23=RATING11
  ; nth 24=RATING12
  ; nth 25=catalog DESC
  ; nth 26=catalog QUERY2 field
  ; nth 27=catalog QUERY3 field
  ; nth 28=catalog MISC1 field
  ; nth 29=catalog MISC2 field
  ; nth 30=catalog USER1 field
  ; nth 31=catalog USER2 field
  ; nth 32=catalog USER3 field
  ; nth 33=1=Parent, 2=child
  ; nth 34=WDBLKNAM
  ; nth 35=BLKNAM
  ; nth 36=HDL
  ; nth 37=CATEGORY
  ; nth 38=ASSYCODE
  ; nth 39=SHEET (%S)
  ; nth 40=SHDWGNAM (%D)
  ; nth 41=SEC
  ; nth 42=SUBSEC
  ; nth 43=FAMILY
  ; nth 44=WDTAGALT
  ; nth 45=WDTYPE
  ; nth 46=

; -- main program execution begins here --
(defun _wd_post_main ( / rtrn dclnam dcl_id user_1 user_2 user_3 cancel xx wlay1
                         lay_map_lst data wd_make_dcl wd_nth_subst rtrn_part2
                         desc newval newdatalst newlst n ix slen str val
                         str2 x word wordlst param_lst fam fam_lst fam1 picked
			 picked_fam_lst lst op_lst)
  ; -- internal subroutines

  (defun wd_nth_subst ( n val lst / newlst ix slen x )
    ; Substitute the nth member of a list "lst" with new value "val"
    ; If "n" is past end of existing list then blank positions "nil" padded
    (if (not lst)
      (setq slen 0)
      (setq slen (length lst))
      ((minusp n)  ) ; rtrn orig list if pos is neg number
      ((zerop n) (setq lst (cons val (cdr lst)))) ; n=0, replace 1st item
      ((= n slen) (setq lst (append lst (list val)))) ; new last item
      ((< n slen) ; Insert item somewhere else in list
        (setq ix 0)
        (setq newlst '())
        (foreach x lst
          (if (/= ix n)
            (setq newlst (cons x newlst)) ; reuse existing
            (setq newlst (cons val newlst)) ; substitute new
          (setq ix (1+ ix))
        (setq lst (reverse newlst))
        (setq newlst nil)
      ((> n slen) ; lengthen list, add "nil" pads as req'd
        (setq lst (reverse lst))
        (while (< slen n)
          (setq lst (cons nil lst))  ; add pads
          (setq slen (1+ slen))
        (setq lst (reverse (cons val lst))) ; tack new item on end
    ) )
   lst ; <-- this is needed 
  ; --
  (defun flip_upper_and_lower_case ( str / wordlst str2 word)
    ; Process character string "str" and flip to upper/lower case. First char
    ; of each word to upper case, rest lower case.
    (setq str2 "")
    ; break passed "str" character string into a list of words
    (setq wordlst (c:wd_delim_str_to_lst str " ")) 
    (foreach word wordlst
      ; process each word
      (if (/= str2 "")(setq str2 (strcat str2 " ")))
      ; Flip first or only character in next word to upper case
      (setq str2 (strcat str2 (strcase (substr word 1 1))))
      ; Flip 2nd+ characters of this word to lower case
      (if (> (strlen word) 1) ; word more than a single character
        (setq str2 (strcat str2 (strcase (substr word 2) T))) ; flip to lower case
    str2 ; return the revised character string
  ; -- main routine --

  (setq rtrn nil)
  ; AutoCAD Electrical passes the report displayed data as a list of lists of lists in variable
  ; called wd_rdata. The first element of this list is the list of lists of
  ; report data. The 2nd element is used to track which lines are main and which
  ; are "subassembly" lines related to the main entry above. See detailed description below.
  (if (AND wd_rdata (car wd_rdata) (listp (car wd_rdata)))

    (progn ; Data comes across as two parallel lists. The first                  
           ; list (car wd_data) carries a sublist of data for each line of the 
           ; report. The parallel list (cadr wd_data) carries a flag for each
           ; line in the first list. A '1' means that the line in the first list
           ; represents the first or only line of data for a given component.
           ; A '2" means that this line of data is a "subassy" line of data and
           ; goes with the previous '1" entry. For example, a component that has
           ; one main line and three subassy lines of data would have parallel
           ; flags in the 2nd list of ...1 2 2 2.... If you insert extra lines
           ; into the first list or remove lines from the first list, you need
           ; to add or remove corresponding entries from the 2nd list to keep
           ; the two lists synchronized. 
      (setq rtrn (car wd_rdata)) ; this is the 1st list, the data sublist list
      (setq rtrn_part2 (cadr wd_rdata)) ; this is the "flag" list of 1's and 2's
  ; Look for dcl file of same name, open if found.
  (setq cancel nil)
  ; see if running as pre-process or auto report. won't work for those below that require selection from dialog
  (if GBL_wd_postprocess
      (if (listp GBL_wd_postprocess)
          (if (> (length GBL_wd_postprocess) 1)
            (setq param_lst (cadr GBL_wd_postprocess)) ; optional 
            (setq param_lst nil)
          (setq GBL_wd_postprocess (car GBL_wd_postprocess)) ; should be which one to run  
      ) )    
      (if (= (type GBL_wd_postprocess) 'INT) (setq GBL_wd_postprocess (itoa GBL_wd_postprocess)))
        ((= GBL_wd_postprocess "1") (setq user_1 "1")) 
        ((= GBL_wd_postprocess "2") (setq user_2 "1")) 
        ((= GBL_wd_postprocess "3") (setq user_3 "1"))
        (T (setq cancel 1)) ; not a valid value
  ) )      
  ; Look for dcl file of same name, open if found.
  (if (AND (not GBL_wd_postprocess) ; otherwise bypass dialog
      (setq dclnam (c:ace_find_file "comp.dcl" 16))) ; 16=display error dialog if file not found
      (setq dcl_id (load_dialog dclnam))                
      (if (new_dialog "main_select" dcl_id)
          (setq user_1 "0") ; default to 1st user entry toggled on
	  (setq user_2 "0")
          (setq user_3 "0")      
          (set_tile "user1" user_1) ; preset toggle ON
	  (set_tile "user2" user_2)
	  (set_tile "user3" user_3)
          (action_tile "user1" "(setq user_1 $value)")
          (action_tile "user2" "(setq user_2 $value)")
          (action_tile "user3" "(setq user_3 $value)")
          (action_tile "cancel" "(setq cancel 1)")
          (unload_dialog dcl_id)
  ) ) ) )

  (if (AND rtrn (not cancel)) 
    (progn ; user didn't cancel out of dialog, okay to continue  
      (if (= user_1 "1")
        (progn ; Example function - flip DESC1-3 text to upper/lower case strings
          (setq newdatalst nil) ; <-- last change made     
	  (foreach lst rtrn 
            ; process each "lst" report row consisting of a list of 50+ data fields
	    (setq desc (nth 7 lst)) ; get DESC1 value for this row
               (if (AND desc (/= desc ""))
                    (setq newval (flip_upper_and_lower_case desc))
                     ; substitute new DESC1 value into "lst" row data                    
		     (setq lst (wd_nth_subst 7 newval lst))
	    (setq desc (nth 8 lst)) ; get DESC2 value for this row
               (if (AND desc (/= desc ""))
                     (setq newval (flip_upper_and_lower_case desc))                    
                     ; substitute new DESC2 value into "lst" row data                    
                     (setq lst (wd_nth_subst 8 newval lst))
	    (setq desc (nth 9 lst)) ; get DESC3 value for this row
               (if (AND desc (/= desc ""))
                     (setq newval (flip_upper_and_lower_case desc))                    
                     ; substitute new DESC3 value into "lst" row data                   
		     (setq lst (wd_nth_subst 9 newval lst))
	    (setq newdatalst (cons lst newdatalst)) ; build up new list of report data
	  (setq rtrn (reverse newdatalst)) ; put back in original order

      (if (= user_2 "1")
          ; Go through data and create a list of FAMILY values
          (setq fam_lst nil)
          (foreach lst rtrn
            (setq fam1 (nth 43 lst))
            (if (= fam1 "")(setq fam1 "(??)"))
            (if (not (member fam1 fam_lst))
              ; This fam1 not in list, add it now
              (setq fam_lst (cons fam1 fam_lst)))
          (if (AND fam_lst (> (length fam_lst) 1) (OR dclnam (setq dclnam (c:ace_find_file "comp.dcl" 16))))
            (progn ; two or more family values, display in a multi-select pick list dialog
              (setq dcl_id (load_dialog dclnam))                
              (if (not (new_dialog "fam_select" dcl_id))
                ; Could not find definition for this family list dialog
                (alert (strcat (c:wd_msg "GEN075" (list "fam_select") "%1 not found") "\n(" dclnam ")"))
              ; ELSE
                (progn ; display family list in pick-list dialog
                  (setq cancel nil)
                  ; Sort the list alphabetically
                  (setq fam_lst (acad_strlsort fam_lst))
                  ; Now display in pick list dialog
                  (start_list "famlst")
                  (mapcar 'add_list fam_lst)
                  ; Define action for pick list dialog
                  (action_tile "famlst" "(setq picked $value)")
                  ; Define action for "Cancel" button
                  (action_tile "cancel" "(setq cancel 1)")
                  (unload_dialog dcl_id)
                  ; Return from dialog as it is dismissed
                  (if (AND (not cancel) picked)
                    (progn ; user picked one or more family codes. Index numbers returned
                           ; in string "picked", space delimited. Break this down and
                           ; assemble a list of the picked family values.
                      (setq lst (c:wd_delim_str_to_lst picked " "))
                      (setq picked_fam_lst nil)
                      (foreach lst lst
                        (setq fam (nth (atoi lst) fam_lst)) ; retrieve actual family text value
                        (if (= fam "(??)") (setq fam "")) ; flip the blank flag to actual blank
                        (setq picked_fam_lst (cons fam picked_fam_lst))
                      ; Now have list of valid family values in "picked_fam_lst". Go 
                      ; through the family data and filter out all entries that do NOT
                      ; have a fam1 that shows up in the picked fam list.
                      (setq rtrn nil) ;----
                      (foreach lst rtrn
                      (if (OR (member (nth 43 lst) picked_fam_lst)
			      (member (nth 43 lst) picked_fam_lst))
                                (progn ; OK, this from/to entry includes one of the target INST values
                                  (setq rtrn (cons lst rtrn)) ; save it in the output list
                      ) ) )
                      (setq rtrn (reverse rtrn)) ; put back into original order
                      (setq rtrn rtrn) ; fresh copy for possible further processing
                ) ) )                 
          ) ) ) 
      ) ) 

    ) ; <-- Keep
 ) ; <-- Keep 

        (c:wd_rtrn_2wd (list rtrn rtrn_part2)) ; paste two lists back together and return                                  
        ; back to AutoCAD Electrical's report dialog

; -- the following AUTO-STARTS when this file is "loaded" from within AutoCAD Electrical (i.e.
;    user hits the "User post" button on a report display dialog)
(_wd_post_main) ; run the above program


Posts: 4
Registered: ‎05-09-2013
Message 2 of 2 (3,337 Views)

Re: AE12 Component User Post Lisp Modification

05-20-2013 11:40 AM in reply to: tomkro

Does anyone out there even modify the User Post formatting lisp routine?  Maybe someone can tell me if this is even possible...?

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community