Jump to content

How do I set a custom property in a dynamic block?


AaronHolmes

Recommended Posts

Hi,

 

I'm trying to set a custom property in a dynamic block. Unfortunately, it's not as simple as just getting the attribute.

 

I'm having trouble with Lee Mac's Set Dynamic Property Value. I'm probably just doing it wrong.

 

The custom property I'm trying to set is called "Distance3".

The function is basically the last line of the code.

Suggestions?

 

Thanks.

-AaronHolmes.

 

 

 


;Set the width of the RoomTag to suit the length of the room number.
(defun c:RTSIZE ()

(vl-load-com)

;;------------=={ Set Dynamic Property Value }==--------------;;
;;                                                            ;;
;;  Modifies the value of a Dynamic Block Property            ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Dynamic Block Reference Object                ;;
;;  prop  - Dynamic Block Property Name                       ;;
;;  value - New value for Property                            ;;
;;------------------------------------------------------------;;
;;  Returns: Value property was set to, else nil              ;;
;;------------------------------------------------------------;;

(defun LM:SetDynamicPropValue ( block prop value )
   (setq prop (strcase prop))
   (vl-some
       (function
           (lambda ( _prop )
               (if (eq prop (strcase (vla-get-propertyname _prop)))
                   (progn
                       (vla-put-value _prop
                           (vlax-make-variant value
                               (vlax-variant-type (vla-get-value _prop))
                           )
                       )
                       value
                   )
               )
           )
       )
       (vlax-invoke block 'GetDynamicBlockProperties)
   )
)


;END DEFUN


(if (setq ent(entsel "\n Select a Block: ")) ;- Let the user select a block

;;Get the attribute list and set the variables.
 (progn                                           
  (setq en(car ent))                             ;- Get the entity name of the block
  (setq enlist(entget en))                                     ;- Get the DXF group codes
  (setq blkType(cdr(assoc 0 enlist)))                          ;- Save the type of entity
  (setq ipt (cdr (assoc 10 enlist)))                           ;- gets the insertion point of block, for use later during insert
  (if (= blkType "INSERT")                                     ;- If the entity type is an Insert entity then do the following:
   (progn
    (if(= (cdr(assoc 66 enlist)) 1)                      ;- See if the attribute flag equals one (if so, attributes follow)
     (progn
      (setq en2(entnext en))                                   ;- Get the next sub-entity
      (setq enlist2(entget en2))                               ;- Get the DXF group codes
      (while (/= (cdr(assoc 0 enlist2)) "SEQEND")              ;- Start the while loop and keep looping until SEQEND is found.

   (if (= (cdr(assoc 2 enlist2)) "RM#")                    ;- Get the Room Number
       (setq ROOMNUMBER (assoc 1 enlist2))
   )
   ;(princ)
   ;(princ "\n ")                                                ;-Print a new line
       ;(princ enlist2)                                              ;-Print the attribute DXF group codes
       (setq en2(entnext en2))                             ;- Get the next sub-entity
       (setq enlist2(entget en2))                          ;- Get the DXF group codes
      );CLOSE PROGN
     );CLOSE IF
    );CLOSE PROGN
   );CLOSE IF
  )
  (setq ROOMNUMBERLENGTH (strlen (CDR ROOMNUMBER)))           ; - Count the number of characters in the room number.
 )
)
(LM:SetDynamicPropValue en "Distance3" 5000); -The 5000 is arbitrary for now. It will end up being a calculation, but I'm trying to get a simple success before making it more complicated.
)


Link to comment
Share on other sites

Hi Aaron,

 

Note that my function requires a 'VLA Dynamic Block Reference Object' as the 'block' argument, so you will need to convert your entity name to a VLA-Object:

 

(LM:SetDynamicPropValue (vlax-ename->vla-object en) "Distance3" 5000)

Link to comment
Share on other sites

Awesome Lee, That did it! - But you knew that already. :)

Thanks again for the insight and assistance.

//Aaron.

Link to comment
Share on other sites

  • 2 weeks later...

Ok - lots of progress on the code. I now have a routine that will let you select a roomtag block, replace it with the one we need, preserve the attributes, and size the dynamic bubble to the right size.

 

Next goal, wrap all this so I can do all the blocks at once. I suspect it has something to do with ssget and ssnamex, but I can't figure out what's really going on there, and I might be completely off base on that too.

 

Any suggestions, or pointers in the right direction would be appreciated.

 

//Aaron.

 

;inspired in large part by  http://www.jefferypsanders.com/autolispexp_enti.html
;Setting up the right size for the Roomtag Block with the Set Dynamic Property Value.
;Necessary for rightsizing the room number bubble.

(vl-load-com)

