Jump to content

LISP to Insert Dynamic Block & Set Values of Attributes


Bill Tillman

Recommended Posts

I have a block which is a detail bubble and when I insert it using this:

(command-s "._INSERT" "TAG BB1" pt1 "16" "16" "")

The block gets inserted but I get prompted to enter the values for two of the attributes DetNo and ShtNo. I'd also like to set a value for the settings Angle1 and Distance1 and then just insert the block at the desired location with the values all set. No entry needed by the users.

Detail LISP.dwg

Link to comment
Share on other sites

-insert should fix it, oh yeah I think its attdia also set to 0

 


(command-s "-INSERT" "TAG BB1" pt1 1 0 "16" "16" "")

(command-s "-INSERT" "TAG BB1" pt1 scale ang "16" "16" "")

Edited by BIGAL
Link to comment
Share on other sites

Thanks BIGAL,

 

I need to study some more on this. Here's what I've got so far:

(command-s "-INSERT" "TAG BB1" pt1 0 0 "16" "16" "")

I added some additional code to set the variable ATTDIA to 0. The dialog window no longer opens but the program pauses and waits for user input with a prompt for the two variables "DT" and "ST". After you enter these it finishes and the block is in, but it's not getting the other variables set as intended.  And the whole idea is to avoid user input.

 

I noticed in the properties of this block, which was assembled by someone else, the two fields "Angle1" and "Distance1" are under the section called "Custom". I am doing some more research on this. The original author of this block is no longer around to ask questions of.

Edited by Bill Tillman
Link to comment
Share on other sites

  • 3 weeks later...

Revisiting this one today. For whatever reason I can't seem to find the resolution for this. I'm using a very simple block that is a rectangle rotated 45° angle to form a diamond shape. Inside this diamond is a single attribute called "MkNo". I would like to assign the value of "A" to the attribute in this block which is named MkNo. 

 

NOTE: While I was playing around with the command line I actually got this to work. I checked the history and apparently I used up the history buffer and can't get the command I used back. It did insert the block with the letter "A" in it.


(command-s "-INSERT" "GLASSTAG" pt1 "" "" "" "A")

Link to comment
Share on other sites

Thanks dlanorh,

 

Please excuse this unplanned behavior of this post. The black rectangle apparently is a screen shot that somehow got caught in the post and I can't delete it.

 

The file with just the block stored in it is attached in 2010 format. I have been searching endlessly and only find articles which say this should do the trick. But I only get the block inserted and the attribute is still blank. The command line says " A Unknown command "A")...

 

 

(command "_-INSERT" "GLASS TAG" zp "1" "1" "" "A")

2010 Diamond Block.dwg

image.png

Edited by Bill Tillman
Link to comment
Share on other sites

