Tharwat Posted September 4, 2010 Share Posted September 4, 2010 Hello. I wonder why this routine although it is creating a Layer(s) of the selected block(s) it return an error at the end. ; error: bad argument type: lentityp nil Here is the routine . (defun c:blk (/ ss1 i num e blkNme ) (prompt "Select Block(s): ") (if (setq ss1 (ssget ":L" '((0 . "INSERT")))) (progn (setq i -1 num (sslength ss1)) (while (< i num) (setq e (entget (ssname ss1 (setq i (1+ i)) ) ) ) (setq BlkNme (cdr (assoc 2 e)) ) (vl-cmdf "_.-layer" "_m" BlkNme "" "") )) (princ "Nothing Selected") ) (princ) ) Thanks. Tharwat Quote Link to comment Share on other sites More sharing options...
alanjt Posted September 4, 2010 Share Posted September 4, 2010 num (1- (sslength ss1))) You are getting to the end of the selection set and trying to extract an eName at an index that doesn't exist. This is why I prefer (while (setq e (ssname ss (setq i (1+ i)))) Much less coding and it will stop the loop when you cannot extract anymore eNames from the selection set. Remember, (entget nil) -> error Also, you don't need the ignore locked objects filter on your ssget selection. Try it this way: (defun c:Test (/ i ss name) (if (setq i -1 ss (ssget '((0 . "INSERT"))) ) (while (setq e (ssname ss (setq i (1+ i)))) (or (tblsearch "LAYER" (setq name (cdr (assoc 2 (entget e))))) (command "_.-layer" "_new" name "" "") ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 4, 2010 Author Share Posted September 4, 2010 (edited) Thanks Alanjt for the interests. Your routine works well ,and as you have mentioned before it would give an error with (entegt nil) Command: (entget nil); error: bad argument type: lentityp nil So I made it another way according to your advise, also it works well . But if we typed after running codes (entget nil) the same above mentioned error. Here is new one ... (defun c:blk (/ ss1 i Notnil e blkNme ) (prompt "Select Block(s): ") (if (setq ss1 (ssget '((0 . "INSERT")))) (progn (setq i -1) (while (setq e (ssname ss1 (setq i (1+ i)))) (setq Notnil (entget e)) (setq BlkNme (cdr (assoc 2 Notnil)) ) (vl-cmdf "_.-layer" "_m" BlkNme "") )) (princ) ) (princ) ) Would like to know your opinion. Thanks Edited September 4, 2010 by Tharwat Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 4, 2010 Share Posted September 4, 2010 Tharwat, nice to see you're experimenting with VL- functions... but you forgot (vl-load-com). :wink: I've never really done something this way, but here's a crack attempt to 'stream-line' if you will... let me know if I've overlooked something: (defun c:blk (/ ss1 i Notnil e blkNme ) [color="red"](vl-load-com)[/color] (prompt "Select Block(s): ") (if (setq ss1 (ssget '((0 . "INSERT")))) (progn (while (and (setq e (ssname ss1 [color="red"](cond (i (setq i (1+ i))) ((setq i -1)))[/color])) (setq Notnil (entget e)) (setq BlkNme (cdr (assoc 2 Notnil)))) (vl-cmdf "_.-layer" "_m" BlkNme ""))) [color="red"](prompt "\n <!> Nothing Selected <!> ")[/color]) (princ)) ...Curious though, why not use foreach in lieu of while? Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 4, 2010 Author Share Posted September 4, 2010 Thank you Renderman. I am really so glad to hear from you, although I expected to see your post a long time a go. I have some opinions and hope you discuss them with me . But to add (and) after while it's really odd to me. Because I think while function would take care of the following codes since if and progn functions passed the entity to it. What you think ? And cond function as you have located it, also odd to me, because thefollowing codes after cond is logical and no conditions as considered in that place . Also what you think ? The routine hasn't worked with me at all, it gives nothing. I am sorry for that. My best regards, Tharwat Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 4, 2010 Share Posted September 4, 2010 Tharwat, Perhaps take a look here, it looks similar: http://www.theswamp.org/index.php?topic=34785.0 Quote Link to comment Share on other sites More sharing options...
Tharwat Posted September 4, 2010 Author Share Posted September 4, 2010 Yes Lee. I have seen that code this afternoon , But for me it a matter of looking for mistakes to avoid them to take a place later on. Thank you. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 4, 2010 Share Posted September 4, 2010 Yeah, it took me a while to check the forums, because I had this whole huge thing, called a 'lazy day', that I had to take care of... I'd personally not do something in this manor, I'm simply trying to 'branch out' and try something new. That said, I usually avoid while statements which rely on a counter variable, because it just doesn't appeal to me. I know it works, and many seasoned programers prefer it, but I just don't like it. I usually go for the foreach, or vlax-for statements instead. I do use while statements often for loop functionality though. As for the cond statement, it *should* set the i variable to -1 the first time through, and once defined (non nil), increment accordingly. I'm pretty sure that the VLIDE watch window will confirm my speculation...but you'll have to verify? If the routine hasn't worked for you, I apologize. I'm at home (actually my Fiancé's house) and do not have AutoCAD at the moment (it's on my other computer!). I hope I've not muddied the water with my little experiment, but I'll be watching this thread to see the solution(s) that come about. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 4, 2010 Share Posted September 4, 2010 That said, I usually avoid while statements which rely on a counter variable, because it just doesn't appeal to me. I know it works, and many seasoned programers prefer it, but I just don't like it. I prefer WHILE purely for sheer speed in most cases: ;; Lets find the total of a list (defun -while ( l / total ) (setq total (car l)) (while (setq l (cdr l)) (setq total (+ total (car l)))) total ) (defun -foreach ( l / total ) (setq total (car l)) (foreach x (cdr l) (setq total (+ total x))) total ) (defun -mapcar ( l / total ) (setq total (car l)) (mapcar (function (lambda ( x ) (setq total (+ total x)))) (cdr l)) total ) (defun -repeat ( l / total ) (setq total (car l)) (repeat (length (cdr l)) (setq l (cdr l) total (+ total (car l)))) total ) (defun -recursive ( l ) (if l (+ (car l) (-recursive (cdr l))) 0) ) Now the moment of truth... (setq l '( 1 2 3 4 5 6 7 8 9 10 )) (Benchmark '((-while l) (-foreach l) (-repeat l) (-mapcar l) (-recursive l))) Benchmarking ...................Elapsed milliseconds / relative speed for 65536 iteration(s): (-WHILE L).........1997 / 1.21 <fastest> (-RECURSIVE L).....2106 / 1.15 (-MAPCAR L)........2137 / 1.13 (-FOREACH L).......2231 / 1.08 (-REPEAT L)........2418 / 1.00 <slowest> Lets ramp things up a bit: (setq l '( 1 2 3 4 5 6 7 8 9 10 )) (repeat 10 (setq l (append l l))) Length of list = 10x 2^10 = 10240 Results: (Benchmark '((-while l) (-foreach l) (-repeat l) (-mapcar l) (-recursive l))) Benchmarking ...........Elapsed milliseconds / relative speed for 256 iteration(s): (-MAPCAR L).........1638 / 7.18 <fastest> (-WHILE L)..........1918 / 6.13 (-FOREACH L)........2169 / 5.42 (-RECURSIVE L)......3666 / 3.21 (-REPEAT L)........11762 / 1.00 <slowest> Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 4, 2010 Share Posted September 4, 2010 Wow, Lee... nice to see someone takes a day off sometimes. You know, you're totally slacking, my friend... you forgot vlax-for. lol (I'm just ribbing you!) Benchmarks really do a great job to illustrate just how much more efficient one method is over another. Thanks! Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 4, 2010 Share Posted September 4, 2010 Wow, Lee... nice to see someone takes a day off sometimes. You know, you're totally slacking, my friend... you forgot vlax-for. lol (I'm just ribbing you!) Haha thanks Renderman, But of course vlax-for isn't a generic control flow statement, as it only applies to vla collections.... Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 4, 2010 Share Posted September 4, 2010 ...vla collections... as in (vla-get-activeselectionset *activeDoc*), perhaps...? :wink: Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 4, 2010 Share Posted September 4, 2010 ...vla collections... as in (vla-get-activeselectionset *activeDoc*), perhaps...? :wink: Well yes, or the layers/linetypes/blocks etc collections, but that's where it stops.. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted September 4, 2010 Share Posted September 4, 2010 Certainly. I understand that it (vlax-for) more specifically processes collection and not lists. I only use that example to point out a function structure which Alan taught me (thanks Alan!), which is a simple way to switch from a list to a collection, and step through each to conduct a task. ... (if (setq ss (ssget ...)) (vlax-for x (setq ss (vla-get-activeselectionset *activeDoc*)) ...)) (vla-delete ss) ... As it happens, I am using more and more vla-* functions lately, so my tendancy to 'lean' towards vlax-for is logical, not necessarily preferable for other situations (i.e., code should be task dependent). Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted September 4, 2010 Share Posted September 4, 2010 Sure, I realise that when dealing with a SelectionSet, you can step through it using either ssname, or iterate through the ActiveSelectionSet within the SelectionSet Collection (although at this point it might be more consistent perhaps to obtain the SelectionSet through VL means also), but my point is, the vlax-for loop is certainly not generic and we are not so much 'switching from a list to a collection', as the Vanilla SelectionSet is not a list. 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.