;;------------=={ Set Dynamic Property Value }==--------------;;
;;                                                            ;;
;;  Modifies the value of a Dynamic Block Property            ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Dynamic Block Reference Object                ;;
;;  prop  - Dynamic Block Property Name                       ;;
;;  value - New value for Property                            ;;
;;------------------------------------------------------------;;
;;  Returns: Value property was set to, else nil              ;;
;;------------------------------------------------------------;;
(defun LM:SetDynamicPropValue ( block prop value )
   (setq prop (strcase prop))
   (vl-some
       (function
           (lambda ( _prop )
               (if (eq prop (strcase (vla-get-propertyname _prop)))
                   (progn
                       (vla-put-value _prop
                           (vlax-make-variant value
                               (vlax-variant-type (vla-get-value _prop))
                           )
                       )
                       value
                   )
               )
           )
       )
       (vlax-invoke block 'GetDynamicBlockProperties)
   )
);/defun


(defun c:RTG ( / ss ipt ROOMNAME1 ROOMNAME2 ROOMNUMBER en enlist newent ROOMNUMBERLENGTH en2 enlist2 )
;inspired in large part by  http://www.jefferypsanders.com/autolispexp_enti.html
; The While command with no exit conditions lets you do this over and over again without restarting the command.


(if  (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 "room info") (cons 66 1) )))
   (progn
       (foreach ent (mapcar 'cadr (ssnamex ss))

(progn   

                                             
 (setq en(car ent))                                           ;- Get the entity name of the block
 (setq enlist(entget en))                                     ;- Get the DXF group codes
 (setq blkType(cdr(assoc 0 enlist)))                          ;- Save the type of entity
 (setq ipt (cdr (assoc 10 enlist)))                           ;- gets the insertion point of block, for use later during insert
 (if (= blkType "INSERT")                                     ;- If the entity type is an Insert entity then do the following:
  (progn
   (if(= (cdr(assoc 66 enlist)) 1)                      ;- See if the attribute flag equals one (if so, attributes follow)
   (progn
     (setq en2(entnext en))                                   ;- Get the next sub-entity
     (setq enlist2(entget en2))                               ;- Get the DXF group codes
     (while (/= (cdr(assoc 0 enlist2)) "SEQEND")              ;- Start the while loop and keep looping until SEQEND is found.

   ;check to see if the attribute tag is the one we want, if so, set the variable.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;CHANGE THE NEXT LINE TO INCLUDE THE NAME OF THE ROOMNAME ATTRIBUTE IN THE BLOCK
   (if (= (cdr(assoc 2 enlist2)) "RMNAME1")
       (setq ROOMNAME1 (assoc 1 enlist2))
   )
   ;Check to see if the attribute tag is the one we want, if so, set the variable

;CHANGE THE NEXT LINE TO INCLUDE THE NAME OF THE SECOND LINE OF ROOMNAME ATTRIBUTE IN THE BLOCK
   (if (= (cdr(assoc 2 enlist2)) "RMNAME2")
       (setq ROOMNAME2 (assoc 1 enlist2))
   )

;CHANGE THE NEXT LINE TO INCLUDE THE NAME OF THE ROOM NUMBER ATTRIBUTE IN THE BLOCK
   (if (= (cdr(assoc 2 enlist2)) "RMNUMB")
       (setq ROOMNUMBER (assoc 1 enlist2))
   )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   (princ)
   ;(princ "\n ")                                                ;-Print a new line
       ;(princ enlist2)                                               ;- Print the attribute DXF group codes
       (setq en2(entnext en2))                             ;- Get the next sub-entity
       (setq enlist2(entget en2))                      ;- Get the DXF group codes
     )
    )
   )  ;- Close the if group code 66 = 1 statement
  );/progn
 )   ;- Close the if block type = "INSERT" statement
)
)


;Select between one, two, and zero lines of roomnames.
(if (= (strlen (CDR ROOMNAME1)) 0)
   (progn
       (if (= (strlen (CDR ROOMNAME2)) 0)
           ;TRUE - No room names
           (command "-insert" "ROOMTAG.DWG" "_NON" ipt "1" "1" "0" "" (CDR ROOMNUMBER))
           ;FALSE -One room name
           (command "-insert" "ROOMTAG.DWG" "_NON" ipt "1" "1" "0" (CDR ROOMNAME2) "" (CDR ROOMNUMBER))
       );/if
   );/progn
);/if
(if (> (strlen (CDR ROOMNAME1)) 0)
   (command "-insert" "ROOMTAG.DWG" "_NON" ipt "1" "1" "0" (CDR ROOMNAME1) (CDR ROOMNAME2) "" (CDR ROOMNUMBER))
)

   ;Rightsize the Room Number Bubble!
   (setq newent(entlast)) ;- Select the most recently inserted object.                                        
   (setq ROOMNUMBERLENGTH (strlen (CDR ROOMNUMBER)))    ;- Count the number of characters in the room number.
   (LM:SetDynamicPropValue (vlax-ename->vla-object newent) "Distance3" (+ 255 (* ROOMNUMBERLENGTH 230)))
   ;/Rightsize the roomnumber bubble.

;delete the original block
(entdel en)
)
)


(princ)
)

Link to comment
Share on other sites

Use the ssget function with the "_X" mode string (to search the drawing database), with a relevant filter list for your blocks. Though, be aware that dynamic blocks will appear as anonymous blocks (*U##) when their dynamic block properties are altered from the block definition, so you will need to include all anonymous blocks in the selection and check the effective name of each block against the required name.

 

In that respect, this page may be of interest:

 

http://lee-mac.com/getanonymousreferences.html

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