Jump to content

Set Attribute Value by Lee Mac not working.


Strydaris

Recommended Posts

Hey everyone,

 

I am trying to use Lee Mac's Set Attributes code that he has posted on his website and I can't seem to get it to work. His code is below.

 

;; Set Attribute Values  -  Lee Mac
;; Sets attributes with tags found in the association list to their associated values.
;; blk - [ent] Block (Insert) Entity Name
;; lst - [lst] Association list of ((<tag> . <value>) ... )
;; Returns: nil

(defun LM:setattributevalues ( blk lst / enx itm )
    (while (and (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk))))))
        (if
            (and
                (setq itm (assoc (cdr (assoc 2 enx)) lst))
                (entmod (subst (cons 1 (cdr itm)) (assoc 1 (reverse enx)) enx))
            )
            (entupd blk)
        )
    )
    nil
)

 

Inside my code I have these lines, which I believe is what I need to use Lee's code.

 

(setq blk (entsel "\nSelect Area Chart to Update: "))
(setq vla-obj (vlax-ename->vla-object (car blk)))
(LM:setattributevalues vla-obj flrlst)

 

I have my code that creates an association list that looks like this ...((LVL4_AREA . "N/A") (LVL3_AREA . 1486) (LVL2_AREA . 841) (LVL1_AREA . 309))

flrlst is my variable that holds the list, so I am pretty sure I have the code correct to run Lee's code properly.

My block that I want to update has all the tags set to match the first items in the dotted pairs.

 

For the life of my I cant figure out why this isnt working.

I keep getting this error

error: bad argument type: lentityp #<VLA-OBJECT IAcadBlockReference 0000020c750748d8>

When I debug and break on error it shows the last break to be (entnext blk) in Lee's code.

 

Anyone understand whats going on here or if I am making the mistake?

 

Thanks in advance.

Link to comment
Share on other sites

My function requires an entity name rather than a VLA-object, try simply:

(setq blk (entsel "\nSelect Area Chart to Update: "))
(LM:setattributevalues (car blk) flrlst)

 

Link to comment
Share on other sites

Thanks Lee.

BTW big fan of your work and all you do to help people out. I have learned a lot from your website and posts on various forums. Still learning though.

 

So I made the change you mentioned and that seemed to fix the code from breaking. Thanks for your help with that.

But now the main issue is that the attribute values in the block are not updating to the values in the dotted pairs.

I know the blocks tags are labeled correctly and when I do an inspect on my flrlst variable I get this.

image.png.c90f165607c791b2f976ccb770ca346b.png

 

That all matches up with the block tags.

Any idea what I might be missing? Does order count when using your function? I wouldnt think it does as its looking for the tag to enter the value.

 

Link to comment
Share on other sites

I figured it out.

All the values that are in the dotted pairs need to be Strings.

 

Is there a way to check that in the SetAttribute function and if they are not strings, change them to a string?

 

Thanks.

Link to comment
Share on other sites

2 hours ago, Strydaris said:

Is there a way to check that in the SetAttribute function and if they are not strings, change them to a string?

 

You should check the validity of the arguments prior to passing them to my function - how are you obtaining the data?

  • Agree 1
Link to comment
Share on other sites

Hi Lee,

I'm still learning so bare with my code. There is a lot of comments in there so I can keep track of things and what things do so I can look at it later and not lose my focus while I am learning more about this.

I'll try and explain what I am looking for this to do.

Basically when you start the LISP, it will turn all the layers off except for what you need to select(for now).

Then you select level 1 Area polylines (if any), then level 2, then level 3 (if any), then level 4(if any). Typically there will be a large area polyline (Floor Area) and sometimes smaller area Polylines within the larger one (Which is Open To Below Areas) The Open to below polylines will always be a smaller area then the main Floor Area.

It puts all the numbers in a list, sorts the list from highest to lowest, adds all the numbers in the list except the first which will give me my Open to Below Area.

It then subtracts the Open to Below area from the highest value in the list and that gives me my Floor Area.

Then I create a new list to store that data into a dotted pair to use with your function with...

(setq flrlst (cons (cons flr flrarea) flrlst)
          otblst (cons (cons otb otbarea) otblst)

)
Which returns  (("LVL4_AREA" . 1051) ("LVL3_AREA" . 616) ("LVL2_AREA" . 841) ("LVL1_AREA" . 309)) for the flrlst

and   (("LVL4_OTB" . 101) ("LVL3_OTB" . 79) ("LVL2_OTB" . 257) ("LVL1_OTB" . 0)) for the otblst

 

