C. Roberts Posted April 8 Share Posted April 8 I am a beginner to AutoLISP and have been searching for a way to insert a block (ID_SYMBOLS) if a block from a list (see below for short list) is currently in the drawing. However the drawing could have multiple blocks from the list in the drawing and I only want to insert the block once and not have multiple entities of it on top of each other. I have found that this works to insert the block needed but I was hoping not to have to repeat these lines for each block that could be in the drawing. Is there a way to have it run through the list until it finds 1 of them in the drawing and then stop and insert the block needed once? (if (tblsearch "BLOCK" "SW1FRM") (command "-INSERT" "ID_SYMBOLS.dwg" "0,-25" txthtscld "0") ) A very short list of blocks that I would need it to check for in the drawing would be: SW1FRM SW1PNL EW1FRM EW1PNL Thanks for the help!! Quote Link to comment Share on other sites More sharing options...
C. Roberts Posted April 9 Author Share Posted April 9 This is what I ended up doing. ;Inserting MBS Tables (setq insert_mbs_tbls (command "-INSERT" "MBS_TABLES.dwg" "0,-50" txthtscld "0")) (if (tblsearch "BLOCK" "SW1FRM") insert_mbs_tbls (if (tblsearch "BLOCK" "SW2FRM") insert_mbs_tbls (if (tblsearch "BLOCK" "SW1PNL") insert_mbs_tbls (if (tblsearch "BLOCK" "SW2PNL") insert_mbs_tbls (if (tblsearch "BLOCK" "EW1FRM") insert_mbs_tbls (if (tblsearch "BLOCK" "EW2FRM") insert_mbs_tbls (if (tblsearch "BLOCK" "EW1PNL") insert_mbs_tbls (if (tblsearch "BLOCK" "EW2PNL") insert_mbs_tbls (if (tblsearch "BLOCK" "ROFFRM") insert_mbs_tbls (if (tblsearch "BLOCK" "ROFSHT") insert_mbs_tbls (if (tblsearch "BLOCK" "WLINER1") insert_mbs_tbls (if (tblsearch "BLOCK" "WLINER2") insert_mbs_tbls (if (tblsearch "BLOCK" "WLINER3") insert_mbs_tbls (if (tblsearch "BLOCK" "WLINER4") insert_mbs_tbls (if (tblsearch "BLOCK" "ROOFLNR") insert_mbs_tbls (if (tblsearch "BLOCK" "CRANETBL") insert_mbs_tbls (if (tblsearch "BLOCK" "FLOORTBL") insert_mbs_tbls (prompt "\nMBS_TABLES block not needed.") ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) Is there a way to write this more efficiently?? Quote Link to comment Share on other sites More sharing options...
pkenewell Posted April 9 Share Posted April 9 (edited) @C. Roberts There are other ways to to this, but here is how I would tackle it: ;; Creates a List of blocks, then converts them into a string that can be used by Wcmatch. ;; NOTE: wildcards can be used in indiviual list items to search for common names, like "SW1*" (setq blks (list "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL") bstr (strcat (car blks) (apply 'strcat (mapcar '(lambda (x)(strcat "," x)) (cdr blks)))) l nil ;; Set l to nil, this was just for testing. not needed if "l" is declared locally in the function. ) ;; Iterate though the list of blocks and get the Block names. Resets the (tblnext) function if the l variable is nil, ;; which allows it to be used multiple times during the session. (while (setq bl (if (not l)(tblnext "BLOCK" T)(tblnext "BLOCK")))(setq l (append l (list (cdr (assoc 2 bl)))))) ;; Returns "T" if any Block names match an item in the "blks" list, NIL if no matches. (setq ex (if (vl-remove-if 'null (mapcar '(lambda (x)(wcmatch x bstr)) l)) T nil)) EDIT - see below. I overthinked this one LOL. Edited April 9 by pkenewell Quote Link to comment Share on other sites More sharing options...
pkenewell Posted April 9 Share Posted April 9 (edited) @C. Roberts Actually, now that I think about it - here is a much shorter way! (setq blks (list "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL") ex (if (vl-remove-if 'null (mapcar '(lambda (x)(if (tblsearch "BLOCK" x) T nil)) blks)) T nil) ) OR as a function: (defun Blockp (l) (if (vl-remove-if 'null (mapcar '(lambda (x)(if (tblsearch "BLOCK" x) T nil)) l)) T nil) ) ;;Example: (Blockp (list "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL")) Edited April 9 by pkenewell 1 Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 9 Share Posted April 9 Another way is to use foreach. (setq blks (list "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL")) (foreach blk blks (if (tblsearch "BLOCK" blk) (if (tblsearch "BLOCK" "MBS_TABLES.dwg") (princ "exists") (command "-INSERT" "MBS_TABLES.dwg" "0,-50" txthtscld "0") ) ) ) 2 Quote Link to comment Share on other sites More sharing options...
C. Roberts Posted May 2 Author Share Posted May 2 On 4/9/2024 at 6:23 PM, BIGAL said: Another way is to use foreach. (setq blks (list "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL")) (foreach blk blks (if (tblsearch "BLOCK" blk) (if (tblsearch "BLOCK" "MBS_TABLES.dwg") (princ "exists") (command "-INSERT" "MBS_TABLES.dwg" "0,-50" txthtscld "0") ) ) ) I tried this and it inserted the object multiple times. The drawing had 2 of the blocks in it from the list. Is there a way to have it stop after inserting it the first time? Quote Link to comment Share on other sites More sharing options...
C. Roberts Posted May 2 Author Share Posted May 2 Nevermind, I figured out the problem with it. Needed to take the .dwg off of MBS_TABLES.dwg. Ran perfectly after that. Thanks for the help!! 1 Quote Link to comment Share on other sites More sharing options...
Jonathan Handojo Posted May 3 Share Posted May 3 I would go with this approach: (vl-some (function (lambda (a) (if (tblsearch "BLOCK" a) (progn (command "-INSERT" "MBS_TABLES.dwg" "0,-50" txthtscld "0") t) ) ) ) '( ;; --- List of Blocks --- ;;; "SW1FRM" "SW1PNL" "EW1FRM" "EW1PNL" ;; --- List of Blocks --- ;;; ) ) 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.