乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 56|回复: 6

[编程交流] Change order of Entities (crea

[复制链接]

76

主题

312

帖子

254

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
390
发表于 2022-7-5 16:23:52 | 显示全部楼层 |阅读模式
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:
  1. (defun PUNTENTUSSENVOEGEN ( hoogstepuntnummer huidigelayer / )(setq blockgroepselecteren (car (entsel "\nSelecteer het bestaand punt om een punt vóór te zetten..."))) [color="red"];SELECT LAST TO KEEP POINT (point 2nd in example)[/color](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) [color="red"];PLACE NEW THIRD[/color]                  (setq blockgroepselecteren (SelectBlockIfAttInRange "GEO_Uitzetpunt" "$NUMMER" tussenpuntnummer. 9999.)) [color="red"];GET CURRENT THIRD AND ALL HIGHER NUMBERS[/color]        (command "_COPYBASE" "0,0" blockgroepselecteren "") [color="red"];COPY THEM[/color]        (command "_ERASE" blockgroepselecteren "") [color="red"];DELETETHEM[/color]        (command "_PASTECLIP" "0,0") [color="red"]; REMAKE THEM[/color]        (setq nieuweblockgroep (ssget "_X" (list (cons 0 "INSERT")(cons 2 "GEO_Uitzetpunt")(cons 8 huidigelayer)))) [color="red"];GET NEW SELECTION[/color]        (PUNTENHERNUMMEREN nieuweblockgroep huidigelayer) [color="red"];RENUMBER ALL[/color]        (setvar "CLAYER" huidigelayer)        )        (t                (princ "\nOngeldige selectie.")        )))
 
I think the copy-past methode is not the most clean way possible...
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 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.
回复

使用道具 举报

106

主题

1万

帖子

101

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1299
发表于 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.
 
  1. ; 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.
回复

使用道具 举报

106

主题

1万

帖子

101

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1299
发表于 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.
 
  1. ; 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
  1. ; 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))
  1. 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 }
回复

使用道具 举报

76

主题

312

帖子

254

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
390
发表于 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! :-)
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 17:20:51 | 显示全部楼层
Interesting suggestion BIGAL,
I think that this modification may be more effective:
 
  1. ; 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 [below/Above] : ")) ("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.
回复

使用道具 举报

106

主题

1万

帖子

101

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1299
发表于 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"
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-7-9 19:34 , Processed in 0.465621 second(s), 66 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表