Lisp to calculate dynamic block lengths based on specific possible widths

Lisp to calculate dynamic block lengths based on specific possible widths

Anonymous
Not applicable
516 Views
4 Replies
Message 1 of 5

Lisp to calculate dynamic block lengths based on specific possible widths

Anonymous
Not applicable

Hello all!
I have written a lisp that in theory should comb through my drawing, select all my dynamic blocks, check their width attributes, and then give me the total lengths of each different width value. (example: "Order 4 units of 3" wide wireway, Order 2 units of 2" wide wireway, etc....)
I've only been learning lisp for a couple weeks, so my knowledge level does not support my level of code ambition.
If anyone is willing to take the time to help point out what i'm doing that is wrong, or where i can make improvements, or any hints or tips, I would be very thankful! 🙂

 

Here are some additional details that may be helpful:
There is only one dynamic block on my drawing, its called DynPan (for dynamic panduit). (Though many of these blocks exist on the drawing)
It has a "Width" attribute and "Length" attribute.
There are only 6 allowed options for the width attribute. This is the "realwidth" called in my code.
These are 1.25, 1.75, 2.25, 3.25, 4.25, & 6.25.
The manufacture lists these as 0.25" smaller than the actual width. (so 1.25 is actually called 1", 1.75 is actually called 2", and so on)


;;;WirewayCalc_3.0 Written by Bw 11-08-2021

(vl-load-com)
(defun c:PanCalc (/ width realwidth total selectionset intger selectionsetname obj n i)
  
   ; ❤️ Lee Mac the Man, the Myth, the Legend <3
  (defun LM:getdynpropvalue ( blk prp )
    (setq prp (strcase prp))
    (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
	     (vlax-invoke blk 'getdynamicblockproperties)
	     )
    ) ; Lee Mac never ends. ;)

	(setq n 0)
	(setq i 0)
  	(setq realwidth '(1.25 1.75 2.25 3.25 4.25 6.25))
	(setq total '(0.0 0.0 0.0 0.0 0.0 0.0))
        (setq units '(0.0 0.0 0.0 0.0 0.0 0.0))
       
  
  (if (setq selectionset
	     (ssget "x" '((2 . "`*U*"))
		    ) ;end creating the selection set
	    )
    (progn
      
     (repeat 6
       
      (repeat (setq intger (sslength selectionset))
	(setq selectionsetname
	       (ssname selectionset
		       (setq intger (1- intger))
		       )
	      obj (vlax-ename->vla-object selectionsetname)
	  ) ;end setqs        
	     (set (nth n total) (+ (nth n total)
		       (cond
			 (
			  (= (LM:getdynpropvalue obj "Width") (nth n realwidth))
			  (LM:getdynpropvalue obj "Length")
			 )
			 (0)
			) ;end conditional
	         ) ;end totaling the lengths
	     ) ;end set
	  (set  (nth n units) (1+ (fix (* 1.25 (/ (/ (nth n total) 12) 6)))))
	
	  (setq n (1+ n))
	  
       ) ;end second repeat
      ) ; end first repeat


      (repeat 6
	(setq width (- (nth i realwidth) 0.25))	
      	(princ ( strcat "\nYou'll want to order the following number of 6 foot long by " (rtos width 2)  " units of wireway: ---> "(rtos (nth i units) 2)))
        (princ )
       ) ; end repeat 
      ) ;end progn
    (princ)
    ) ;end if
  (princ)
) ;end function

 

0 Likes
Accepted solutions (1)
517 Views
4 Replies
Replies (4)
Message 2 of 5

ВeekeeCZ
Consultant
Consultant
Accepted solution

Post the block dwg. 

 

Here is the core func untested without all the bells and whistles... 

 

(vl-load-com)

(defun c:Test ( / LM:getdynpropvalue s i o w l lst a)
  
  (defun LM:getdynpropvalue ( blk prp )
    (setq prp (strcase prp))
    (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
	     (vlax-invoke blk 'getdynamicblockproperties)))
  
  (if (setq s (ssget "_X" '((0 . "INSERT")
		       (-4 . "<or") (2 . "`*U*") (2 . "DynPan") (-4 . "or>")))) ; it keeps its origin name until some of dynprop is changed.
    (repeat (setq i (sslength s))
      (and (setq o (vlax-ename->vla-object (ssname s (setq i (1- i)))))
	   (= (if (vlax-property-available-p o 'EffectiveName)
		(vla-get-EffectiveName o)
		(vla-get-Name o))
	      "DynPan")
	   (setq w (LM:getdynpropvalue o "Width"))
	   (setq l (LM:getdynpropvalue o "Length"))
	   (setq w (+ w 0.25))
	   (setq lst (if (setq a (assoc w lst))  					; lst has to be localized! The other var just should be.
		       (subst (cons w (+ l (cdr a))) a lst)
		       (cons (cons w l) lst))))))
  (setq lst (vl-sort lst '(lambda (e1 e2) (< (car e1) (car e2)))))
  (foreach e lst
    (princ (strcat "\nOrder " (rtos (cdr e) 2)  " units of " (rtos (car e) 2))))
  (princ)
  )

Edit: Fixed after testing.

 

Message 3 of 5

Anonymous
Not applicable

Oh wow! thanks as always @ВeekeeCZ !
This looks incredibly clean and incredibly out of my league 🙂 haha
Yea, i definitely need to do my homework on this to get a better grasp of what's happening.
I suspect this is exactly what i'm looking for, but I'll need a bit to play around with it hopefully in the next couple days. (Just kicked off a new job so my lisp time has been cut short this week)


Hopefully I correctly attached the dynamic block, I think you might have to explode it for it to work? (I'm still new to those as well. I insert it via a custom tool palette that I think i assigned via the Design Center... i don't have to explode it when I do it that way)
In case the block doesn't work for whatever reason, i've also attached a screen shot of it in the block editor for reference. (i really wanted to figure out how to add editable text that moved center with the expanding length and width... but after hours of not getting it working I decided to cut my losses and move on)

DynPan-BEDIT.JPG

0 Likes
Message 4 of 5

ВeekeeCZ
Consultant
Consultant

Well, I just wanted to test the code - and fix it. Drawing with some of those blocks would have been fain. 

Not so versed with dyn blocks, so I didn't look inside.

Posted fixed code. Did not bother with units much, that's up to you to fix.

Good luck with learning.

Cheers.

Message 5 of 5

Anonymous
Not applicable

@ВeekeeCZ Thanks for the solution!
Like you said, I do still need to get the math in for the units, and the following line needed a minus instead of plus:
(setq w (- w 0.25))
But those are absolutely things i already know how to do!
So thanks again! Cheers!