Jump to content

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


Recommended Posts

Posted

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

Posted

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

Posted (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 by pkenewell
Posted (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 by pkenewell
  • Agree 1
Posted

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 2
  • 4 weeks later...
Posted
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?

Posted

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

  • Like 1
Posted

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

 

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