Author Topic: Multiple attribute edit  (Read 4378 times)

0 Members and 1 Guest are viewing this topic.

Cad64

  • Guest
Multiple attribute edit
« on: January 30, 2006, 08:05:56 PM »
I am new to lisp, so I don't really know how to make this happen.

Say I have a block containing 10 attributes. Each attribute has a starting number, followed by a letter/no. combo. Ex: 100-A-1, 100-A-2, 100-B-1, 100-B-2, etc. The A-1, A-2, B-1, B-2,  etc. is the same in every block. Just the starting number changes from block to block. The program I am using now will allow me to change all attributes in a block in one shot, which is great. The problem is that it changes them all to 100-A-1 or whatever. I need to be able to change the starting number without affecting the letter/no. combo's. I tried keeping the (100) as an attribute and separating it from the (-A-1) which is now dtext. This works, but the client has a prog. that he will use to extract the attribute info from the drawing into excel to generate his sales charts, so the letter/no. combo needs to be part of the attribute. I don't want to manually change every attribute in the drawing one by one. This could take hours. Each block could have up to 16 attributes and each drawing could have hundreds of blocks.

Is there a way to append the combo's to the starting number, or change the starting number without affecting the combo's? Any help would be greatly appreciated

Also, is there a way to have the program terminate at the end, rather than having to hit enter twice? Since every block will have a different starting number, I don't need to select multiple blocks.

Thanks in advance.

I have included the program I am currently using which I think I got from this board? Let me know if you need more info.

(setq tag (itoa 100))               
(setq val (getstring "\nInput New Value: "))
(if (and tag (/= tag "") val (/= val ""))
  (while
    (progn
(princ "\nSelect Block Objects...")
(setq ss (ssget (list (cons 0 "INSERT"))))
)
(setq i 0)
(repeat (sslength ss)
(setq oBlock (vlax-ename->vla-object (ssname ss i)))
  (if (= (vla-get-HasAttributes oBlock) :vlax-true)
    (progn
(setq attributeList
(vlax-safearray->list
(variant-value (vla-GetAttributes oBlock))
 )
)
(foreach attrib attributeList
(if (= (vla-get-TagString attrib) tag)
(vla-put-TextString attrib val)
   )
  )
 )
)
(setq i (1+ i))
  )
 )
)
(princ)
)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #1 on: January 30, 2006, 10:27:52 PM »
Yes,
Preset each attribute value so that the numeric part is <say> "-" and the remainder is as you want it, for each attribute in each block definition.
ie :
-A-1
-A-2
.. etc < whatever >

Then have your routine :

Select the block,
iterate through ALL the attributes in that block
reading the preset value
if the preset first character is not "-", strip to the first "-"  edit:kwb: < in this case you are editing a pre-numbered block >
So, the first character is or was "-"
concatenate the required number with the value and replace attribute with the NEW value.

repeat ...


at least this way your sub-component identifier "combo" will be consistant for each insertion of similar blocks.
« Last Edit: January 30, 2006, 10:41:15 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #2 on: January 30, 2006, 10:48:04 PM »
There is another way, provided you are sure the "combo" will be maintained long term ...

Name the Attribute TAGS with the unique "COMBO"
ie :
A-1
A-2
B-13
.. etc < whatever >

Then
As your routine changes the attribute values, just read the TAG name, concatenate your number, and use that value for the attribute
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #3 on: January 30, 2006, 10:53:42 PM »
Thinking about it seriously .. The second alternative would be cleaner, and still allow automated editing of pre-numbered attributes.

Once you decide, it's only about 15 minutes work to write that ...
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #4 on: January 30, 2006, 11:28:39 PM »
Forgot, It's almost midnight over there ..

I'll pretend you said "go ahead" 

