Jump to content

Insert block only if another block from a list of blocks is currently in the drawing


C. Roberts

Recommended Posts

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!!

Link to comment
Share on other sites

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??

Link to comment
Share on other sites

@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 by pkenewell
Link to comment
Share on other sites

@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 by pkenewell
  • Agree 1
Link to comment
Share on other sites

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")
   )
  )
)

 

 

  • Agree 1
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...