Aftertouch 发表于 2022-7-5 16:23:52

Change order of Entities (crea

Hello again everybody,
 
got myself yet another challenge...
 
I got a drawing with three same blocks with attributes, wich get nummbers automaticaly.
 
Can look like:
First block att: 1001
Second block att: 1002
Third block att: 1003
etc.
 
Now i want to add a fourth block between block 1 and 2, so give it number 1003, and make the current 3th block the fourth block...
So the command needs me to select the 'second' block, and place the new block 'after' it.
 
But when i add the new block, its defined as the last made block, so it just gets the number 1004.
 
So... how can i place a new entity between the 2nd and 3th entitie... (so the 3th actualy becomes the fourth???...
 
EDIT:
My quick and dirty solution:

(defun PUNTENTUSSENVOEGEN ( hoogstepuntnummer huidigelayer / )(setq blockgroepselecteren (car (entsel "\nSelecteer het bestaand punt om een punt vóór te zetten..."))) ;SELECT LAST TO KEEP POINT (point 2nd in example)(cond        ((= blockgroepselecteren nil)                (princ "\nGeen selectie.")        )        ((AND (= "INSERT" (cdr (assoc 0 (entget blockgroepselecteren))))(= "GEO_Uitzetpunt" (cdr (assoc 2 (entget blockgroepselecteren)))))        (setq tussenpuntnummer (LM:getattributevalue blockgroepselecteren "$NUMMER" ))        (setq tussenpuntnummer (- (atoi tussenpuntnummer) 1))        (setq blockgroepselecteren (entget blockgroepselecteren))        (setq huidigelayer (cdr (assoc 8 blockgroepselecteren)))        (setq plaatspunt (getpoint (strcat "\nUitzetpunt plaatsen :")))        (command "_insert" "G:\\CAD\\AutoDesk\\06-Landmeten\\GEO_Uitzetpunt.dwg" plaatspunt "1" "1" "" tussenpuntnummer) ;PLACE NEW THIRD                (setq blockgroepselecteren (SelectBlockIfAttInRange "GEO_Uitzetpunt" "$NUMMER" tussenpuntnummer. 9999.)) ;GET CURRENT THIRD AND ALL HIGHER NUMBERS        (command "_COPYBASE" "0,0" blockgroepselecteren "") ;COPY THEM        (command "_ERASE" blockgroepselecteren "") ;DELETETHEM        (command "_PASTECLIP" "0,0") ; REMAKE THEM        (setq nieuweblockgroep (ssget "_X" (list (cons 0 "INSERT")(cons 2 "GEO_Uitzetpunt")(cons 8 huidigelayer)))) ;GET NEW SELECTION        (PUNTENHERNUMMEREN nieuweblockgroep huidigelayer) ;RENUMBER ALL        (setvar "CLAYER" huidigelayer)        )        (t                (princ "\nOngeldige selectie.")        )))
 
I think the copy-past methode is not the most clean way possible...

Grrr 发表于 2022-7-5 16:36:00

You can't change the creation order - that means modifying the handles of the blocks which is impossible.
But you can construct a sorted list of ( . ) thats being used by object and insert reactor,
so everytime you change the attribute value / insert or copy by that particular block name the reactor would readjust the attribute values.
And theres also this.
 
The other way would be to recreate the objects like you mentioned - but still requires checking of the last created entity, and whats the attrib value it holds.

BIGAL 发表于 2022-7-5 16:52:13

A non reactor would be to do a insert block but before inserting ask for a number like 3 then ssget all the blocks and either if =>3 add 1 to attribute then insert new block with attribute = 3.
 
This could be done as a more global routine, pick an existing block, using a dialouge pick correct attribute and enter attribute value to start at. Now that I think about it may have been asked before. I know I did the attribute pick from list bit recently.
 

; do this first(setq nieuweblockgroep (ssget "_X" (list (cons 0 "INSERT")(cons 2 "GEO_Uitzetpunt")(cons 8 huidigelayer)))); repeat etc add 1; Insert block with correct att.

BIGAL 发表于 2022-7-5 16:57:45

Had a play this seems to work its version 1 its a global routine rather than just 1 block name. A lowest & highest value can be added pretty easy.
 

; adds a value to an existing attribute across multiple blocks like an insert and update.; based on a lower range value; by Alan H May 2017(defun attinc ( / obj lst objname x tag1 att rtn )(setq obj (vlax-ename->vla-object (car (entsel "\nPick block"))))(setq objname (vla-get-name obj))(setq lst '())(foreach att (vlax-invoke obj 'getattributes)(setq lst (cons (vla-get-tagstring att) lst)))(if (not listbox)(load "listbox"))(listbox lst)(setq tag1 rtn)(setq ss (ssget "x" (list (cons 0 "Insert")(cons 2 objname))))(setq newnum (getint "Enter new number"))(repeat (setq x (sslength ss))(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (1- x)) )) 'getattributes)(if (= tag1 (strcase (vla-get-tagstring att)))(progn (setq ans (atoi (vla-get-textstring att))) (if (>= ans newnum)(setq ans (+ ans 1)))(vla-put-textstring att (rtos ans 2 0)))   )))) ;defun(attinc); now do your insert thing for a new block

; this is hardcoded for directory c:\acadtemp change to suit; uses listbox.dcl; returns the list item value(defun listbox (lst ) ;(setq lst (list "150" "200" "225" "250" "300" "375" "450" "600")) (setq dcl_id (load_dialog "c:\\acadtemp\\listbox.dcl")) (if (not (new_dialog "listbox" dcl_id))   (exit) ) (start_list "list") (foreach itm lst (add_list itm)) (end_list);(setq rtn (set_tile "list" "0"))(set_tile "list" "0")(action_tile "list" "(setq rtn (nth (atoi $value) lst))") (start_dialog) (unload_dialog dcl_id))

listbox : dialog {                                //dialog name      label = "List box pick an item" ;      //give it a label      : row {                                //define row             spacer;      :list_box {key="list";      multiple_select=false;      width=20;      height=10;      }                              //end list box      }                              //end row             ok_cancel ;                        //predifined OK/Cancel }

Aftertouch 发表于 2022-7-5 17:13:29

Hey Bigal, thanks al lot for thinking with me. And your code'll work in this situattion. Altho... i also have a routine that renumbers all blocks with the attribute. I use that when when i deleted multiple points between the first and last point. It than renumbers all attributes in, you gues it.. the creation order. So you method works,but clashes with the other functions i have. So i realy need to have control of the creation order. :-)
 
Thanks alot for your imput tho! :-)

Grrr 发表于 2022-7-5 17:20:51

Interesting suggestion BIGAL,
I think that this modification may be more effective:
 

; Increment Attribute with grread - Grrr(defun C:test ( / e enx n tag b bnm SS mv i o grr Stop m ) (and   (setq e (car (nentselp "\nPick numerical attribute from block: ")))   (setq enx (entget e)) (member '(0 . "ATTRIB") enx) (numberp (setq n (read (cdr (assoc 1 enx))))) (setq tag (cdr (assoc 2 enx)))   (setq b (cdr (assoc 330 enx))) (setq bnm (vla-get-EffectiveName (vlax-ename->vla-object b)))   (setq SS (ssget "X" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," bnm)) '(66 . 1))))   (setq mv (progn (initget "Below Above") (eval (cadr (assoc (cond ((getkword "\nModify values : ")) ("Above")) '(("Below" ))))) ) )   (princ "\nPress [+/-] to increment/decrement the values: ")   (while (not Stop) (setq grr (grread T))           (cond       ( (or (eq grr '(2 13)) (member (car grr) '(25 3))) (setq Stop T) )       ( (and (= (car grr) 2) (setq m (eval (cadr (assoc (cadr grr) '((43 1+) (45 1-)))))))         (repeat (setq i (sslength SS))         (cond ( (not (eq bnm (vla-get-EffectiveName (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i)))))))) )             (               (vl-some                  (function                  (lambda (x / v)                     (and (eq tag (vla-get-TagString x)) (numberp (setq v (read (vla-get-TextString x))))                     (mv v n); _$ (>= 3 2) -> T                     (setq v (m v))                     (progn (vla-put-TextString x (vl-prin1-to-string v)) T)                     ); and                     ); lambda (x)               ); function               (vlax-invoke o 'GetAttributes)               ); mapcar             )         ); cond          ); repeat       )   ); cond   ); while ); and (princ)); defun
 
But I'd advise first to do some tests with the above code (because for example if you increment too much - up to the value's limit the values would stack).
For instance decrement too much from number 3 the values above (5 6 7 8...)
by pressing "-" they'll all become (3 3 3 3...) therefore no fix for this.

BIGAL 发表于 2022-7-5 17:33:51

Nice one Grr I crashed 1st time then realised pick correct attribute. Using nentsel makes sense to, removing the need for a list select function. I found the same got two attributes with same value.
 
Back to aftertouch the one way I can think off to make the blocks in a continuous order for selection from the database would be to erase and recreate in numerical order. The other is just make a list with the blocks in there correct numerical order but save the entity names ((1002 7ff7893496c0)(1003 7ff789349a80) ..... "sort list on attribute value"
页: [1]
查看完整版本: Change order of Entities (crea