ILoveMadoka Posted August 2 Share Posted August 2 (edited) Up til now I have had 3 separate routines for inserting a block based upon the existence of an inserted block in a drawing. (if (tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "")) (if (tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "")) (if (tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "")) I was wanting to combine them into a single routine similar to this; (defun c:foo () (cond (if (tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "")) (if (tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "")) (if (tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "")) ) (princ)) [Which does not work correctly BTW - it does not go beyond the first step] I also wondered "what if more than one block exists?" Ideally only one of these blocks "should" exist in a drawing in my situation. How can I test for the existence of more than one block first and return an error if found or insert the appropriate block meeting the criteria otherwise? I read about using wcmatch if I set (setq myblks (list "BlockA" "BlockB" "BlockC")) Not sure how to incorporate that if it is the better way I have pieces and parts but cannot put it together Help please.. ps: When using multiple searches, how to you proceed to the next search if the criteria is not met? (if (tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "")) Edited August 2 by ILoveMadoka Quote Link to comment Share on other sites More sharing options...
Steven P Posted August 2 Share Posted August 2 (edited) So in your cond I don't think you need the 'if', it should run through until it finds the first condition that is true - in this case if you have BlockA and BlockC it will insert Block1 and not Block3... you can order your inserts in order of priority. You might also consider a 'T' condition - if none of the above conditions are met, do "T" (defun c:foo () (cond ((tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) ) (princ) ) (tablesearch "block") will return a list of all the blocks in the drawing, you can search this using "member" and the block name (tblsearch will return just the specified block if it exists) Edited August 2 by Steven P 1 Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 2 Author Share Posted August 2 Something like this? (defun c:foo () (cond ((tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) (t nil) ) (princ) ) That answers one question. <Thank you!> Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 2 Author Share Posted August 2 For the other questions.. How do I search for any of the three possible error combinations? How do I test if more than one of these blocks is present and exit with a message if so? If I have BlockA & BlockC = exit with error message. I think wcmatch only searches for one string Will I use this and member? [I don't know how to do that..] (setq myblks (list "BlockA" "BlockB" "BlockC")) Quote Link to comment Share on other sites More sharing options...
mhupp Posted August 2 Share Posted August 2 (edited) Would also bring up that using generic block names between drawings that get modified in the drawing itself could bring issues. I worked in production and our projects would be exported to CNC. for speed we used blocks that stored shapes and depth. everything could be exported to a spread sheet and updated there and then imported back into the drawing. when someone said part of project x is in project y we would open Y copy the section we needed and paste into the new project. problem is if the Block A was already defined in the new project it wouldn't bring over Block A from the old project it would bring the insertion put but use the block reference that is already in the new drawing. if their was any difference between the two block's depth or shape difference it would just bring everything over and not throw an error or say anything about changes. and I didn't know anything was different when this happened. the shape was the same but depth info was almost 2" difference. required additional machining and a "investigation" on why this happened On 8/2/2024 at 10:48 AM, ILoveMadoka said: For the other questions.. How do I test if more than one of these blocks is present and exit with a message if so? (setq myblks (list "BlockA" "BlockB" "BlockC")) (setq myblks '("BlockA" "BlockB" "BlockC")) (foreach blk myblks (if (tblsearch "BLOCK" blk) (prompt (strcat "\n" blk " Found")) ) ) Edited August 3 by mhupp fixed typo blkl to blk 1 Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 2 Author Share Posted August 2 I understand... I'm using generic names for simplicity sake. The actual application will have different names... = (setq myblks '("BlockA" "BlockB" "BlockC")) foreach blk myblks (if (tblsearch "BLOCK" blkl) (prompt (strcat "\n" blk " Found") ) ) this returns "BlockA" "BlockB" "BlockC" even in a drawing with no blocks. I'm confused about how to apply.. Still quite the novice (if that) but thank you... Quote Link to comment Share on other sites More sharing options...
mhupp Posted August 3 Share Posted August 3 (edited) had a typo of blkl instead of blk so nothing was found when searching the block table since blkl wasn't a defined variable. As for displaying the list AutoLISP always prints the value of the last evaluated expression to the command line when exiting the function. in some cases you want this when your using it to return a list or some other value. when you don't want this to happen you just use a (princ) so nothing is outputted (defun c:Foo1 () (princ "Hello, World!") ;will display as "Hello, World! (princ) ) (defun c:Foo2 () (princ "Hello, World!") ;will display as "Hello, World!Hello, World!" ) to get what you want you are going to have to combine Steven's and my code (defun c:foo () (setq myblks '("BlockA" "BlockB" "BlockC")) (foreach blk myblks (if (tblsearch "BLOCK" blk) (cond ((eq blk "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((eq blk "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((eq blk "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) ) ) ) (princ) ) Edited August 6 by mhupp code update 1 Quote Link to comment Share on other sites More sharing options...
ronjonp Posted August 3 Share Posted August 3 An association list is nice for this and can easily be generated if A=1 B=2 etc. (defun c:foo (/ a myblks) (setq myblks (mapcar '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64))))) '("BlockA" "BlockB" "BlockC") ) ) ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) (foreach blk myblks (if (and (tblsearch "BLOCK" blk) (set a (assoc blk myblks))) (command "-insert" (cadr a) "0,0" "" "" "") ) ) (princ) ) 1 Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 5 Author Share Posted August 5 If you guys are trying to lead me to the water... I'm not smart enough to drink unfortunately.... I cannot put the pieces together. I see some promise in this (none of these can be true) I need to <Exit> with an error if any of these are true. (("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC")) ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ;;;this code <Steven P> works (defun c:foo () (cond ((tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) (t nil) ) (princ) ) How do I run this check first and exit if any are true (("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC")) Exit (t nil) Again, all these block names are example placeholders and are not the actual block names for the checks or the insert. ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ;;;;Does not work as is.. returns *Cancel* (defun c:foo (/ a myblks) (setq myblks (mapcar '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64))))) '("BlockA" "BlockB" "BlockC") ) ) ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) (foreach blk myblks (if (and (tblsearch "BLOCK" blk) (set a (assoc blk myblks))) (command "-insert" (cadr a) "0,0" "" "" "") ) ) (princ) ) ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ;;;;Does not work as is.. returns *Cancel* (defun c:foo (/ a myblks) (setq myblks (mapcar '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64))))) '("BlockA" "BlockB" "BlockC") ) ) ;; (("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC")) (foreach blk myblks (if (and (tblsearch "BLOCK" blk) (set a (assoc blk myblks))) (command "-insert" (cadr a) "0,0" "" "" "") ) ) (princ) ) ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ;;; Parenthesis Mismatch [ 15ea ( ] [ 18ea ) ] ;;;;Does not work as is.. (defun c:foo3 () (setq myblks '("BlockA" "BlockB" "BlockC")) (foreach blk myblks (if (tblsearch "BLOCK" blk) (cond (eq blk "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) (eq blk "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) (eq blk "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) ) ) ) (princ) ) ==== === ==== ===== ==== === ==== ===== ==== === ==== ===== ;;;;Does not work as is.. for me error on load with a *Cancel* (defun c:foo3 () (setq myblks '("BlockA" "BlockB" "BlockC")) (foreach blk myblks (if (tblsearch "BLOCK" blk) (cond (eq blk "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) (eq blk "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) (eq blk "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) (princ) ) I appreciate that you are hoping that I'm smarter than I really am... Thank you all so very much for all your input and assistance! Quote Link to comment Share on other sites More sharing options...
ronjonp Posted August 5 Share Posted August 5 Had a typo .. give this a try: (defun c:foo (/ a myblks) (setq myblks (mapcar '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64))))) '("BlockA" "BlockB" "BlockC") ) ) ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) (foreach blk myblks (if (and (tblsearch "BLOCK" (cadr blk)) (set a (assoc (car blk) myblks))) (command "-insert" (cadr a) "0,0" "" "" "") ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 21 Author Share Posted August 21 (edited) Sorry for the long delay... <ronjonp> Thank you for the response. after testing multiple scenarios, your last code returns *Cancel* for me This code is the only code that I've gotten to work (defun c:foo () ;;Steven P (cond ((tblsearch "BLOCK" "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((tblsearch "BLOCK" "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) (t nil) ) (princ) ) this works too (defun c:foo () ;;mhupp/Steven P (setq myblks '("BlockA" "BlockB" "BlockC")) (foreach blk myblks (if (tblsearch "BLOCK" blk) (cond ((eq blk "BlockA") (command "-insert" "Block1" "0,0" "" "" "") ) ((eq blk "BlockB") (command "-insert" "Block2" "0,0" "" "" "") ) ((eq blk "BlockC") (command "-insert" "Block3" "0,0" "" "" "") ) ) ) ) (princ) ) If I could check for multiple inserts and exit if true, I'd be golden. something along these lines [Not real code] (if (BlockA & BlockB) or (BlockA & BlockC) or (BlockB & BlockC) are true <exit> Sorry again for the delay in getting back. I've attached a dummy drawing with all the blocks referenced contained within. Block1 and BlockA go together Block2 and BlockB go together Block3 and BlockC go together How I test is I copy 1 or 2 sets to a new drawing and test my routines... foo.dwg Edited August 21 by ILoveMadoka Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 21 Author Share Posted August 21 (edited) There is a song that says "Baby did a bad, bad thing..." I went over to an ai website and asked some questions and it eventually returned this working code... (Probably not the most efficient code but it is working in all my situations) (defun c:foo(/ blockNames foundBlocks insertBlock) ;; Define the blocks to check (setq blockNames '("BLOCKA" "BLOCKB" "BLOCKC") foundBlocks '() insertBlock "") ;; Check for each block's presence in the drawing (foreach blk blockNames (if (tblsearch "BLOCK" blk) (setq foundBlocks (cons blk foundBlocks)) ) ) ;; Determine action based on found blocks (cond ;; If more than one block is found ((> (length foundBlocks) 1) (princ "\nMore than one block found - Exiting...") ) ;; If exactly one block is found ((= (length foundBlocks) 1) (setq insertBlock (cond ((equal (car foundBlocks) "BLOCKA") "Block1") ((equal (car foundBlocks) "BLOCKB") "Block2") ((equal (car foundBlocks) "BLOCKC") "Block3") ) ) ;; Insert the block at the origin (0,0) (if (tblsearch "BLOCK" insertBlock) (command "_.-INSERT" insertBlock '(0 0) "1" "1" "0") (princ (strcat "\nBlock \"" insertBlock "\" not found in the drawing.")) ) ) ;; If no blocks are found (T (princ "\nNo blocks found.") ) ) (princ) ) My success rate using ai has been about 10% or less in the past.. so I gave up trying to use that method.. I got lucky I suppose. I still thank each and every one of you for your assistance. Edited August 21 by ILoveMadoka 1 Quote Link to comment Share on other sites More sharing options...
Steven P Posted August 21 Share Posted August 21 AI is a tool to use but you do need to be able to assess what it is telling you rather than blindly following it. Perhaps best used to get you around tricky parts of the code rather than the whole code? Quote Link to comment Share on other sites More sharing options...
SLW210 Posted August 21 Share Posted August 21 I haven't tried LISP, but some of the programming languages have IDE's and Code Editors that practically write your code for you, at least helping finish and autocomplete with syntax, etc. I am guessing that's what AI is doing pretty much adapting written instructions to appropriate IDE and letting that finish it up. Most AI programmers probably not knowledgeable in AutoLISP, VLISP so might be a learn as LISP gets asked and corrected would be my guess. Looks like they aren't working for me at work as per the recent CoPilot thread. 1 Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 21 Author Share Posted August 21 (edited) Early on I couldn't get ai to write an autolisp routine that could draw a circle.. It would make up weird commands and stuff because it didn't know jack about lisp ie: drawcircle as a command.. I'm glad it's learning... I guess if Skynet is going to take over it has to learn lisp first... Edited August 21 by ILoveMadoka Quote Link to comment Share on other sites More sharing options...
ILoveMadoka Posted August 21 Author Share Posted August 21 I wish I had saved the conversation I had with ChatGPT about not knowing lisp... It was kinda funny... 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.