TheSwamp

CAD Forums => CAD General => Topic started by: 42 on November 19, 2003, 04:51:13 PM

Title: Changing blocks globeally
Post by: 42 on November 19, 2003, 04:51:13 PM
Evening, morning or afternoon wherever you are.

An answer that I sure that I have seen before, but I’m unable to find it. The problem I have is that I have multiple blocks (same block) giving vertical heights in a building section. i.e. 4.770, 7.542…. etc. Now through a client alteration the entire building is being raised 0.3, (all dimensions are in meters, although it wouldn’t matter if the dimensions were in inches, feet wombats or what ever). So I need to increase the values by 0.3m, the above will become 5.070 and 7.842… etc etc. Not a problem if there were only a few on one drawing, but I have 10 drawings and probably upwards of 150 blocks to change. Is there a lisp available to globally change the value (attribute) of all selected blocks? If there is I want to steal it!
Title: Changing blocks globeally
Post by: daron on November 19, 2003, 04:53:41 PM
If you have express tools type gatte. If you don't I have a vba file that Trev wrote for me.
Title: Changing blocks globeally
Post by: 42 on November 19, 2003, 05:06:52 PM
Blimey are you reading my keyboard, this is a chat room. This is a reply after I tried your suggestion. Forgotten about gate. This will change all of the values to the same figure, i.e. if the original values were 6.9, 7.4, 8.7, and I changed 6.9 to 7.2 for instance then all of the values would become 7.2, not 7.2, 7.7, 9.0. Perhaps the vba from Trev would help, althoughI would need help in doing something with it. Thanks.
Title: Changing blocks globeally
Post by: daron on November 19, 2003, 05:27:55 PM
No, Trev's won't do what you ask. He wrote it for me because I asked for a dialog box version of the same command. Sounds like what you want is to select all the blocks and increment them to the same value from where they reside. That shouldn't be too difficult. Are all the blocks of the same name and more importantly are the changing values having the same tagname? What is the tagname? Do you have any experience in programming and would you like some help writing it, or do you just need a quick fix?
Title: Changing blocks globeally
Post by: 42 on November 19, 2003, 06:02:30 PM
All of the blocks have the same name.
Two attributes, one is a text string that does not change, the other is the numeric value that does. The tag is the same
Block name level.dwg
tag LEVEL
no
Yes but would'nt even know where to start and probably  not got enough time if I,m honest before this peticular job is nhanded over.
Yes.

