Author Topic: Another selection method question  (Read 4768 times)

0 Members and 1 Guest are viewing this topic.

EddieFromDc

  • Newt
  • Posts: 34
Another selection method question
« on: December 12, 2008, 10:13:30 AM »
Hello again,

I receive dwgs from a client that does not use autocad. The way that program insert
blocks is that it gives it a random name every time it inserts it (even though its the same block)
..ex 1AD3C_PC_GROUP, 1BDD4_PC_GROUP. The problem is that all blocks are all in one layer. I
dont know if its a translation issue or just bad drafting. I need to select certain blocks & put it in
a seperate layer.

The block has text in it (not attributes)....Has anyone come up yet with a lisp program that can
select blocks that has a certain "text" string in it? Maybe text and attribute?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #1 on: December 12, 2008, 10:22:57 AM »
Would a partial block name help with the selection?
Code: [Select]
(setq ss (ssget '((2 . "*_PC_GROUP"))))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

EddieFromDc

  • Newt
  • Posts: 34
Re: Another selection method question
« Reply #2 on: December 12, 2008, 10:38:28 AM »
Hi Cab,

No. I forget to mention all  block names end with "_PC_GROUP". No block
will have the same name. I tried to use "ssx" but it only gave me one
selection....Thanks Cab

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #3 on: December 12, 2008, 10:43:34 AM »
Well a simple selection won't do. You will need select potential blocks and then iterate through the block to find matching text.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Another selection method question
« Reply #4 on: December 12, 2008, 10:57:28 AM »
Well a simple selection won't do. You will need select potential blocks and then iterate through the block to find matching text.


Or get the text string, and then search through the block collection, and build a filter list of the block names.  This way your selection will only allow those blocks that you desire to be selected.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #5 on: December 12, 2008, 11:55:09 AM »
You can give this a test drive. Modeled after Tim's suggestion.  :-)
Code: [Select]
;;  CAB  12/12/2008
;;  Find Text within blocks and selects the inserts
;; set the variable IgnoreCase as desired
(defun c:BlockTextFind (/ txt adoc blk obj BlockNameList ss filter)
  (vl-load-com)
  (setq IgnoreCase t)
  (if (setq txt (getstring t "\nEnter text to find."))
    (progn
      (and IgnoreCase (setq txt (strcase txt)))
      (setq ss (ssadd))
      (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
      (vlax-for blk (vla-get-blocks adoc)
        ;; Exclude model and paper spaces, xref and anonymus blocks
        (if (and (equal (vla-get-IsLayout blk) :vlax-false)
                 (equal (vla-get-IsXref blk) :vlax-false)
                 (/= (substr (vla-get-Name blk) 1 1) "*")
            )
          (vlax-for obj blk
            (if (and (vl-position (vla-get-objectname obj) '("AcDbText" "AcDbMText"))
                     (= txt
                        (if IgnoreCase
                          (strcase (vla-get-textstring obj))
                          (vla-get-textstring obj)))
                )
              (setq BlockNameList (cons (vla-get-name blk) BlockNameList))
            )
          )
        )
      )
    )
  )
  (if BlockNameList
    (progn
      (setq filter "")
      (mapcar '(lambda (x) (setq filter (strcat filter x ","))) BlockNameList)
      ;;  get matching blocks in current space
      (and (setq ss (ssget "_X" (list (cons 2 filter) (cons 410 (getvar "ctab")))))
           (sssetfirst nil ss)
      )
    )
    (prompt "\nNo matching blocks found.")
  )
  (princ)
)
<edit: Fixed Mtext error>
« Last Edit: December 12, 2008, 12:49:03 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

EddieFromDc

  • Newt
  • Posts: 34
Re: Another selection method question
« Reply #6 on: December 12, 2008, 12:18:46 PM »
Cab,

Thank you very much! Works exactly the way I want it to....Could you please do me a favor
when you get the chance. You & Tim kindda gave me some ideas earlier so I made several
attemps to write the program (I'm a beginner) & got stuck. Could you please help me with "ssadd".


(defun C:Test ( / txt ss sslen cnt ename entdata blkname tempent nextent tempnext)
(setq Txt (getstring "\nEnter string to search in blocks: "))
(setq ss (ssget "x" '((0 . "INSERT"))))
(setq cnt 0)
(setq sslen (sslength ss))
(while (< cnt sslen)
       (setq ename (ssname ss cnt))
       (setq entdata (entget ename))
       (setq blkname (cdr (assoc 2 entdata)))
       (setq tempent (tblobjname "block" blkname))
       (setq nextent (entnext tempent))
       (setq tempnext (entget nextent))
       (if (= (cdr (assoc 1 tempnext)) Txt) (progn

                                                        ;This is where I wanted to use ssadd to collect the blocks

                                                         )
       )
(setq cnt (1+ cnt))
)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #7 on: December 12, 2008, 12:33:17 PM »
Glad we could help.
Make sure you initialize a selection set before adding to it.
Code: [Select]
(defun C:Test (/ txt ss sslen cnt ename entdata blkname tempent nextent tempnext)
  (setq Txt (getstring "\nEnter string to search in blocks: "))
  (setq ss (ssget "x" '((0 . "INSERT"))))
  (setq cnt 0
        ss2 (ssadd) ; initialize the selection set  ***
  )
  (setq sslen (sslength ss))
  (while (< cnt sslen)
    (setq ename (ssname ss cnt))
    (setq entdata (entget ename))
    (setq blkname (cdr (assoc 2 entdata)))
    (setq tempent (tblobjname "block" blkname))
    (setq nextent (entnext tempent))
    (setq tempnext (entget nextent))
    (if (= (cdr (assoc 1 tempnext)) Txt)
      (ssadd ename ss2) ; add to the selection set  ***
    )
    (setq cnt (1+ cnt))
  )
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Another selection method question
« Reply #8 on: December 12, 2008, 12:41:34 PM »
Alan,

  Another way to do it, since you are selecting all the blocks, in the code you posted based off my idea, is to just get all the block inserts from the block definition without a selection set.  Also you had a mis-type in your if statement here
Code: [Select]
(if (and (vl-position (vla-get-objectname obj) '("AcDbText" "AcDbText"))I think it should be
Code: [Select]
(if (and (vl-position (vla-get-objectname obj) '("AcDbText" "AcDbMText"))
Just another way to the skin a cat on a friday.  :-D
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #9 on: December 12, 2008, 12:49:46 PM »
Thanks Tim, good catch. I updated the code. 8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #10 on: December 12, 2008, 12:53:29 PM »
Alan,

  Another way to do it, since you are selecting all the blocks, in the code you posted based off my idea, is to just get all the block inserts from the block definition without a selection set. 
Just another way to the skin a cat on a friday.  :-D

I was being lazy as I wanted only current space inserts.  :-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Another selection method question
« Reply #11 on: December 12, 2008, 12:58:07 PM »
Alan,

  Another way to do it, since you are selecting all the blocks, in the code you posted based off my idea, is to just get all the block inserts from the block definition without a selection set. 
Just another way to the skin a cat on a friday.  :-D

I was being lazy as I wanted only current space inserts.  :-)
Maybe I should of read it better, as I didn't notice the filter for the current tab.  Since it is in there, nevermind my other part of the post.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Another selection method question
« Reply #12 on: December 12, 2008, 01:42:20 PM »
All this talking made me what you write some code.  Here is a sub function that will return a selection of ( empty or not ) of the blocks that contain a certain string in either text or mtext within the definition.  Now before you go bitting my head off.  I figured that there wasn't going to be a string within an mtext entity that is long than 256 characters within a block.  That case can be rectified, but I just didn't code for it now.  It will also let you pass a string name for the space desired to grab within ( maybe it could be list, so that more than one space could be passed ) or nil for all spaces.  Hope that isn't confusing.  Well here is the code.

Case is ignored in both arguments.

Code: [Select]
(defun GetSsBlockByString (str spaceName / ss BlkEntData tempEnt tempData tempInsList)
   
    (setq ss (ssadd))
    (while (setq BlkEntData (tblnext "block" (not BlkEntData)))
        (setq tempEnt (cdr (assoc -2 BlkEntData)))
        (while tempEnt
            (setq tempData (entget tempEnt))
            (if
                (and
                    (not (wcmatch (cdr (assoc 2 BlkEntData)) "*|*"))
                    (member (cdr (assoc 0 tempData)) '("TEXT" "MTEXT"))
                    (wcmatch (strcase (cdr (assoc 1 tempData))) (strcase (strcat "*" str "*")))
                    (setq tempData (entget (tblobjname "block" (cdr (assoc 2 BlkEntData)))))
                    (setq tempInsList
                        (cdr
                            (member
                                '(102 . "{BLKREFS")
                                (entget
                                    (cdr
                                        (assoc
                                            330
                                            (entget
                                                (tblobjname "block" (cdr (assoc 2 tempData)))
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    )
                    (setq tempInsList (cdr (member '(102 . "}") (reverse tempInsList))))
                    (not (setq tempEnt nil))
                )
                (foreach i tempInsList
                    (if spaceName
                        (if (= (strcase spaceName) (strcase (cdr (assoc 410 (entget (cdr i))))))
                            (ssadd (cdr i) ss)
                        )
                        (ssadd (cdr i) ss)
                    )
                )
                (setq tempEnt (entnext tempEnt))
            )
        )
    )
    ss
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #13 on: December 12, 2008, 02:28:42 PM »
You having coding withdrawal? :lmao:
Nice code Tim. 8-)

All we need to do now is add attributes in the string match. :evil:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Another selection method question
« Reply #14 on: December 12, 2008, 02:38:32 PM »
Me too. 8-)
Code: [Select]
;;  CAB  12/12/2008  version 1.1
;;  Find Text within blocks and selects the inserts
;;  set the variable IgnoreCase as desired
;;  http://www.theswamp.org/index.php?topic=26368.msg318197#msg318197
(defun c:BlockTextFind (/ txt adoc blk obj BlockNameList ss filter)
  (vl-load-com)
  (setq IgnoreCase t) ; this can be globle
  (if (setq txt (getstring t "\nEnter text to find."))
    (progn
      (and IgnoreCase (setq txt (strcase txt)))
      (setq ss (ssadd))
      (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
      (vlax-for blk (vla-get-blocks adoc) ; in the drawing
        ;; Exclude model and paper spaces, xref and anonymus blocks
        (if (and (equal (vla-get-IsLayout blk) :vlax-false)
                 (equal (vla-get-IsXref blk) :vlax-false)
                 (/= (substr (vla-get-Name blk) 1 1) "*")
            )
          (vlax-for obj blk ; in the block definition
            (if (and (vl-position (vla-get-objectname obj) '("AcDbText" "AcDbMText")) ; removed "AcDbAttributeDefinition"))
                     (= txt
                        (if IgnoreCase
                          (strcase (vla-get-textstring obj))
                          (vla-get-textstring obj)))
                     (not (vl-position (vla-get-name blk) BlockNameList))
                )
              (setq BlockNameList (cons (vla-get-name blk) BlockNameList))
            )
          )
        )
      )
    )
  )
  (if BlockNameList
    (progn
      (setq filter "")
      (mapcar '(lambda (x) (setq filter (strcat filter x ","))) BlockNameList)
      ;;  get matching blocks in current space
      (and (setq ss (ssget "_X" (list (cons 2 filter) (cons 410 (getvar "ctab")))))
           (sssetfirst nil ss)
      )
    )
    (prompt "\nNo matching blocks found.")
  )
  (princ)
)

<edit: removed attributes :( >
« Last Edit: December 12, 2008, 03:03:14 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.