Commandobill 发表于 2022-7-5 20:15:40

Way to keep it simple, Lee.
 
To reiterate what Lee's initial point was You need set your 'idx' variable else where, like this.

(defun c:SEL_BLOCKS (/ ss);; FN by lpseifert @ http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/how-to-filter-xrefs-out-from-ssget-list-cons-0-quot-insert-quot/m-p/2852572#M293570(setq idx -1)         (if (setq ss (ssget (list (cons 0 "INSERT"))))                              ((progn                   (repeat (sslength ss)                     (setq en (ssname ss (setq idx (1+ idx)))                           obj (vlax-ename->vla-object en)                           )                     (if                           (vlax-property-available-p obj 'Path)                           (progn                               (ssdel en ss)                               (setq idx (1- idx))                     )                     )                   )               )               (princ (strcat "\nNumber of found Blocks : < " (itoa (sslength ss)) " >")))               (princ "\n***Nothing Selected***")         )       (sssetfirst nil ss)   (princ))

3dwannab 发表于 2022-7-5 20:17:55

Thanks this creates a selection set. after it's run it selects nothing. Is it suppose to?
 
 
Thanks, this now creates an error when blocks have been selected. The opposite of what was happening.

Number of found Blocks : < 3 >; error: no function definition: nil

David Bethel 发表于 2022-7-5 20:22:50

 
Looks good Lee.
 
Is there no longer a limit to the string length of a filter ?
 
-David

3dwannab 发表于 2022-7-5 20:25:45

Please forgive my blatant disregard for learning anything. Lunch break has helped me figure it out.
Working code to select blocks only. Thanks Lee Mac.
 

(defun c:sel_blocks ( / def lst sel ); FN by Lee Mac http://www.cadtutor.net/forum/showthread.php?92638-Simple-fix-%28LISP-noob%29-Syntax-problem&p=633824&viewfull=1#post633824   ;; Iterate over the block table and compile a list of xref blocks to exclude   (while (setq def (tblnext "block" (not def)))       (if (= 4 (logand 4 (cdr (assoc 70 def))))         (setq lst (vl-list* "," (cdr (assoc 2 def)) lst))       )   )   ;; Attempt to retrieve a selection of blocks (but not xrefs)   (if (setq sel (ssget (cons '(0 . "INSERT") (if lst (vl-list* '(-4 . "")))))))       (princ (strcat "\nNumber of blocks: " (itoa (sslength sel))))       (princ "\n***Nothing Selected***")   )   (sssetfirst nil sel)   (princ))How can I expand on this to select only annotative blocks. Where can I find good info for this?
 
EDIT: I have a code for the selection of non associative hatches:

(setq ss (ssget '((0 . "HATCH") (-4 . "=") (71 . 0))))What fn has (-4 . "=") (71 . 0)
 
Do they relate to the standard filter dialog in any way?

Lee Mac 发表于 2022-7-5 20:27:11

 

 
 
No problem - as you've gathered, the sssetfirst function will highlight & grip a given selection set, though, even without this function and without highlighting & gripping the selection set, Select > Previous will still acquire the selection set obtained by ssget.
 
 
Thanks David
 
 
A character limit for DXF string groups in the selection filter list may still exist, though, I am not sure exactly what that limit may be as I have not encountered issues up to now.
 
Of course, an alternative approach to circumvent any potential character limit could be simply:

(defun c:sel_blocks ( / def lst sel )   ;; Iterate over the block table and compile a list of xref blocks to exclude   (while (setq def (tblnext "block" (not def)))       (if (= 4 (logand 4 (cdr (assoc 70 def))))         (setq lst (cons (assoc 2 def) lst))       )   )   ;; Attempt to retrieve a selection of blocks (but not xrefs)   (if (setq sel (ssget (cons '(0 . "INSERT") (if lst (append '((-4 . "")))))))       (princ (strcat "\nNumber of blocks: " (itoa (sslength sel))))       (princ "\nNothing selected.")   )   (princ))
 
Annotative data complicates matters somewhat - consider the following:

(defun c:sel_blocks ( / ano def sel xrf )   (while (setq def (tblnext "block" (not def)))       (setq blk (assoc 2 def))       (cond         (   (= 4 (logand 4 (cdr (assoc 70 def))))               (setq xrf (cons blk xrf))         )         (   (= 1                   (cdr                     (assoc 1070                           (reverse                               (cadr                                 (assoc -3                                       (entget                                           (cdr                                             (assoc 330                                                   (entget                                                       (tblobjname "block" (cdr blk))                                                   )                                             )                                           )                                       )                                 )                               )                           )                     )                   )               )               (setq ano (cons blk ano))         )       )   )   (if       (setq sel         (ssget               (append '((0 . "INSERT"))                   (if ano                     (append                        '((-4 . ""))                     )                   )                   (if xrf                     (append                        '((-4 . ""))                     )                   )               )         )       )       (princ (strcat "\nNumber of blocks: " (itoa (sslength sel))))       (princ "\nNothing selected.")   )   (sssetfirst nil sel)   (princ))
 
You may find my ssget function reference helpful in this regard - though, in your example, the '(-4 . "=") is not actually required as the ssget filter list uses an implicit AND logic (that is, by default every item in the list must match).

David Bethel 发表于 2022-7-5 20:33:11

 
 
I still see references of 'approximately 500 character limit' for wcmatch and that ssget follows it's rules.
 
-David

3dwannab 发表于 2022-7-5 20:34:02

Thanks, I've attached an example I've tested on. Saved in 2010 ACAD. The code you posted selects non-Anno blocks in this example.
 
Test Drawing Annotative Verus Non Anno Blocks.dwg
 
So, maybe would the process be easier say if I just wanted to select all annotative objects instead using something like:

(setq ss1 (ssget "all" ))and then apply a filter after this to select Anno objects. ACAD Help does not list these filters completely or am I missing something?
 
This will complete my quest for quick selection tools.

Lee Mac 发表于 2022-7-5 20:38:13

 
After a quick test, I'm not seeing that limit with wcmatch:

_$ (setq str "x")"x"_$ (repeat 500 (setq str (strcat "x" str)))"xxxxxxxxxxx...xxxxxxxxxxxxx"_$ (strlen str)501_$ (wcmatch str "*x*")T_$ (repeat 500 (setq str (strcat "a" str)))"aaaaaaaaaaaaaaa...xxxxxxxxxxx"_$ (strlen str)1001_$ (wcmatch str "*x*")T_$ (repeat 500 (setq str (strcat "b" str)))"bbbbbbbbbbbb...xxxxxxxxxxxxxxx"_$ (strlen str)1501_$ (wcmatch str "*x*")T

David Bethel 发表于 2022-7-5 20:41:30

From 2000 -> 2004 help and 2012 Autodesk exchange
 
 
Go figure    -David

Lee Mac 发表于 2022-7-5 20:44:42

 
Sorry, I had overlooked a few things:

(defun c:sel_blocks ( / blk def lst sel )   (while (setq def (tblnext "block" (not def)))       (setq blk (cdr (assoc 2 def)))       (cond         (   (= 4 (logand 4 (cdr (assoc 70 def))))               (setq lst (cons (cons 2 (LM:escapewildcards blk)) lst))         )         (   (/= 1                   (cdr                     (assoc 1070                           (reverse                               (cadr                                 (assoc -3                                       (entget                                           (cdr                                             (assoc 330                                                   (entget                                                       (tblobjname "block" blk)                                                   )                                             )                                           )                                          '("AcadAnnotative")                                       )                                 )                               )                           )                     )                   )               )               (setq lst (cons (cons 2 (LM:escapewildcards blk)) lst))         )       )   )   (if lst       (if (setq sel (ssget (append '((0 . "INSERT") (-4 . "")))))         (princ (strcat "\nNumber of blocks: " (itoa (sslength sel))))         (princ "\nNothing selected.")       )       (princ "\nNo valid blocks found in drawing.")   )   (sssetfirst nil sel)   (princ));; Escape Wildcards-Lee Mac;; Escapes wildcard special characters in a supplied string(defun LM:escapewildcards ( str )   (vl-list->string       (apply 'append         (mapcar            '(lambda ( c )                   (if (member c '(35 64 46 42 63 126 91 93 45 44))                     (list 96 c)                     (list c)                   )               )               (vl-string->list str)         )       )   ))
Escape Wildcards function from here.
 
Note that the above code will still not be compatible with annotative dynamic blocks, as these will require yet more checks.
 
 
Correct - the developer documentation in AutoCAD is not complete.
页: 1 [2]
查看完整版本: Simple fix (LISP noob) Syntax