BRB ..
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #5 on: January 30, 2006, 11:52:29 PM »
Try something like this perhaps ..
Code: [Select]
(defun c:test (/ ATTRIB BLOCKOBJECT PREFIXNUMBER TAG VAL catchit)
  ;;
  ;; kwb@TheSwamp
  ;;
  ;;
  (while (and (setq blockObject (vlax-ename->vla-object (car (entsel))))
              (not (vl-catch-all-error-p
                     (setq catchit (vl-catch-all-apply 'vlax-invoke
                                                       (list blockObject 'GetAttributes)
                                   )
                     )
                   )
              )
              (setq PrefixNumber (getint "Prefix Number"))
         )
    (mapcar '(lambda (Attrib)
               (setq Tag (vla-get-tagstring Attrib)
                     Val (strcat (itoa PrefixNumber) "-" Tag)
               )
               (vla-put-textstring Attrib Val)
             )
            catchit
    )
    (vla-update blockObject)
  )
  (princ)
)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Cad64

  • Guest
Re: Multiple attribute edit
« Reply #6 on: January 31, 2006, 12:11:10 AM »
Kerry,
Sorry I didn't reply before. I was away from my computer. I just tried your program and it worked like a charm. That's exactly what I was looking for. Thank you so much. Where did you learn to write code? I've been trying to teach myself, but it's very slow going. At the moment I can only write simple programs. Hopefully one day I'll be able to get my head around this stuff.
Thanks again.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #7 on: January 31, 2006, 12:23:10 AM »
Kerry,
...... Where did you learn to write code? ....

Self taught before there was an internet as we know it.  Lots of practice,  and lots of key thumping.


added : .. and you're welcome   :-)
« Last Edit: January 31, 2006, 12:30:40 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Multiple attribute edit
« Reply #8 on: January 31, 2006, 02:56:50 PM »
Here is an alternative.
This routine will replace the prefix. Anything before the first "-"
with the user entered prefix.
If the "-" is missing an error message is displayed.
If the text starts with "-" the prefix is added.
Remembers the previous prefix entered in this session.


Code: [Select]
Command: ATTRUPDATE

Input New Prefix: <100>500

Select Block to update...
Select objects:

Error, attribute missing '-'.

Code: [Select]
100-A-1  -->  500-A-1
100-B-1  -->  500-B-1
3-C-1    -->  500-C-1
-D-1     -->  500-D-1
ABCD     -->  Error message


