Lee Mac Posted February 17, 2009 Share Posted February 17, 2009 Hi Guys, Just a quick question, how can I retrieve all the entities that have been arrayed after performing an array? I thought a simple (entlast) would do the trick, but this only retrieves the first arrayed object. Any thoughts or ideas would be much appreciated. Thanks Lee Quote Link to comment Share on other sites More sharing options...
ASMI Posted February 17, 2009 Share Posted February 17, 2009 After _ARRAY command Store last entity before ARRAY command with (entlast) and use function like this to retrieve all new entities after command: (defun Ent_List_to_End(ent / a) (reverse (if(setq a(entnext ent)) (cons ent(Ent_List_to_End a)) ); end if ); end reverse ); Ent_List_to_End or inside SAFEARRAY use standard (vlax-safearray->list(vlax-variant->value safearray)) expression to transform array to list. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 17, 2009 Author Share Posted February 17, 2009 ASMI, many thanks for your code - it works well - although, for some reason 1 entity is left behind (but I may be using it wrong). I have arrayed two entities, a circle and a line. (command circle... (setq c1 (entlast)) (command line.... (setq l1 (entlast)) (command -array .... (setq ents (Ent_List_to_End l1)) would I need to array the entities separately? But it is weird because although I have only included the "line" entity in your code, all the arrayed circles are picked up too.. Could you please explain how your code works please? Thanks Lee Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 18, 2009 Author Share Posted February 18, 2009 Ahhh, I think I understand it now... after the entity has been arrayed, the arrayed entities are stored as sub-entities within the original entity. I understand that your LISP code returns a list of all the subentities contained within the original entity. - would I be somewhere near correct? So, I would understand it that this would only work if one entity were to be arrayed at a time. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 18, 2009 Author Share Posted February 18, 2009 I'm quite impressed to be honest, I would never have thought about nesting functions inside themselves... Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 18, 2009 Author Share Posted February 18, 2009 So would this also work? (defun get_array_ents (ent / ent eLst) (while (setq ent (entnext ent)) (setq eLst (cons ent eLst))) (reverse eLst)) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 18, 2009 Author Share Posted February 18, 2009 Ok, now I am completely baffled... it seems that if I arraym more than one item all the entities that are arrayed are retrieved by your code, but one of the original entities that was arrayed is left out somehow Quote Link to comment Share on other sites More sharing options...
wizman Posted February 18, 2009 Share Posted February 18, 2009 hi lee, you may want to combine the your selection set (your items to be arrayed) with the new selection set derived from asmi's recursive lisp. have a look also if it is applicable to complex entities such as blocks & polylines. Quote Link to comment Share on other sites More sharing options...
CarlB Posted February 18, 2009 Share Posted February 18, 2009 Lee, The use of 'entnext' in this case is not to retrieve subentities' it is to just step through the drawing database of all entities. First, 'entlast' retrieves the last created entity. Then new entities are created. 'Entnext' steps through these new entities, and adds their names to a list. If one of these entities was a complex entity (like a block with attributes), then entnext would step through the subentites. hope this helps decipher ASMI's code Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 18, 2009 Author Share Posted February 18, 2009 Many thanks to you Carl for your explanation - it is very clear and concise. I have only really ever used "entnext" to step into subentities such as block attributes and polyline vertices.. etc etc, so I have not seen it used in this way - thanks for clarifying that. Thanks also to you Wizman for your suggestion. I shall experiment with using a selection set process and let you know of the results. Thanks for the help guys, as always, it is much appreciated. Thanks Lee Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 19, 2009 Author Share Posted February 19, 2009 Ok - I am driving myself up the wall with this one... Why is a circle missed from this entity collection? (defun c:test (/ l1 c1 eLst ss) (setq ss (ssadd)) (command "_line" "0,5" "0,11" "") (setq l1 (entlast)) (command "_circle" "0,5" "5") (setq c1 (entlast)) (command "-array" l1 c1 "" "P" "0,0" "3" "" "Y") (setq eLst (Ent_List_to_End c1)) (foreach n eLst (ssadd n ss)) (command "_move" ss l1 "" pause pause) ) (defun Ent_List_to_End(ent / a) (reverse (if(setq a(entnext ent)) (cons ent(Ent_List_to_End a))))) Seems too simple to be going wrong Quote Link to comment Share on other sites More sharing options...
CarlB Posted February 19, 2009 Share Posted February 19, 2009 Because the first item you add to the list is 'entnext' of c1; you need to first add c1 to the list. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 19, 2009 Author Share Posted February 19, 2009 Ok, I take your point Carl, but why then does this not move c1? (defun c:test (/ l1 c1 eLst ss) (setq ss (ssadd)) (command "_line" "0,5" "0,11" "") (setq l1 (entlast)) (command "_circle" "0,5" "5") (setq c1 (entlast)) (command "-array" l1 c1 "" "P" "0,0" "3" "" "Y") (setq eLst (Ent_List_to_End c1)) (foreach n eLst (ssadd n ss)) (command "_move" [b][color=Red]ss l1 c1[/color][/b] "" pause pause) ) (defun Ent_List_to_End(ent / a) (reverse (if(setq a(entnext ent)) (cons ent(Ent_List_to_End a))))) Quote Link to comment Share on other sites More sharing options...
CarlB Posted February 19, 2009 Share Posted February 19, 2009 I get that it does move c1, it does NOT move the lower right circle, which is the (entlast). I misinterpreted your routine to add items to the list, it does add the c1 initially, as it is the 'a' for the first loop. But the loop stops when 'entnext a' is nil, so it actually fails to add the LAST item to the list. I think **edit** This entity collection routine is not as elegant as your recursive version but seems to work. Plus modified your move command some: (defun c:test () (setq ss (ssadd)) (command "_line" "0,5" "0,11" "") (setq l1 (entlast)) (command "_circle" "0,5" "5") (setq c1 (entlast)) (command "-array" l1 c1 "" "P" "0,0" "3" "" "Y") (setq eLst (Ent_List_to_End c1)) (foreach n eLst (ssadd n ss)) (command "_move" ss l1 "" pause pause) ) (defun Ent_List_to_End(ent / a entlist) (while ent (setq entlist (cons ent entlist)) (setq ent (entnext ent)) ) entlist ) Quote Link to comment Share on other sites More sharing options...
badien Posted February 19, 2009 Share Posted February 19, 2009 CarlB's function is great!! If you still want to use your function, you can refer this following file, I only add another function to select the objects that your function missed. Hope this helps!! Cheers!! select last.LSP Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 19, 2009 Author Share Posted February 19, 2009 Ahhh, I understand it now... because it tests for the entnext of the entity it will miss one of the entities... namely the "entlast" Thank you ever so much Carl for donating your time to solving this problem, I am very grateful. I have tested your code and, as expected, it works perfectly. After your suggestion that the original code did not encompass the "entlast", I changed my code slightly and found that this also works: (defun c:test (/ l1 c1 c2 eLst ss) (setq ss (ssadd)) (command "_line" "0,5" "0,11" "") (setq l1 (entlast)) (command "_circle" "0,5" "5") (setq c1 (entlast)) (command "-array" l1 c1 "" "P" "0,0" "3" "" "Y") (setq eLst (Ent_List_to_End c1)) [color=Red][b] (setq c2 (entlast))[/b][/color] (foreach n eLst (ssadd n ss)) (command "_move" [b][color=Red]ss l1[/color][/b] [b][color=Red]c2[/color][/b] "" pause pause) ) (defun Ent_List_to_End(ent / a) (reverse (if(setq a(entnext ent)) (cons ent(Ent_List_to_End a))))) Thanks also to Badien for his code, your time is much appreciated. Quote Link to comment Share on other sites More sharing options...
David Bethel Posted February 19, 2009 Share Posted February 19, 2009 Lee, How about just using (ssadd) ? -David (defun c:test (/ l1 c1 c2 eLst ss) (setq ss (ssadd)) (command "_line" "0,5" "0,11" "") [color=DarkOrchid] (ssadd (entlast) ss)[/color] (command "_circle" "0,5" "5") (setq c1 (entlast)) (command "-array"[color=DarkOrchid] c1 ss [/color]"" "P" "0,0" "3" "" "Y") [color=DeepSkyBlue] [color=DarkOrchid] (while c1 (ssadd c1 ss) (setq c1 (entnext c1))) [/color][/color] (command "_move" [b][color=Red]ss[/color][/b] "" pause pause) ) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 19, 2009 Author Share Posted February 19, 2009 Thanks David for your suggestion - that certainly makes thing much more concise. Cheers Lee Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.