Again thanks.
Trev is also looking at this via Cadalog.
Title: Changing blocks globeally
Post by: daron on November 20, 2003, 12:35:29 PM
See if this will work:
Code: [Select]
(defun attribute-list (x)
     (vlax-safearray->list
 (vlax-variant-value
      (vla-GetAttributes x)
 )
     )
)
(defun each-attribute (x string newval)
     (if (= (vlax-get-property x 'TagString) string)
 (vlax-put-property
      x
      'TextString
      (vlax-make-variant newval vlax-vbstring)
 )
     )
)
(defun ssget->vla-list (selection-set / index vla-list)
     (setq index (if selection-set
     (1- (sslength selection-set))
     -1
)
     )
     (while (>= index 0)
 (setq vla-list
(cons
     (vlax-ename->vla-object
  (ssname selection-set index)
     )
     vla-list
)
index (1- index)
 )
     )
     vla-list
)
;;;=====================================================================;
;;; increments level blocks globally                           ;
;;;=====================================================================;
(defun c:cbg (/ objlist n incval atts)
  (setq objlist (ssget->vla-list (ssget '((2 . "level")))))
  (setq n nil)
  (initget 2)
  (setq incval (getreal "\nType the value to add to each string: "))
  (foreach item objlist
    (setq atts (attribute-list item))
    (foreach val atts
      (each-attribute
val
"level"
(+ (atof (vla-get-textstring val))
  incval
)
      )
    )
  )
  (princ)
)
Title: Changing blocks globeally
Post by: 42 on November 20, 2003, 12:38:32 PM
Thankyou. I will try it when I get home.
Title: Changing blocks globeally
Post by: 42 on November 21, 2003, 07:39:16 AM
I feel like the monkey climbing the tree and exposing his a**e.
I have saved it as a lisp file (cbg).loaded it Selected a number of tags and get the return  
'Select objects: Specify opposite corner: 3 found, 0 total 3 were filtered out'
Is it me?
Title: Changing blocks globeally
Post by: daron on November 21, 2003, 09:13:40 AM
Quote
Block name level.dwg

What's the name of the blocks you selected? You told me level. If the name of the block is level, you might capitalize level in this line.
Code: [Select]
(setq objlist (ssget->vla-list (ssget '((2 . "level")))))
If the name of the block is not level, either change level to the appropriate name or replace:
Code: [Select]
'((2 . "level"))
with
Code: [Select]
'((0 . "INSERT") (66 . 1))
That will select any block with attributes.

Also note, I am now in violation of the Daron Act (http://www.cadalog.com/phpbb2/viewtopic.php?p=41274#41274), so you might want to put (vl-load-com) in the routine. After you run it, if it still blows up, do as you did before and we'll get it working for you. You also, might want to repost the code if the changes don't work.
Title: Changing blocks globeally
Post by: 42 on November 21, 2003, 10:26:31 AM
Changing one thing at a time
changed 'level' to 'LEVEL' and ran it with the following message
Command: cbg

Select objects: 1 found

Select objects:
; error: no function definition: VLAX-ENAME->VLA-OBJECT

added ''((0 . "INSERT") (66 . 1))' as suggested and received the same message.
And excusing my ignorance, but where do I stick '(vl-load-com)' ?
Title: Changing blocks globeally
Post by: daron on November 21, 2003, 10:54:00 AM
Either before or after:
Code: [Select]
(vl-load-com)
(defun...()
(vl-load-com)
(rest of code here.)
)

You wouldn't need to put it in both places and it only needs to be in one place as long as it occurs before any vl- functions are activated.
Title: Changing blocks globeally
Post by: 42 on November 21, 2003, 11:16:52 AM
iT WORKS Many thanks

Code: [Select]

(vl-load-com)
(defun attribute-list (x)
     (vlax-safearray->list
     (vlax-variant-value
          (vla-GetAttributes x)
     )
     )
)
(defun each-attribute (x string newval)
     (if (= (vlax-get-property x 'TagString) string)
     (vlax-put-property
          x
          'TextString
          (vlax-make-variant newval vlax-vbstring)
     )
     )
)
(defun ssget->vla-list (selection-set / index vla-list)
     (setq index (if selection-set
            (1- (sslength selection-set))
            -1
       )
     )
     (while (>= index 0)
     (setq   vla-list
          (cons
               (vlax-ename->vla-object
               (ssname selection-set index)
               )
               vla-list
          )
      index    (1- index)
     )
     )
     vla-list
)
;;;=====================================================================;
;;; increments level blocks globally                                 ;
;;;=====================================================================;
(defun c:cbg (/ objlist n incval atts)
  (setq objlist (ssget->vla-list (ssget '((0 . "INSERT") (66 . 1)))))
  (setq n nil)
  (initget 2)
  (setq incval (getreal "\nType the value to add to each string: "))
  (foreach item   objlist
    (setq atts (attribute-list item))
    (foreach val atts
      (each-attribute
   val
   "LEVEL"
   (+ (atof (vla-get-textstring val))
      incval
   )
      )
    )
  )
  (princ)
)
Title: Changing blocks globeally
Post by: daron on November 21, 2003, 11:38:48 AM
You're highly welcome. Now, open the vlide and test each line. I wouldn't want you to just take off with code without understanding what makes it work. BTW, two of the functions were not written by me. I stole them too.
Title: Changing blocks globeally
Post by: Trev on December 05, 2003, 10:38:29 AM
How'd it go 42?
Sorry I havn't got back to you earlier. Been pretty busy lately &
no internet connection at work.  :shock:  hence why I have been a bit on the quite side.
been a bit side tracked so haven't got back to it.
The method I was doing (using lisp) was to select an attribute & from that selection
obtain the block name and the attribute tag. From there loop through the
the drawing table for each said block and add your addition to the value
of selected attribute. Including dialog box for ease of use.
(if that all makes sense)
The objective was so it could be used on any block with any attribute, that way it may have many uses in the future  :)  trying to think ahead really  :shock:
However I did hit a little snag, a major mental block.
I had 2 versions 1 would select the block and loop through finding all attributes. This was no good as I wanted it to be specific to the selected attribute.
The 2nd I could select the attribute and obtain tag & value, this was good but for some dumb reason I couldn't find the block name  :oops:
using nentsel for this but the assoc value 0 would return "insert" obviously
rather than the blockname if entsel was used.
I should do the VBA version. It would be a very similar program to the one I did for Daron (gatte.dvb)