Code: [Select]
(defun c:attrupdate (/ ss oblock tmp attributelist pos)
  (or prefix (setq prefix "100"))
  (setq val (getstring (strcat "\nInput New Prefix: <" prefix ">")))
  (if (or (null val) (= val ""))
    (setq val prefix)
    (setq prefix val)
  )

  (princ "\nSelect Block to update...")
  (setq ss (ssget ":S" (list (cons 0 "INSERT") '(66 . 1))))

  (if ss
    (progn
      (setq oblock (vlax-ename->vla-object (ssname ss 0)))
      (if (= (vla-get-hasattributes oblock) :vlax-true)
        (progn
          (setq attributelist (vlax-safearray->list (variant-value (vla-getattributes oblock))))
          (foreach attrib attributelist
            (setq tmp (vla-get-textstring attrib)
                  pos (vl-string-position 45 tmp) ; find the "-"
            )
            (if pos
              (progn
                (setq tmp (vl-string-subst prefix (substr tmp 1 pos) tmp))
                (vla-put-textstring attrib tmp)
              )
              (prompt "\nError, attribute missing '-'.")
            )

          )
        )
      )
    )
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Cad64

  • Guest
Re: Multiple attribute edit
« Reply #9 on: January 31, 2006, 09:42:10 PM »
Thanks Cab. I like this version better because it remembers the last number input, in case I forget. This program is going to save me hours of tedious computer time on big drawings. There is only one more thing needed to make this program perfect. I have another attribute in each block that needs to update along with the others. It is the block number. If the individual attributes are 100-A-1, etc. then the block number would be 100 with no extension. Is there a way to update that one attribute independent from the others? Maybe when I create the block, I could choose that attribute first so it's at the top of the list, then the program could somehow isolate it and update it separately? That would be awesome. Otherwise it's still a great program. Thanks guys.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Multiple attribute edit
« Reply #10 on: January 31, 2006, 09:54:28 PM »
just test for the tagstring name of the attribute and ignore it or treat it differently.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Multiple attribute edit
« Reply #11 on: January 31, 2006, 09:59:35 PM »
Well you could replace the error message with code to replace the text in that attribute.
Be aware that there is little error checking.
So it will work like this.

Code: [Select]
100-A-1  -->  500-A-1
100-B-1  -->  500-B-1
3-C-1    -->  500-C-1
-D-1     -->  500-D-1
100      -->  500
Code: [Select]
(defun c:attrupdate (/ ss oblock tmp attributelist pos)
  (or prefix (setq prefix "100"))
  (setq val (getstring (strcat "\nInput New Prefix: <" prefix ">")))
  (if (or (null val) (= val ""))
    (setq val prefix)
    (setq prefix val)
  )

  (princ "\nSelect Block to update...")
  (setq ss (ssget ":S" (list (cons 0 "INSERT") '(66 . 1))))

  (if ss
    (progn
      (setq oblock (vlax-ename->vla-object (ssname ss 0)))
      (if (= (vla-get-hasattributes oblock) :vlax-true)
        (progn
          (setq attributelist (vlax-safearray->list (variant-value (vla-getattributes oblock))))
          (foreach attrib attributelist
            (setq tmp (vla-get-textstring attrib)
                  pos (vl-string-position 45 tmp) ; find the "-"
            )
            (if pos
              (progn
                (setq tmp (vl-string-subst prefix (substr tmp 1 pos) tmp))
                (vla-put-textstring attrib tmp)
              )
              ;;(prompt "\nError, attribute missing '-'.")
              (vla-put-textstring attrib prefix)
            )

          )
        )
      )
    )
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Multiple attribute edit
« Reply #12 on: January 31, 2006, 11:30:30 PM »
Just to clarify, this lisp does not discriminate between attribute tags.
it looks at the text value. If there is no "-" within the text string
the text string is replaced withe the user entered text. If it finds a "-"
any text before the "-" is replaced with the user entered text.

If there are instances where the "-" is not in the correct attribute the
perhaps the tag, as Kerry suggested, should be tested to assure the proper
placement. But if you are sure of the block data, then no need.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Cad64

  • Guest
Re: Multiple attribute edit
« Reply #13 on: February 01, 2006, 12:28:21 AM »
It works perfectly. This program is gonna make my life a whole lot easier. Thanks for all your help guys.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Multiple attribute edit
« Reply #14 on: February 01, 2006, 08:33:13 AM »
Glad it will work for you.
Here is a cleaned up version.
Code: [Select]
(defun c:attrupdate (/ ss BlkObj tmpStr pos val)
  (vl-load-com)
  (or *prefix* (setq *prefix* "100"))
  (setq val (getstring (strcat "\nInput New *prefix*: <" *prefix* ">")))
  (if (or (null val) (= val ""))
    (setq val *prefix*)
    (setq *prefix* val)
  )
  (princ "\nSelect Block to update...") ; only blocks with attributes
  (if (setq ss (ssget ":S" (list (cons 0 "INSERT") '(66 . 1))))
    (progn
      (setq BlkObj (vlax-ename->vla-object (ssname ss 0)))
      (foreach attrib (vlax-safearray->list (variant-value (vla-getattributes BlkObj)))
        (setq tmpStr (vla-get-textstring attrib)
              pos (vl-string-position 45 tmpStr) ; find the "-"
        )
        (if pos
          (progn
            (setq tmpStr (vl-string-subst *prefix* (substr tmpStr 1 pos) tmpStr))
            (vla-put-textstring attrib tmpStr)
          )
          (vla-put-textstring attrib *prefix*)
        )
      )
    )
  )
  (princ)
)
(prompt "\nAttribute Updater loaded, Enter AttrUpdate to run.")
(princ)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.