(vl-load-com)
(defun c:flrarea (/ lay1 lay2 *error* curlay)
  ;;Set the Layers you use for Floor area Calcs here
  (setq	lay1 "AREA-Floor"
	;;Floor Area Layer
	lay2 "WD-Wall"
	     ;;Another Layer for something
  )
  ;;End of Layer Set

  ;;SETQs TO BE DELETED AFTER LISP IS COMPLETE
  (SETQ	NLST NIL
	flrlst NIL
	otblst NIL
	lvl NIL
	flrarea nil
	otbarea nil
  )

  ;;ERROR HANDLING
(defun *error* (errmsg)
(princ "\nThis is a trap. HANDLE IT!! ")
(terpri)
(layerstate-restore "$Cas-Temp" NIL NIL)
(layerstate-delete "$Cas-Temp")
(setvar 'clayer Curlay)
(al-Regen)

(prompt errmsg)
(princ)
)

  ;;END OF ERROR HANDLING

  ;;Save the current layer state, set the layer to your Floor Area Layer and Freeze all other layers
  (setq curlay (getvar 'clayer))
  (if (layerstate-has "$Cas-Temp")
    (layerstate-delete "$Cas-Temp")
  )
  (layerstate-save "$Cas-Temp" 31 nil)
  (vl-cmdf "_layer" "_Set" lay1 "_Freeze" "*" "")
;;End of Layer Save and Change

;;Start Main Command
  (setq lvl 1)
  (while (/= lvl 5)
    (setq flr (strcat "LVL" (itoa lvl) "_AREA"));Set the incrementing variables for Areas
    (setq otb (strcat "LVL" (itoa lvl) "_OTB"));Set the incrementing variables for OTBs
;;Select the Area Objects
    (prompt (strcat "\nGet all Level " (itoa lvl) " area Polyline(s) or [Enter] for 0: "))
    (setq objlst (ssget (list '(0 . "LWPOLYLINE") (cons 8 lay1))))
;;If object selection set does not equal nil, then cycle through the selection set & get the areas of each object in the list
    (setq i    0
	  nlst nil)
    (if	(/= objlst nil)
      (repeat (sslength objlst)
	(setq entname (vlax-ename->vla-object (ssname objlst i))
	      entname (atoi (rtos (/ (vla-get-area entname) 144) 2 0))
	)
;;Create the list then sort the list from largest to smallest
	(setq nlst (cons entname nlst)
	      i	   (1+ i))
      )	;End Repeat for getting and sorting the list
    );End if
    ;start Conditional statements
    (cond ((/= nlst nil)
	   (setq nlst (vl-sort nlst '>)
		 n	 1
		 otbarea 0
	   )
	   (repeat (- (length nlst) 1)
	     (setq otbarea (+ (nth n nlst) otbarea))
	     (setq n (1+ n))
	   );end repeat
	   (setq flrarea (- (car nlst) otbarea))
	  );end 1st Condition
	  ;Start 2nd Condition
	  ((and (= lvl 1) (= nlst nil))
	   (setq flrarea 0)
	   (setq otbarea 0)
	  );End 2nd Condition
	  ;Start 3rd Condition
	  ((and (/= lvl 1) (= nlst nil))
	   (setq flrarea "N/A"
		 otbarea "N/A")
	  );End 3rd Condition
    );END CONDITIONAL STATEMENTS
     ;(setq test (type flrarea))
;(if (numberp flrarea)
    (setq flrlst (cons (cons flr flrarea) flrlst)
	  otblst (cons (cons otb otbarea) otblst)
	  )
 ;      (setq flrlst (cons (cons flr flrarea) flrlst)
;	  otblst (cons (cons otb otbarea) otblst))
 ;  )
    (setq lvl (1+ lvl));setq to cycle through while loop and end it.
  );End While

   ;(setq TOTAL (+ (cdr (nth 3 flrlst)) (cdr (nth 2 flrlst)) (cdr (nth 1 flrlst))))
   
;Restore the layers & layerstate to previously stored state
  (layerstate-restore "$Cas-Temp" NIL NIL)
  (layerstate-delete "$Cas-Temp")
  (setvar 'clayer curlay)
  (al-Regen)
   
;ADDS THE VALUES TO THE AREA CHART BLOCK
(setq blk (entsel "\nSelect Area Chart to Update: "))
(LM:setattributevalues (car blk) flrlst)
(LM:setattributevalues (car blk) otblst)

;(setq blk (entnext (car blk)))
;(setq enx (entget blk))
;(setq itm (assoc (cdr (assoc 2 enx)) flrlst)) 
  (princ flrlst)
  (princ otblst)
  (princ nlst)
  (princ)
)

;; Set Attribute Values  -  Lee Mac
;; Sets attributes with tags found in the association list to their associated values.
;; blk - [ent] Block (Insert) Entity Name
;; lst - [lst] Association list of ((<tag> . <value>) ... )
;; Returns: nil

(defun LM:setattributevalues ( blk lst / enx itm )
    (while (and (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk))))))
        (if
            (and
                (setq itm (assoc (cdr (assoc 2 enx)) lst))
                (entmod (subst (cons 1 (cdr itm)) (assoc 1 (reverse enx)) enx))
            )
            (entupd blk)
        )
    )
    nil
)

(defun al-Regen ()
(vl-load-com)
(setq thisdrawing 
       (vla-get-activedocument 
               (vlax-get-acad-object)))
(vla-Regen thisdrawing acAllViewports)
(princ)
)

 

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