Jump to content
stusic

LISP to Increment Unique Attributes?

Recommended Posts

stusic

Hello Everyone!

 

As my first post I'm going to give a doozy. I've searched and searched, but can't find a lisp or info that helps me with my problem. Maybe I can find some help here - even though I've already turned grey, I'd still appreciate it.

 

So, here we go...

 

I insert attributed blocks into my drawings that list part number, model number, etc. Along with these attributes, there's another tag that is an incremental number (used in our Bill of Materials). If there are two identical parts (i.e., same model number), the incremental number needs to be the same; if the parts are different, the next sequential number needs to be used.

 

Doing this by hand is not only time-consuming, but tends to be extraordinarily erroneous. So I'm looking to make a lisp routine that I can run to auto-number these blocks. I'm thinking that I can insert my blocks (or re-use them, copy, etc.) without too much concern over the number tag, then run the lisp at the end to give the numbers to each unique block. It'd be nice if any numbers already there could stay the same (we re-use drawings all the time).

 

 

Block:

BOMTAG

Tags:

ITEM (Increment Number)

MODEL (Model Number)

PART (Part Number)

 

I don't know a ton of lisp, so I don't know that I can make it on my own, but maybe a nudge in the right direction could keep me from wasting a bunch of time. Any ideas?

 

Make a list of blocks, do something with them, give if-then statements, re-number if needed, move to next block. Easy to type, hard to program. Free rendering to anyone who gets the winning code.

 

Thanks so much, I appreciate any help.

 

-stu

Edited by stusic
grammar

Share this post


Link to post
Share on other sites
pBe

Welcome to the forum stu

 

what you're asking sounds easy enough to code, you want this to work only with BOMTAG block?

 

Is ITEM the first attribute of the block?

You import the blocks via Copy and Paste?

which means MODEL number alrady havea value, or

Insert a block wiht a constant attribute for MODEL tag?

Edited by pBe

Share this post


Link to post
Share on other sites
VVA

attach dwg file with example

Share this post


Link to post
Share on other sites
stusic

Thanks for the replies.

 

Only BOMTAG? Not exactly, there's nearly identical blocks called BOMTAG_TR, BOMTAG_T, BOMTAG_TL, BOMTAG_L, BOMTAG_BL, BOMTAG_B, BOMTAG_BR, BOMTAG_R. They're for leader lines coming off the block. I wouldn't do it that way if I had my choice.

 

Yes, ITEM is the first attribute, and they're normally already in there from another job (we copy a drawing over from another job and re-use). We'll just copy within the drawing, so all the tags are generally filled (some will remain empty forever because there is no exact model number) and no fields are constant.

 

Thanks again!

Share this post


Link to post
Share on other sites
pBe

So its copy and paste? or import from another drawing via "insert?

Share this post


Link to post
Share on other sites
Tharwat

Sometimes with an image would be much clearer than words , so if you upload an image showing before and after would be highly appreciated by all . :D

Share this post


Link to post
Share on other sites
Lee Mac

Hi stusic,

 

Firstly, welcome to CADTutor :)

 

If I've understood correctly (and have used the correct attribute tags as you described), try the following:

 

[color=GREEN];; Dependent Attribute Numbering  -  Lee Mac  -  2011  -  www.lee-mac.com[/color]
[color=GREEN];; Assigns a number to a specific attribute whose 'dependent' attribute is[/color]
[color=GREEN];; the same for all attributes with the same number.[/color]