I hope I have finally resolved this. I don't recall what the original setting on the attribute was for "Preset". I do know that something I read made me toy around with this parameter but I didn't get the desired results. I set the Preset parameter to "NO" and then used this in the command window and all worked well. I also found that the code needed (setvar "ATTDIA" 0) and (setvar "ATTREQ 1).

(command "._-INSERT" "GLASS TAG" '(-200 200) "1" "1" "0" "B")
Edited by Bill Tillman
Link to comment
Share on other sites

Okay, with the simpler block taken care of I'm now moving on to the more complex dynamic block. The new copy of the drawing file saved to 2010 version is attached and it has the other block "TAG BB1". This one is dynamic and has several attributes I'd like to again assign using LISP, on the fly, no user input required. This block was created by someone else so I can't claim I know all about it especially since two of the values I want to set are in the "Custom" section of the properties.  These are the ones which control the dynamic actions of the block like which angle the line appears and how long it is.

2010 Diamond Block.dwg

Link to comment
Share on other sites

9 hours ago, Bill Tillman said:

I hope I have finally resolved this. I don't recall what the original setting on the attribute was for "Preset". I do know that something I read made me toy around with this parameter but I didn't get the desired results. I set the Preset parameter to "NO" and then used this in the command window and all worked well. I also found that the code needed (setvar "ATTDIA" 0) and (setvar "ATTREQ 1).


(command "._-INSERT" "GLASS TAG" '(-200 200) "1" "1" "0" "B")

 

Glad you got it sorted. I noticed straight away that a simple insert wasn't prompting for the attribute value.

Link to comment
Share on other sites

Still hacking at the Dynamic Block insertion this morning.  I am able to insert it and set values for the attributes "DT" and "ST" (see screen shot of the properties for this block). What I'm after now is to set values for the other two parameters which are shown under the "Custom" section of the properties, "Angle1" and "Distance1". I'm doing lots of searches and finding many similar topics but not quite the cigar I need for this project

 

image.thumb.png.50a83007ef07dd0aef7b0c498a1111d7.png

Link to comment
Share on other sites

This lisp and two sub functions will do as you ask. Unfortunately I don't think it can be done on the fly (without user input) as to set the values you need to get the values.

You can play around altering settings (top setq in main c:IBA routine) but this will only ever set the angle and distance to the hard coded values. You could read a set of (angle dist) from an external file. Code is documented.

 

;Lee Macs set dynamic block properties function
;adapted by rh
(defun LM:setdynpropvalue ( blk prp val )
    (vl-some
       '(lambda ( x )
            (if (= (strcase prp) (strcase (vla-get-propertyname x)))
                (progn
                    (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                    (cond (val) (t))
                );end_progn
            );end_if
        )
        (vlax-invoke blk 'getdynamicblockproperties)
    )
);end_defun

;convert degrees to radians
(defun rh:D2R (d) (* pi (/ d 180.0)))

(defun c:IBA ( / blk_scl p_ang p_dist blk_prop_lst blk_prop_val atd atq b_obj)

  (setq blk_scl "16"                              ;block scale
        p_ang 60.0                                ;angle as real in degrees
        p_dist 25.0                               ;distance as real
        blk_prop_lst (list "Angle1" "Distance1")  ;list of block properties to change
        blk_prop_val (list (rh:D2R p_ang) p_dist) ;list of converted values in order of blk_prop_lst 
  );end_setq
  
  (cond ( (/= (getvar 'attdia) 0)                 ;sets attdia to 0 if not 0
          (setq atd (getvar 'attdia))
          (setvar 'attdia 0)
        )
  );end_cond
  
  (cond ( (/= (getvar 'attreq) 1)                 ;sets attreq to 1 if not 1
          (setq atq (getvar 'attreq))
          (setvar 'attreq 1)
        )
  );end_cond
  
  (command "_-insert" "TAG BB1" pause blk_scl blk_scl "" "2" "300")                ;Much the same as the simple block pause is to allow placement or supplied insertion point
  
  (setq b_obj (vlax-ename->vla-object (entlast)))                                  ;gets the last entity (the block just inserted) and convert to a vla-object
  
  (mapcar '(lambda (x y) (LM:setdynpropvalue b_obj x y)) blk_prop_lst blk_prop_val);Feed the two lists to LM:setdynpropvalue item by item
  
  (if atd (setvar attdia atd))                 ;resets attdia to entry value if changed
  (if atq (setvar attreq atq))                 ;resets attreq to entry value if changed
);end_defun  

 

Edited by dlanorh
Update code comment
Link to comment
Share on other sites

Thanks again my friend. This seems to do the trick in only a few lines.


(defun SetDynProp (e propname newval / obj v vval sal tot i)
  (setq    obj (if    (= (type e) 'vla-object)
          e
          (vlax-ename->vla-object e)
        )
  )
  (if (= (vlax-get-property obj 'isdynamicblock) :vlax-true)
    (progn
      (setq v     (vla-getdynamicblockproperties obj)
        vval (vlax-variant-value v)
        sal     (vlax-safearray->list vval)
        tot     (length sal)
        i     0
      )
      (while (< i tot)
    (if (= (vlax-get-property (nth i sal) "PropertyName") propname)
      (progn
        (vlax-put-property (nth i sal) "Value" newval)
        (setq i tot)
      )                ;end progn
      (setq i (1+ i))
    );end if
      );end while
    ) ;end progn
  );end if
);end defun SetDynProp

I call it like this:

(command-s "._-INSERT" "TAG BB1" pt1 0 0 "16" "16" "0" "2" "302")
  (SetDynProp (entlast) "Angle1" (dtr 180.))
  (SetDynProp (entlast) "Distance1" 12)

This is an on-the-fly project, with no user input allowed. This inserts the dynamic block with the two attributes "DT" and "ST" and the two Custom Properties of "Angle1" and "Distance1" assigned properly and without any pause or user input.

Edited by Bill Tillman
Link to comment
Share on other sites

Have a look at lee-mac's dynamic block it uses a list for the input so can do angle and dist in one go.

 

Also (dtr 180)  is Pi which is valid in lisp  

(SetDynProp (entlast) "Angle1" pi)
Link to comment
Share on other sites

Thanks for the tips. I've always been a big fan of Lee-Mac. So I tried out one of the Dynamic Block Functions.


;; Set Dynamic Block Property Value  -  Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil

(defun LM:setdynpropvalue ( blk prp val )
    (setq pr
       p (strcase prp))
    (vl-some
       '(lambda ( x )
            (if (= prp (strcase (vla-get-propertyname x)))
                (progn
                    (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                    (cond (val) (t))
                )
            )
        )
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

 

So when I call this like:



(LM:setdynpropvalue (entget (entlast)) "Angle1" "270.0")

I do this just after inserting or selecting the block. When this app runs it will need to run without user input. I get back the entity properties listing of the block but nothing changes with the properties of the block.

Link to comment
Share on other sites

You need to make the block a Vla object not a entget.

 


(LM:setdynpropvalue (entget (entlast)) "Angle1" "270.0") 
 

(LM:setdynpropvalue (vlax-ename->vla-object (entlast)) "Angle1" "270.0") 

Link to comment
Share on other sites

Thanks again BIGAL,

 

That's working fine now. Just had to use (dtr 270.) as you referenced. I was curious of your previous post which said I could do both properties in one go... I'm guessing that's a different program than the one I selected.

 

And hats off again to Lee-Mac. I'm doing some light LISP work for this client and it's like shaking off a lot of rust to get back into coding.

Link to comment
Share on other sites

Its Set dynamic properties

 


;; Set Dynamic Block Properties  -  Lee Mac;; Modifies values of Dynamic Block properties using a supplied association list.;; blk - [vla] VLA Dynamic Block Reference object;; lst - [lst] Association list of ((<Property> . <Value>) ... );; Returns: nil(defun LM:setdynprops ( blk lst / itm )    (setq lst (mapcar '(lambda ( x ) (cons (strcase (car x)) (cdr x))) lst))    (foreach x (vlax-invoke blk 'getdynamicblockproperties)        (if (setq itm (assoc (strcase (vla-get-propertyname x)) lst))            (vla-put-value x (vlax-make-variant (cdr itm) (vlax-variant-type (vla-get-value x))))        )    ))

Link to comment
Share on other sites

  • 2 years later...
On 30.09.2018 at 15:17, Bill Tillman said:

Hala bu sabah Dinamik Blok girişinde hack'leniyor. Bunu ekleyebiliyorum ve "DT" ve "ST" nitelikleri için değerleri ayarlayabiliyorum (bu bloğun özelliklerinin ekran görüntüsüne bakın). Şimdi peşinde olduğum şey, özelliklerin "Özel" bölümü altında gösterilen diğer iki parametre, "Açı1" ve "Mesafe1" için değerleri ayarlamaktır. Çok fazla arama yapıyorum ve pek çok benzer konu buluyorum ama bu proje için tam olarak ihtiyacım olan puro değil

 

image.thumb.png.50a83007ef07dd0aef7b0c498a1111d7.png

I have a template that I prepared from excel from the command line you are looking for. Can you help me about how I can change the marked part in the photo I added in the autocad command line from the command line.
Link to comment
Share on other sites

  • 4 weeks later...

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