So, in scouring the webs today in search of finding a routine that will do what I am trying to accomplish, i've had little luck.
Best I've found was a program written by Lee Mac that bumps attributes using grread. Great work, very nicely done and works properly, but not for our purposes. See, what we've been doing when an issue goes out with 100+ isometrics or so in it is to use (again) Lee Mac's global attribute editor. The program works amazingly and saves us alot of time.
We've noticed a case that requires us to reinject more time into modifying these attributes, and I'll describe it here...
For whatever reason, one of a set of drawings may be a different revision than the next, and the next. These drawings will be either bumped to the same revision number/letter for all the drawings in the issue, or alternatively, each drawing would have it's revision bumped up once, so A becomes B......2 becomes 3.....E becomes F....and so on and so on.
The global attribute editor from Lee can handle all of this quite well, as well as it can being a program and not a human, and I'm not counting on a program being able to recognize characters in order to 'rev-up' properly, that's crossing the line between human-operated and program-ran tasks. I'm fine with that, a certain amount of oversight is required here to do the revisions correctly.
What would be great though is if there was a method to force an inputted attribute string to the first of available attribute fields, i.e. "on the next line".
I'll post a few .dwgs to describe what i'm talking about, and hope that someone knows if this is possible to be coded or not
Hi Brandon,
If I have correctly understood your intentions, consider the following function:
(defun attbump ( blk tag lst / idx obj sel upp ) (setq blk (strcase blk) tag (strcase tag) upp (mapcar 'strcase lst) ) (if (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (strcat "`*U*," blk))))) (repeat (setq idx (sslength sel)) (if (= blk (strcase (LM:blockname (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))))) (vl-some '(lambda ( att / pos ) (if (setq pos (vl-position (strcase (vla-get-textstring att)) upp)) (progn (vla-put-textstring att (nth (rem (1+ pos) (length lst)) lst)) t) ) ) (vlax-invoke obj 'getattributes) ) ) ) ) (princ) ) ;; Block Name - Lee Mac ;; Returns the true (effective) name of a supplied block reference (defun LM:blockname ( obj ) (if (vlax-property-available-p obj 'effectivename) (defun LM:blockname ( obj ) (vla-get-effectivename obj)) (defun LM:blockname ( obj ) (vla-get-name obj)) ) (LM:blockname obj) ) (vl-load-com) (princ)
Usage:
(attbump "block" "tag" '("A" "B" "C" "1" "2" "3"))
Hey Lee-
It's lunchtime, but I just got giddy to know you've put something there for me when I return.
Thanks, i'll reply to this thread once I get back and check it out
You rock!
Cheers Brandon - bon appétit!
Having some trouble in understanding what the list argument is for, but this should help with the block tag names.
For clarification:
Basically what I'm needing here is the ability to take the values from R#DATE, R#CHK, R#BY, R#DESC, REV# tags where # is whichever revision tag is misplaced (will not be static) , and to move ALL of the values to the corresponding tags but with another #. What this would do is 'bump' the entire line of revision information to another slot of attributes within the same block. Unfortunately the block has other attributes in it that do not contain revision information and thusly are located on the other end of the same block, but they do take up places in the block attribute list. If the program could be supplied those tag strings but with a wildcard in place of the actual #, with a getstring asking for user input to fill the "attribute line to be moved" that would replace the wildcard after obtaining the input with the # then the actual tag names would be contained in variables.
(setq num (getint "/nAttribute line to be moved:"))
(setq rdate R*DATE)
(setq rchk R*CHK)
(setq rby R*BY)
(setq rdesc R*DESC)
(setq rev REV*)
(setq $rdatepre (substr 'rdate 1 1))
(setq $rdatesuf (substr 'rdate 3 4))
(setq new_rdate (strcat $rdatepre num $rdatesuf))
If my thinking here is correct....
The same technique could then be used for obtaining the "position to be moved to" and from there the tags could be swapped. This would work for when there is existing text within the position to be moved to or blank values as placeholders.
I think my purposes and the purposes of the program you've written might be misaligned, either that or I'm failing to use it correctly. Step 1, reply with this information!
as a sidenote, i very seriously doubt your program is malfunctioning. It's loading properly and not giving any errors. I think it's something I'm failing to understand, but for my testing this is what i've shown, as illustrated below
then after <enter>
and after <enter> again
if i'm using this incorrectly as i suspect then i apologize for my ignorance, hopefully it can do what i need just with a different syntax!
images attached now for actual viewing possibility, but hopefully this one shows now
realized that this may be a better way to go about it.
(setq num (getint "/nAttribute line to be moved"))
(setq rdate (strcat "R" num "DATE"))
(setq rchk (strcat "R" num "CHK"))
(setq rby (strcat "R" num "BY"))
(setq rdesc (strcat "R" num "DESC"))
(setq rev (strcat "REV" num)
i can see that i've opened a whole new can of worms with this one....
i'll be busy, good to learn attribute functions anyways
Found a routine on the swamp to accomplish what I was attempting.
This allows me to do a pickbox over the rectangular line of attributes then specify a distance of 0.25 and bam, entire line of atts moved up/down depending on dist given.
Pretty nifty, now it's time to play.
****, no.
that moves the tag values to the correct positions within the block
but does not take the values from rev# and store them then place into tag rev# of a different number...
back to it, then
Hi Brandon,
To explain: I initially thought you were looking to update the attribute values based on their current content, i.e. if the attribute had a content of 'A', the attribute would be updated with a value of 'B' - this was the purpose of the lst argument: to indicate the values that the attributes should use based upon their current values.
Therefore, by calling the function in the following way:
(attbump "block" "tag" '("A" "B" "C" "1" "2" "3"))
For every block with block name 'block', if the block contains an attribute with tag name 'tag', the attribute value will be altered based on the values in the given list. Hence, if the attribute has value 'B', it will be changed to 'C'; similarly, a value of 'C' would be changed to '1'.