• This forum is the machine-generated translation of www.cad3d.it/forum1 - the Italian design community. Several terms are not translated correctly.

Add value to block attribute

  • Thread starter Thread starter Cristallo
  • Start date Start date

Cristallo

Guest
Then, I started the embol and would like to write a routine that selected a set of blocks (which contain an altimetric quota in the form of an attribute value) can add/subtract a specific delta.
the idea is simple, a kind of addval already present on the site, but that acts on the values of attributes.

but I clashed with acad already at the first step, that is to get the value of the attribute contained in the block.
I get the block list, I get the sub entities, I see them all (all this in command line so if present I see what I am looking for), but in no way I can find a group that contains the current value of the attribute.

Does anyone give me a tip?
 
Enter the block name and label name in the variables at first.
Code:
(defun c:cambiaquota (nb ne blk n listed option)

(setq nb “quota”)
(setq ne “altim”)

(vla-startundomark (vla-get-activedocument))
(ii) (and
(Princ "Nselezionare in Blucochi Da modificare")
(setq blk (ssget (list '(0. "insert") (cons 2 nb))))
(Setq delta)
(Getdist (strcat "ndelta quota" (if delta (strcat "<" (rtos delta 2 2)">: ")")))))))
(to participate)
) )
)
(repeat (setq n)
(setq bl (ssname blk)
(foreach listed (vlax-invoke (vlax-ename->vla-object bl) 'getattributes')
(if (strcase (vla-get-tagstring listed))
(progn
(setq attval (+ (atof (vla-get texting listed)))
(vla-put text string listed (rtos selection 2 (getvar ‘luprec))))
)
)
)
)
)
(vla-endundomark (vla-get-activedocument))
(Princ)
)
 
What are we talking about? I can only thank you here.
Obviously your code does exactly what I was looking for, now I just have to apply a little to refine it.
Thanks again.
 
Please:

if you prefer in vanilla the loop on the individual blocks you could set like this:
Code:
 (repeat (ssslength blk))
(setq bl (ssname blk (setq n (1-n)))))
(if (setq ent1)
(while (= (cdr (assoc 0) "attrib")
(if (= (strcase (cdr (assoc 2)) ne)
(progn)
(setq attval (cdr (assoc 1)))
(setq newattval (rtos (+ (atof attval) delta) 2 (getvar 'luprec))))
(entmod (subst (cons 1 newattval) (assoc 1 (entget ent1))
)
)
(setq ent1 (entnext ent1))
)
)
)
 
other thing, if you don't want to limit the lisp to only one block name, you can select them with a filter on the dxf 66

(ssget "x"(0 . "insert") (66 .1))

if the value is 1 the insert entity is followed by a series of attrib entities, which end with a seqend entity.
:smile:
 
So... .
I took the block name (poor flexible to indicate it in the list) by a simple association to group 2(setq nb (cdr (assoc '2 (entget (car (entsel " select one of the blocks to update: ")))))Now, if you want to get the tag of the only attribute in the block?
Damn attributes, I hide well!
 
if the block has attributes this fragment returns the name of the label and the value of the cousin attribute.

(setq bl (car (entsel "select one of the blocks to update: ")
(setq ent1 (entget (entnext (cdr)))))
(setq label (cdr (assoc 2 ent1))
(setq value (cdr (assoc 1 ent1))
 
always on the piece. It works great and the fact that you split it into multiple steps allows me to reason on another aspect, namely that if the value of the attribute has other characters beyond the numeretto of the quota I can stralciate them before and rebuild them after (a thing like "-5.70 q.p.f.") or even choose to skip that entity.

just for my culture, if I repeat the entroxt, I move to the next attribute, until I meet a sequend?
 
So... .
starting from the "gp" I fixed a bit the list and now the lisp adds/sottrae a delta from a block with single attribute, keeping a possible text following the quota.
for example two blocks containing "3.50" and "-3.50 estradosso", adding a delta of 0.30 will be "3.80" and "-3.20 estradosso".
the selection of the blocks on which to operate takes place by means of pick of the block (it is the lisp to get the block name and tag of the attribute) and then on the selection of the blocks to be changed (the lisp selects only those satisfying the requirements of the previous pick).

All right, now the painful notes.

in version 3 everything works well, but if you select a dynamic block the result of the block name will be * uetc (the dynamic blocks are like this) and obviously there will be no selection to apply the delta.
in version 4 I solved, adding recovery ofeffective name of the anonymous block, but when I go to select with ssget there is no block that respects the ssget condition: and by force! I select maybe a block named "planiquo", the lisp finds a tide of blocks called "*uetc"
how do I select a dynamic block, but that respects the conditions of the dynamic block chosen with the pick?

do not mind the fact that the variables remain full after the execution of the lisp, being in the embryonic phase I left it so to have the value of the variables at the time of the crash.
 

Attachments

Code:
;capture all blocks
(setq blk1 (ssget "_x" ((0 . "insert")))))

;initializes the selection group blk
(setq blk (ssadd))

;loop on all blocks: if the actual name corresponds to the desired one (nb) adds the block to blk
(repeat (setq n (sslength blk1))
(if (= nb (vlax-get-property (vlax-ename->vla-object (setq b (ssname blk1 (setq n (1- n)))))) (effectivename)))
(setq blk (ssadd blk))
)
)
 
intelligently simple solution to a seemingly insurmountable problem.
Of course it works, although it seems that I had some trouble going from anonymous to normal, but I'm going to love it.
 
with 'effectivename should be influential the type of block.
I thought so, too. but at the second cycle (with other block) the selection blk1 remained empty despite nb (block name) was correct.
I thought it was a matter of emptying some variables (which in the draft stage are not reset), but I couldn't delve into it for time.

I'm asking you a new question. We admit that the value of the attribute does not start for a number, but there is an initial string, like "quota 11.23" and we say that the check to var. value.
in this case all the lisp goes into crisis.
I tried to isolate the only initial part by (read value) and correctly returns me share, but if I try to replace it in the string (setq value2 (subst ")) it returns me error.
investigating the read result sees it as sym and not as string, so the subst does not go.
is there any way to change the type of data you read?
 
starting from(setq valore "quota 11.23");imposed to 0 string character counter(setq n 0);track all characters until you find a number (*), the value of n then locks on the number that matches the position in the string))))
(setq v1 (substr valore 1 (1-n))) -> rest "quota"
(setq v2 (substr valore n (strlen valore)) -> rest "11.23"change the value of v2 and then with(setq valorre (strcat v1 v2)) restore the attribute string.


(*) i caratteri ascii 48 to 57 are numbers.
 
guazie of explanations. I had imagined that from the top of your magheggi there was a simpler way, instead you have to run all the string character by character.
But that's okay.
 

Forum statistics

Threads
44,997
Messages
339,767
Members
4
Latest member
ibt

Members online

No members online now.
Back
Top