Assign latest attribute value from a list!

Assign latest attribute value from a list!

leonardo.alvarez4SZJL
Advocate Advocate
532 Views
9 Replies
Message 1 of 10

Assign latest attribute value from a list!

leonardo.alvarez4SZJL
Advocate
Advocate

Hi, I am using AutoCAD Electrical, Windows 10

 

I am still learning LISP and I want to be able to accomplish this task, but I am still struggling to write this routine.

How can I grab values from multiple attributes in order and assign the latest attribute value to another attribute. For example.

 

Attributes to grab:             |               Attribute to store value to:

RevA = A                              |               Real_Rev = B

RevB = B                              |

RevC =                                  | 

RevD =                                 |      

..

I want the lisp routine to check each (Rev) attribute in list order and extract the latest attribute that returns a non-nil value and assigns it to Real_rev attribute. And how can I use it in multiple drawings by selecting a folder.

 

Best Regards,

Leo

 

 

0 Likes
533 Views
9 Replies
Replies (9)
Message 2 of 10

paullimapa
Mentor
Mentor

If you are new to LISP progamming, this is actually a very complicated routine to start off with.

Take a look at this routine I call Getval to see if you can use it to learn from it. I try and place as much comments as possible to explain the lines of code are doing.

Save to location and then use APPLOAD command to select and load then enter Getval at command line.

Select your first Block with Attribute then hit Enter to complete selection.

Next select your second Block with Attribute that you want to place the result and hit Enter to complete that selection. Now see if that's the result you want to get.

There are many ways to improve the routine more like changing it so you only select the Block with the matching Name. I including this in the code but commented out. Also you can change the code so that you don't have to hit an Enter after selecting the object. Lastly, you can learn how to use Visual Lisp functions to do similar steps.

; getval.lsp 
(defun c:getval (/ ss1 ss2 en ed sen sed val1 val)
 (princ"\nSelect 1st Block with Attribute Values: ")
 (setq ss1 (ssget ":L" '((0 . "INSERT")(66 . 1))))     ; select block with attribute on unlock layer
; (setq ss1 (ssget ":L" '((0 . "INSERT")(2 . "RMNUM")(66 . 1))))   ; select block with name set as "RMNUM" & attribute on unlock layer
 (if ss1
  (progn
   (princ"\nSelect 2nd Block to Place Attribute Value: ")
   (setq ss2 (ssget ":L" '((0 . "INSERT")(66 . 1))))  ; select block with attribute to place
; (setq ss2 (ssget ":L" '((0 . "INSERT")(2 . "RMNUM")(66 . 1))))   ; select block with name set as "RMNUM" & attribute on unlock layer
    (if ss2
      (progn
       (setq val "" val1 "")                ; set initial value
       (setq en (ssname ss1 0))     ; get obj
       (setq ed (entget en))        ; get obj data
       (setq sen (entnext en))       ; get subentity's name
        (while sen                    ; while there are subentities
          (setq sed (entget sen))     ; get subentity's data
          (if (/= (cdr(assoc 0 sed)) "SEQEND") ; look for Attribute subentity
	         (progn
            (setq val (cdr(assoc 1 sed))) ; get attribute value 
            (if (= val "")
              (progn
               (setq sen nil) ; if value is empty then end while loop
               (setq val val1) ; use previous val
              )
              (progn
               (setq sen (entnext sen)) ; else continue to next
               (setq val1 val) ; store non empty value
              )
            )
           ) ; progn get val
           (setq sen nil)     ; stop while loop
          ) ; if
        ) ; while
        (setq sen (entnext (ssname ss2 0)))   ; get placement subentity's name
        (setq sed (entget sen))     ; get subentity's data
        (setq sed (subst (cons 1 val) (assoc 1 sed) sed)) ; substitute new value
        (entmod sed)       ; modify its' data
        (entupd sen)       ; update obj
      ) ; progn
      (progn
       (princ"\nNo Object Selected.")
      )
    ) ; if
  ) ; progn
  (progn
    (princ"\nNo Object Selected.")
  )
 ) ; if
 (princ)
) ; defun
(princ"\nGetVal command loaded")(princ)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 3 of 10

leonardo.alvarez4SZJL
Advocate
Advocate

Hi @paullimapa 

Thank you very much. This is very helpful. Can I ask what is the difference between Lisp and Visual Lisp?

0 Likes
Message 4 of 10

paullimapa
Mentor
Mentor

AutoCAD incorporated initially programmin functions called AutoLISP. Then later additional functions were added to enhance called Visual Lisp. Here's a great learning website where you can learn AutoLISP as well as Visual Lisp

https://www.afralisp.net/visual-lisp/


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 5 of 10

leonardo.alvarez4SZJL
Advocate
Advocate

@paullimapa 

You are awesome man thank you very much!

0 Likes
Message 6 of 10

paullimapa
Mentor
Mentor

you are welcome...glad I could help...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 7 of 10

Sea-Haven
Mentor
Mentor

In VL you use get-attributes 1 line and it does just that in creation order. 

1 example

 

(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 0 )) 'getattributes)

 

You can compare tagstring etc and update another block. Or just use nth to change a attribute.

 

Re multi dwgs look into a script that runs over multiple dwgs or OBDX. 

Message 8 of 10

pbejse
Mentor
Mentor

@leonardo.alvarez4SZJL wrote:

I want the lisp routine to check each (Rev) attribute in list order and extract the latest attribute that returns a non-nil value and assigns it to Real_rev attribute. ..


Here's one way

If the tag names are known:
Starting from the last Revtag, Check the value if empty string, If not use the value string from that Tagname

	(setq TagNames '("RevD" "RevC" "RevB" "RevA"))
	(while (setq tag (Car TagNames))	  
	  	(if (/= (setq value (GetPropertyValue en tag)) "")
	    		(setq TagNames nil data (list tag value))
		  	(setq  TagNames (Cdr TagNames))
	    	)
	  )

That way you don't have to go through all the attribute definitions and eliminate the need to sort the list

 


@leonardo.alvarez4SZJL wrote:

And how can I use it in multiple drawings by selecting a folder.


You may have to select between ActiveX or Vanilla lisp depending on what method you are going to use to go through multiple files.

 

With Vanilla is safe to use script or AccoreConsole , but if you choose Visual lisp read this similar to what i did with this recent  post

 

HTH

 

 

 

Message 9 of 10

leonardo.alvarez4SZJL
Advocate
Advocate

@pbejse 

Always coming in clutch. Thank you for the feedback

0 Likes
Message 10 of 10

leonardo.alvarez4SZJL
Advocate
Advocate

@Sea-Haven 

 

Very good, I'll look into this for sure!

0 Likes