([color=BLUE]defun[/color] c:AttNum ( [color=BLUE]/[/color] att blk dep inc itm lst num obj sel tmp val )

   ([color=BLUE]setq[/color] blk [color=MAROON]"BOMTAG"[/color] [color=GREEN];; Block Name[/color]
         num [color=MAROON]"ITEM"[/color]   [color=GREEN];; Numbering Tag[/color]
         dep [color=MAROON]"MODEL"[/color]  [color=GREEN];; Numbering Dependent Tag[/color]
   )
   ([color=BLUE]mapcar[/color] '[color=BLUE]set[/color] '(blk num dep) ([color=BLUE]mapcar[/color] '[color=BLUE]strcase[/color] ([color=BLUE]list[/color] blk num dep)))

   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] sel
           ([color=BLUE]ssget[/color] [color=MAROON]"_X"[/color]
               ([color=BLUE]list[/color]
                  '(0 . [color=MAROON]"INSERT"[/color])
                  '(66 . 1)
                   ([color=BLUE]cons[/color] 2 ([color=BLUE]strcat[/color] [color=MAROON]"`*U*,"[/color] blk))
                   ([color=BLUE]cons[/color] 410 ([color=BLUE]getvar[/color] 'CTAB))
               )
           )
       )
       ([color=BLUE]progn[/color]
           ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] inc ([color=BLUE]sslength[/color] sel))
               ([color=BLUE]setq[/color] obj ([color=BLUE]vlax-ename->vla-object[/color] ([color=BLUE]ssname[/color] sel ([color=BLUE]setq[/color] inc ([color=BLUE]1-[/color] inc)))))
               ([color=BLUE]if[/color]
                   ([color=BLUE]or[/color]
                       ([color=BLUE]null[/color] ([color=BLUE]vlax-property-available-p[/color] obj 'effectivename))
                       ([color=BLUE]eq[/color] blk ([color=BLUE]strcase[/color] ([color=BLUE]vla-get-effectivename[/color] obj)))
                   )
                   ([color=BLUE]progn[/color]
                       ([color=BLUE]setq[/color] tmp
                           ([color=BLUE]mapcar[/color]
                               ([color=BLUE]function[/color]
                                   ([color=BLUE]lambda[/color] ( att )
                                       ([color=BLUE]cons[/color] ([color=BLUE]strcase[/color] ([color=BLUE]vla-get-tagstring[/color] att)) att)
                                   )
                               )
                               ([color=BLUE]vlax-invoke[/color] obj 'getattributes)
                           )
                       )
                       ([color=BLUE]if[/color]
                           ([color=BLUE]and[/color]
                               ([color=BLUE]setq[/color] val ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] dep tmp)))
                               ([color=BLUE]setq[/color] val ([color=BLUE]vla-get-textstring[/color] val))
                               ([color=BLUE]setq[/color] att ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] num tmp)))
                           )                            
                           ([color=BLUE]if[/color] ([color=BLUE]setq[/color] itm ([color=BLUE]assoc[/color] val lst))
                               ([color=BLUE]setq[/color] lst ([color=BLUE]subst[/color] ([color=BLUE]vl-list*[/color] val att ([color=BLUE]cdr[/color] itm)) itm lst))
                               ([color=BLUE]setq[/color] lst ([color=BLUE]cons[/color]  ([color=BLUE]list[/color] val att) lst))
                           )
                       )
                   )
               )
           )
           ([color=BLUE]setq[/color] inc 1)
           ([color=BLUE]foreach[/color] grp ([color=BLUE]vl-sort[/color] lst ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( a b ) ([color=BLUE]<[/color] ([color=BLUE]car[/color] a) ([color=BLUE]car[/color] b)))))
               ([color=BLUE]foreach[/color] att ([color=BLUE]cdr[/color] grp)
                   ([color=BLUE]vla-put-textstring[/color] att ([color=BLUE]itoa[/color] inc))
               )
               ([color=BLUE]setq[/color] inc ([color=BLUE]1+[/color] inc))
           )
       )
       ([color=BLUE]princ[/color] ([color=BLUE]strcat[/color] [color=MAROON]"\nNo "[/color] blk [color=MAROON]" blocks found in this layout."[/color]))
   )
   ([color=BLUE]princ[/color])
)
([color=blue]vl-load-com[/color]) ([color=blue]princ[/color])

Share this post


Link to post
Share on other sites
Lee Mac

FYI: to apply my above program to all blocks beginning "BOMTAG", change the block name at the top of the code to "BOMTAG*"

Share this post


Link to post
Share on other sites
pBe

