C. Roberts Posted April 8 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
C. Roberts Posted April 9 Author 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
pkenewell Posted April 9 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
pkenewell Posted April 9 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
BIGAL Posted April 9 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
C. Roberts Posted May 2 Author 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
C. Roberts Posted May 2 Author 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
Jonathan Handojo Posted May 3 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
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.