Jump to content

SSGET - BLOCK, then Search Descriptions


Recommended Posts

Posted

Try the following -

(defun c:test2 ( / a e i s x )
   (if (setq s (ssget "_C" '(7.244 2.071) '(16.665 10.003) '((0 . "INSERT") (8 . "FTG-Iso") (66 . 1))))
       (repeat (setq i (sslength s))
           (setq i (1- i)
                 e (ssname  s i)
                 a (entnext e)
                 x (entget  a)
           )
           (while
               (and (= "ATTRIB" (cdr (assoc 0 x)))
                   (not
                       (and
                           (= "description" (strcase (cdr (assoc 2 x)) t))
                           (wcmatch (strcase (cdr (assoc 1 x)) t) "aaa,bbb,ccc")
                       )
                   )
               )
               (setq a (entnext a)
                     x (entget  a)
               )
           )
           (or (= "ATTRIB" (cdr (assoc 0 x))) (ssdel e s))
       )
   )
   (sssetfirst nil s)
   (princ)
)

  • Replies 31
  • Created
  • Last Reply

Top Posters In This Topic

  • GregGleason

    13

  • ronjonp

    12

  • BIGAL

    3

  • Lee Mac

    3

Top Posters In This Topic

Posted Images

Posted

I'm sure Lee's code will work, but if you include a drawing with before and after results, most likely you'll will always get better answers to your questions.

Posted
I'm sure Lee's code will work, but if you include a drawing with before and after results, most likely you'll will always get better answers to your questions.

 

As I am still learning, do you mean upload the .dwg file with a "before" condition and another with the "after" condition (with the desired state)?

 

Well if that helps then I am more than happy to do that!

 

Greg

Posted
Try the following -

(defun c:test2 ( / a e i s x )
   (if (setq s (ssget "_C" '(7.244 2.071) '(16.665 10.003) '((0 . "INSERT") (8 . "FTG-Iso") (66 . 1))))
       (repeat (setq i (sslength s))
           (setq i (1- i)
                 e (ssname  s i)
                 a (entnext e)
                 x (entget  a)
           )
           (while
               (and (= "ATTRIB" (cdr (assoc 0 x)))
                   (not
                       (and
                           (= "description" (strcase (cdr (assoc 2 x)) t))
                           (wcmatch (strcase (cdr (assoc 1 x)) t) "aaa,bbb,ccc")
                       )
                   )
               )
               (setq a (entnext a)
                     x (entget  a)
               )
           )
           (or (= "ATTRIB" (cdr (assoc 0 x))) (ssdel e s))
       )
   )
   (sssetfirst nil s)
   (princ)
)

 

I will give it a run the first thing in the morning!

 

Greg

Posted
.. do you mean upload the .dwg file with a "before" condition and another with the "after" condition (with the desired state)?

...

Yes. More information is always better. This thread is about 2 pages longer than it needs to be just because your question eluded to something different.

 

BTW .. you don't need code to do this. The FIND command will create a selection set of items based on a common text value.

2018-03-22_6-58-28.jpg

Posted
Yes. More information is always better. This thread is about 2 pages longer than it needs to be just because your question eluded to something different.

 

BTW .. you don't need code to do this. The FIND command will create a selection set of items based on a common text value.

 

Oh, I was not aware of that feature. That's very helpful.

 

In my case, I do need code because my supervision wants an automated solution for end users. So that when the process is completed and reviewed it can moved on to the client.

 

Greg

Posted

Just so that any further ambiguity can be minimized I am including a test drawing and a screen shot. The test drawing is not a native AutoCAD document so it is going to bark at you and make you aware of that (I am working on another program to address that issue). In the screen shot below, you can information on the block (from the drawing, the number 3 in the square) and the string "10x0.75" SKSW 71" is found in the "Description" attribute. Because that has "SKSW" in the description, I want to keep it in the selection.

 

attachment.php?attachmentid=63566&cid=1&stc=1

 

In this drawing there are 27 blocks on the "FTG-Iso" layer. On the "Description" attribute, there is a string of information present. I want to find any of the following strings in the description:

 

SKSW

NISC

NIPL

THSC

WTBW

NRSC

PL

KASC

KASW

 

Those Descriptions that do not have those sequence of characters should be omitted from the selection.

 

And if they appear keep it in the selection and change the layer to "FTG-Pipe".

 

In this sample file there are 6 blocks of the 27 that meet this criteria.

 

I hope that clears up what the objective is and I now wish I had put this information earlier in my post. Please let me know if anything is unclear. Hopefully at the end of the day I will have the problem solved with your help.

 

Greg

Test1.DWG

EAE_2.jpg

Posted

Try this:

(defun c:test (/ _getattvalue s v)
 ;; RJP - Simple get attribute value sub .. no error checking
 (defun _getattvalue (block tag)
   (vl-some
     '(lambda (att)
 (cond ((eq (strcase tag) (strcase (vla-get-tagstring att))) (vla-get-textstring att)))
      )
     (vlax-invoke block 'getattributes)
   )
 )
 ;; RJP - added (66 . 1) to filter ( attributed blocks )
 (cond	((setq
   s (ssget "_C" '(7.244 2.071) '(16.665 10.003) '((0 . "INSERT") (8 . "FTG-Iso") (66 . 1)))
 )
 (foreach en (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
   (if (and ;; If we have a value, and it does not match the filter then remove item from selection
	    (setq v (_getattvalue (vlax-ename->vla-object en) "Description"))
	    ;; Wcmatch example
	    ;; (not (wcmatch (strcase v) "*SKSW*,*NISC*,*NIPL*,*THSC*,*WTBW*,*NRSC*,*PL*,*KASC*,*KASW*,"))
	    ;; vl-string-search example ( more legible IMO )
	    (not (vl-some '(lambda (x) (vl-string-search x (strcase v)))
			  '("SKSW" "NISC" "NIPL" "THSC" "WTBW" "NRSC" "PL" "KASC" "KASW")
		 )
	    )
       )
     (ssdel en s)
   )
 )
 ;; Highlight selection
 (sssetfirst nil s)
)
 )
 (princ)
)
(vl-load-com)

Posted
Try this:

(defun c:test (/ _getattvalue s v)
 ;; RJP - Simple get attribute value sub .. no error checking
 (defun _getattvalue (block tag)
   (vl-some
     '(lambda (att)
    (cond ((eq (strcase tag) (strcase (vla-get-tagstring att))) (vla-get-textstring att)))
      )
     (vlax-invoke block 'getattributes)
   )
 )
 ;; RJP - added (66 . 1) to filter ( attributed blocks )
 (cond    ((setq
      s (ssget "_C" '(7.244 2.071) '(16.665 10.003) '((0 . "INSERT") (8 . "FTG-Iso") (66 . 1)))
    )
    (foreach en (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
      (if (and ;; If we have a value, and it does not match the filter then remove item from selection
           (setq v (_getattvalue (vlax-ename->vla-object en) "Description"))
           ;; Wcmatch example
           ;; (not (wcmatch (strcase v) "*SKSW*,*NISC*,*NIPL*,*THSC*,*WTBW*,*NRSC*,*PL*,*KASC*,*KASW*,"))
           ;; vl-string-search example ( more legible IMO )
           (not (vl-some '(lambda (x) (vl-string-search x (strcase v)))
                 '("SKSW" "NISC" "NIPL" "THSC" "WTBW" "NRSC" "PL" "KASC" "KASW")
            )
           )
          )
        (ssdel en s)
      )
    )
    ;; Highlight selection
    (sssetfirst nil s)
   )
 )
 (princ)
)
(vl-load-com)

 

Woohoo! That works great ronjonp!

 

To change the layer of the set do I put the code underneath the "(sssetfirst nil s)" line?

 

Greg

Posted

If you don't need the selection set, it's more logical to just change the layer of the items within the loop.

(if (and ;; If we have a value, and it does not match the filter then remove item from selection
	    (setq v (_getattvalue (vlax-ename->vla-object en) "Description"))
	    ;; vl-string-search example ( more legible IMO )
	    (vl-some '(lambda (x) (vl-string-search x (strcase v)))
		     '("SKSW" "NISC" "NIPL" "THSC" "WTBW" "NRSC" "PL" "KASC" "KASW")
	    )
       )
     (entmod (append (entget en) '((8 . "NewLayer"))))
   )

Posted
If you don't need the selection set, it's more logical to just change the layer of the items within the loop.

(if (and ;; If we have a value, and it does not match the filter then remove item from selection
	    (setq v (_getattvalue (vlax-ename->vla-object en) "Description"))
	    ;; vl-string-search example ( more legible IMO )
	    (vl-some '(lambda (x) (vl-string-search x (strcase v)))
		     '("SKSW" "NISC" "NIPL" "THSC" "WTBW" "NRSC" "PL" "KASC" "KASW")
	    )
       )
     (entmod (append (entget en) '((8 . "NewLayer"))))
   )

 

Thank you again, ronjonp! That was the final piece to this phase of the puzzle.

 

Greg

Posted

Glad to help.

 

See how easy that was once you provided a sample drawing? :P

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