(defun  c:IBN (/ aDoc bn n Modnum mn ss ib num lst)
 (defun _GetAttributes (ent)
   (mapcar
     (function
       (lambda (j)
         (list (vla-get-tagstring j) (vla-get-textstring j) j)
         )
       )
     (vlax-invoke ent 'GetAttributes)
     )
   )
 (vl-load-com)
 (setq  aDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
 (if
   (and
     (ssget "_X" '((0 . "INSERT")(2 . "BOMTAG*")))
     (progn
       (vlax-for
          itm (setq ss (vla-get-ActiveSelectionSet aDoc))
         (if (and
               (setq n (assoc "MODEL" (setq Modnum (_GetAttributes itm)))
                 )
               (not (assoc (setq mn (cadr n)) lst))
               )
           (setq lst (cons (list mn (atoi (cadar Modnum))) lst))
           )
         )
       (vla-delete ss)
       (command "_pasteclip" pause)
       (wcmatch (cdr (assoc 2 (entget (setq ib (entlast))))) "*BOMTAG*")
       )
     )
    (progn
      (setq num
         (assoc (cadr (assoc
               "MODEL"
               (setq ib (_GetAttributes (vlax-ename->vla-object ib)))
               )
             )
           lst
           )
        )
      (vla-put-textstring (last (assoc "ITEM" ib))
        (itoa
          (if num
            (cadr num)
            (1+ (apply 'max (mapcar 'cadr lst)))
            )
          )
        )
      )
    )
 (princ)
 )

 

If its cut and paste <_pasteclip>. only works with one block at a time though

Share this post


Link to post
Share on other sites
stusic

Attached is a horribly wonderful example of a typical drawing. The note bubbles (1, 2, 5, 8, & 30) are the blocks that contain the info that needs to change (BOM blocks are exactly identical to this situation, just with differing block names, since this is the uploaded drawing, I'll use these blocks as the example). 1 and 2 are different part/model numbers (hidden attributes), they therefore need different numbers in the note bubble. Aside from being out of sequence, both bubbles numbered 8 are correct, as they have identical part/model numbers. 5 and 30 however are incorrect, as they have different numbers, but identical part/model numbers. The lisp should leave 1, 2, and both 8's alone, and change 5 and 30 to the same number, preferably to 3 (if it's not used).

 

We'll use this drawing just about as-is. As new tags are needed, we'll copy an older tag (1, 2, 5, 8, or 30) and modify the attributes. Copy, yes, but solely inside of Autocad.

 

I really appreciate you guys' help!

Block Tag Example.dwg

Share this post


Link to post
Share on other sites
Lee Mac

Did you try my code Stusic?

Share this post


Link to post
Share on other sites
stusic

I meant to make tag 8 have different part numbers, but the same tag (item) number.

Share this post


Link to post
Share on other sites
Lee Mac
I did, it didnt' seem to do anything... :(

 

Btw, here's the correct example drawing

 

Looking at your drawing, none of the blocks have a "MODEL" attribute tag as you described?!? :?

 

If there are two identical parts (i.e., same model number), the incremental number needs to be the same; if the parts are different, the next sequential number needs to be used.

 

Block:

BOMTAG

Tags:

ITEM (Increment Number)

MODEL (Model Number)

PART (Part Number)

 

Also, I don't see a block called "BOMTAG" anywhere?!

Share this post


Link to post
Share on other sites
stusic

Yeah, I know. The easiest example was this drawing that uses a different block with different tags. The BOMTAG drawings aren't with me and this is the exact same situation. I replaced "BOMTAG" with "Balloon*" and "MODEL" with "PART_NUM" ("ITEM" stayed the same).

Share this post


Link to post
Share on other sites
Lee Mac

I see.

 

Try this instead:

 

[color=GREEN];; Dependent Attribute Numbering  -  Lee Mac  -  2011  -  www.lee-mac.com[/color]
[color=GREEN];; Assigns a number to a specific attribute whose 'dependent' attribute is[/color]
[color=GREEN];; the same for all attributes with the same number.[/color]

([color=BLUE]defun[/color] c:AttNum ( [color=BLUE]/[/color] att blk dep inc itm lst num obj sel tmp val )

   ([color=BLUE]setq[/color] blk [color=MAROON]"Balloon_*"[/color] [color=GREEN];; Block Name[/color]
         num [color=MAROON]"ITEM"[/color]      [color=GREEN];; Numbering Tag[/color]
         dep [color=MAROON]"PART_NUM"[/color]  [color=GREEN];; Numbering Dependent Tag[/color]
   )
   ([color=BLUE]mapcar[/color] '[color=BLUE]set[/color] '(blk num dep) ([color=BLUE]mapcar[/color] '[color=BLUE]strcase[/color] ([color=BLUE]list[/color] blk num dep)))

   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] sel
           ([color=BLUE]ssget[/color] [color=MAROON]"_X"[/color]
               ([color=BLUE]list[/color]
                  '(0 . [color=MAROON]"INSERT"[/color])
                  '(66 . 1)
                   ([color=BLUE]cons[/color] 2 ([color=BLUE]strcat[/color] [color=MAROON]"`*U*,"[/color] blk))
                   ([color=BLUE]cons[/color] 410 ([color=BLUE]getvar[/color] 'CTAB))
               )
           )
       )
       ([color=BLUE]progn[/color]
           ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] inc ([color=BLUE]sslength[/color] sel))
               ([color=BLUE]setq[/color] obj ([color=BLUE]vlax-ename->vla-object[/color] ([color=BLUE]ssname[/color] sel ([color=BLUE]setq[/color] inc ([color=BLUE]1-[/color] inc)))))
               ([color=BLUE]if[/color]
                   ([color=BLUE]or[/color]
                       ([color=BLUE]null[/color] ([color=BLUE]vlax-property-available-p[/color] obj 'effectivename))
                       ([color=BLUE]wcmatch[/color] ([color=BLUE]strcase[/color] ([color=BLUE]vla-get-effectivename[/color] obj)) blk)
                   )
                   ([color=BLUE]progn[/color]
                       ([color=BLUE]setq[/color] tmp
                           ([color=BLUE]mapcar[/color]
                               ([color=BLUE]function[/color]
                                   ([color=BLUE]lambda[/color] ( att )
                                       ([color=BLUE]cons[/color] ([color=BLUE]strcase[/color] ([color=BLUE]vla-get-tagstring[/color] att)) att)
                                   )
                               )
                               ([color=BLUE]vlax-invoke[/color] obj 'getattributes)
                           )
                       )
                       ([color=BLUE]if[/color]
                           ([color=BLUE]and[/color]
                               ([color=BLUE]setq[/color] val ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] dep tmp)))
                               ([color=BLUE]setq[/color] val ([color=BLUE]vla-get-textstring[/color] val))
                               ([color=BLUE]setq[/color] att ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] num tmp)))
                           )                            
                           ([color=BLUE]if[/color] ([color=BLUE]setq[/color] itm ([color=BLUE]assoc[/color] val lst))
                               ([color=BLUE]setq[/color] lst ([color=BLUE]subst[/color] ([color=BLUE]vl-list*[/color] val att ([color=BLUE]cdr[/color] itm)) itm lst))
                               ([color=BLUE]setq[/color] lst ([color=BLUE]cons[/color]  ([color=BLUE]list[/color] val att) lst))
                           )
                       )
                   )
               )
           )
           ([color=BLUE]setq[/color] inc 1)
           ([color=BLUE]foreach[/color] grp ([color=BLUE]vl-sort[/color] lst ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( a b ) ([color=BLUE]<[/color] ([color=BLUE]car[/color] a) ([color=BLUE]car[/color] b)))))
               ([color=BLUE]foreach[/color] att ([color=BLUE]cdr[/color] grp)
                   ([color=BLUE]vla-put-textstring[/color] att ([color=BLUE]itoa[/color] inc))
               )
               ([color=BLUE]setq[/color] inc ([color=BLUE]1+[/color] inc))
           )
       )
       ([color=BLUE]princ[/color] ([color=BLUE]strcat[/color] [color=MAROON]"\nNo "[/color] blk [color=MAROON]" blocks found in this layout."[/color]))
   )
   ([color=BLUE]princ[/color])
)
([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color])

Share this post


Link to post
Share on other sites
stusic

Sorry, I'm a tard. Changing things up at the last minute...

 

Block:

Balloon_* (with TL, TR, T, L, R, BL, BR, B)

 

Tags:

ITEM (Increment Number)

PART_NUM (Part/Model Number)

Share this post


Link to post
Share on other sites
stusic

Dude, I'll do a little more testing, but I think that got it. I want to swear in joyous delight. Thanks so much. You make it look so easy. What do you want a rendering of? :D

Share this post


Link to post
Share on other sites
Lee Mac
Dude, I'll do a little more testing, but I think that got it. I want to swear in joyous delight. Thanks so much. You make it look so easy. What do you want a rendering of? :D

 

lol Excellent mate, glad it works for you :)

Share this post


Link to post
Share on other sites
stusic

If you don't mind, one more quick question for you. I wanted to exclude the "COPPER" layer from the selection set, but adding (8 . "~COPPER") after ssget didn't seem to work. Any ideas?

 

Thanks a heap.

Share this post


Link to post
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
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

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