Author Topic: ssget filtering  (Read 11430 times)

0 Members and 1 Guest are viewing this topic.

Robert98

  • Guest
ssget filtering
« on: October 19, 2010, 09:26:12 AM »
Hi friends
I want select all 3 digit number on my drawing and put them onto a list , so I wrote this codes but that have some bugs and error , please tell me what must I do ?

thank you very much

code:
Code: [Select]
;;; =================================================

(defun c:comp ()
  (prompt "\n Please select a 3 digit number for filtering :")
  (setq N (entsel))
  (setq N2 (car N))
  (setq N3 (entget N2))
  (setq LAY_N (cdr (assoc 8 N3)))    ; determine selected layer name
  (setq H_N (cdr (assoc 40 N3)))    ; determine selected text height
  (setq TXT_STYL_N (cdr (assoc 7 N3)))    ; determine style of digit text number for filtering
  (setq TXT_COLOR_N (cdr (assoc 62 N3))); determine color of digit text number for filtering
  (setq LEN_N (strlen (cdr (assoc 1 N3))))
                    ; determine length of left digit text number for filtering


;;; =================================================

  (setq    N3_filter
     (list
       (cons 0 "TEXT")
       (cons 7 TXT_STYL_N)
       (cons 8 LAY_N)
       (cons 40 H_N)
       (cons 62 TXT_COLOR_N)
       (cons 410 "MODEL")
     )                ;end of list
  )                    ;end of setq N3_filter

  (setq ss_list (ssget "X" N3_filter))    ; select all number in up filter
  (setq countr 0)            ; first counter
  (while (< countr (sslength ss_list))
    (setq en_N (ssname ss_list countr))
    (setq enlis_N (entget en_N))
    (setq val_enlist (cons (cdr (assoc 1 enlis_N))))
    (setq countr (1+ countr))


  )                    ;close while
  (princ val_enlist)            ;print on command bar made list of 3 digit numbers that found on drawing

)                    ;end defun  
                 
« Last Edit: October 19, 2010, 09:51:08 AM by CAB »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: ssget filtering
« Reply #1 on: October 19, 2010, 09:50:33 AM »
Here is an example of select you may find interesting.
Code: [Select]
;;  Sel by Type.lsp

;;  CAB 11.06.2007
;;  Get a selection set of thawed objects in current space with matching type
;;  Option to match layer too
;;  Highlights the selected items & returns the selection set
(defun c:oSel (/ fuzz ent obj layFilter Area2match lst ss ss2)
  (vl-load-com)
  (setq fuzz  0.001)
  (while
    (not
      (and
        (or (setq ent (car (entsel "\nSelect object to match object type & layer.")))
            (prompt "\nMissed, try again."))
        (setq obj (vlax-ename->vla-object ent)
              typ (cdr(assoc 0 (entget ent))))
        (or (not (vl-position typ '(""))) ; Add type excluded names here ("DIMENSION" "LEADER")
            (prompt "\nObject type not supported, try again."))
      )
    )
  )
  (initget "Yes No")
  (if (equal (getkword "\nMatch layer too? [Yes/No]<Yes>: ") "No")
     (setq layFilter '(8 . "*"))
     (setq layFilter (cons 8 (vla-get-layer obj)))
  )
  (setq ss2 (ssadd))
  (prompt "\nSelect objects or ENTER for All objects in this space.")

  (or (setq ss (ssget (list layFilter (cons 0 typ)(cons 410 (getvar "ctab")))))
      (setq ss (ssget "_All" (list layFilter (cons 0 typ)(cons 410 (getvar "ctab"))))))
  (sssetfirst)
  (print)
  (if (and ss (not(zerop(sslength ss))))
    (progn
      (prompt (strcat "\n" (itoa (sslength ss)) " Object(s) selected."))
      (cadr(sssetfirst nil ss))
    )
  )
)
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: ssget filtering
« Reply #2 on: October 19, 2010, 10:18:35 AM »
Here is a rework of your routine:
Code: [Select]
(defun c:comp (/ ELST EN ENAME I LST N3_FILTER SS)
  (if (and
        (setq en (entsel "\n Please select a 3 digit number for filtering :"))
        (setq elst (entget (car en)))
        (or (equal '(0 . "TEXT") (assoc 0 elst))
            (prompt "\nObject was not text."))
        (or (wcmatch (cdr (assoc 1 elst)) "###")
            (prompt "\nText did not contain 3 numbers."))
      )
    (progn

      ;; =================================================

      (setq N3_filter
             (list
               (cons 0 "TEXT")
               (assoc 1 elst)           ; text to match
               (assoc 7 elst)           ; style of digit text
               (assoc 8 elst)           ; selected layer name
               (assoc 40 elst)          ; selected text height
               (assoc 410 elst)
             )
      )

      (setq ss (ssget "X" N3_filter))   ; select all number in up filter
      (setq i -1)
      (while (setq ename (ssname ss (setq i (1+ i))))
        (setq elst (entget ename))
        (setq lst (cons (cdr (assoc 1 elst)) lst))
      )
      (princ lst)   ;print  list of 3 digit numbers that found on drawing
    )
   
  )
  (princ)
)                                       ;end defun       
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.

Robert98

  • Guest
Re: ssget filtering
« Reply #3 on: October 19, 2010, 11:56:51 AM »
Hi CAB
First ,I have special thanks for your tips ,your first routine is very professional for me because I beginner in autolisp and don't know about vlisp programming .so I work with second solution .
Another thanks and buy. :lol:

Dear CAB
Hi
I used second routine with many Small and very simple drawings that they had just many numbers , but after loading file and pick on a sample number the routine just returned me :
Command: comp
 Please select a 3 digit number for filtering :(400)
Command:
why !?

« Last Edit: October 19, 2010, 12:58:57 PM by Robert98 »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: ssget filtering
« Reply #4 on: October 20, 2010, 04:43:27 AM »
why !?
The function outputs a list of 3 digit numbers. In your test the list contains only one number: 400.
The filter is the problem. You should change this line:
Code: [Select]
              (assoc 1 elst)           ; EXACT text to match (but you don't want that)To:
Code: [Select]
              (cons 1 "###")           ; text to match

Robert98

  • Guest
Re: ssget filtering
« Reply #5 on: October 20, 2010, 08:30:06 AM »
Thanks Roy
I replaced your code and that give me a correct list .  :wink:
have a nice time

Robert98

  • Guest
Re: ssget filtering
« Reply #6 on: October 22, 2010, 12:23:09 PM »
Hi dear members
I have a new question !
If I want filter a string with for example N numbers or elements in my database  , I must create a function for do it , or I can use "cond" primitive in my routine, or I must change for example "######" to "##" or " "??" in any run .!
I made many functions that they are returns correct answers  in our environments but if I use of its in another routines  ,  they returned incorrect answer or nil , the finall results is bug or error or unwanted results !
please tell me which one is flexible " write a function or use  of (condo ) primitive "
I know that you are master in autocad programming , but I'm a beginner and must go up step by step , if I didn't under estand  previous stage I don't go to later stage ! , so please help me , I want algorithms , don't any supplied answers ?!! :realmad:
Please accept my apologies
thanks for your help
« Last Edit: October 22, 2010, 12:38:07 PM by Robert98 »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: ssget filtering
« Reply #7 on: October 22, 2010, 02:16:05 PM »
Not completely sure I understand what you want. In your original post you speak of 3 digits. Do you want to change your (CAB's) code so that it works on variable length digit-only texts?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: ssget filtering
« Reply #8 on: October 22, 2010, 11:44:55 PM »
Maybe this?
Code: [Select]
(defun c:comp (/ ELST EN ENAME I LST N3_FILTER SS filter)
  (setq filter "")
  (if (and
        (setq en (entsel "\n Please select a number for filtering :"))
        (setq elst (entget (car en)))
        (or (equal '(0 . "TEXT") (assoc 0 elst))
            (prompt "\nObject was not text."))
        (or (not(repeat (strlen (cdr(assoc 1 elst)))(setq filter (strcat filter "#"))))
            (wcmatch (cdr (assoc 1 elst)) filter)
            (prompt "\nText did not contain correct number of digets."))
      )
    (progn

      ;; =================================================

      (setq N3_filter
             (list
               (cons 0 "TEXT")
               (cons 1 filter)          ; text to match
               (assoc 7 elst)           ; style of digit text
               (assoc 8 elst)           ; selected layer name
               (assoc 40 elst)          ; selected text height
               (assoc 410 elst)
             )
      )

      (setq ss (ssget "X" N3_filter))   ; select all number in up filter
      (setq i -1)
      (while (setq ename (ssname ss (setq i (1+ i))))
        (setq elst (entget ename))
        (setq lst (cons (cdr (assoc 1 elst)) lst))
      )
      (princ lst)   ;print  list of 3 digit numbers that found on drawing
    )
   
  )
  (princ)
)                                       ;end defun     
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.

Robert98

  • Guest
Re: ssget filtering
« Reply #9 on: October 23, 2010, 01:32:59 PM »
Maybe this?
Code: [Select]
(defun c:comp (/ ELST EN ENAME I LST N3_FILTER SS filter)
  (setq filter "")
  (if (and
        (setq en (entsel "\n Please select a number for filtering :"))
        (setq elst (entget (car en)))
        (or (equal '(0 . "TEXT") (assoc 0 elst))
            (prompt "\nObject was not text."))
        (or (not(repeat (strlen (cdr(assoc 1 elst)))(setq filter (strcat filter "#"))))
            (wcmatch (cdr (assoc 1 elst)) filter)
            (prompt "\nText did not contain correct number of digets."))
      )
    (progn

      ;; =================================================

      (setq N3_filter
             (list
               (cons 0 "TEXT")
               (cons 1 filter)          ; text to match
               (assoc 7 elst)           ; style of digit text
               (assoc 8 elst)           ; selected layer name
               (assoc 40 elst)          ; selected text height
               (assoc 410 elst)
             )
      )

      (setq ss (ssget "X" N3_filter))   ; select all number in up filter
      (setq i -1)
      (while (setq ename (ssname ss (setq i (1+ i))))
        (setq elst (entget ename))
        (setq lst (cons (cdr (assoc 1 elst)) lst))
      )
      (princ lst)   ;print  list of 3 digit numbers that found on drawing
    )
   
  )
  (princ)
)                                       ;end defun     

Special thanks for your good tips. Your method is more flexible than my idea about use of "cond" function. 8-)

Robert98

  • Guest
Re: ssget filtering
« Reply #10 on: October 24, 2010, 02:32:22 PM »
Hi all friends and members
I have a new problem now !! , when I run dear CAB codes (final version) and pick on a 3 digit number it returns me this list : (130 134 136 138 132 139)
I put it at this small routine :

codes :

Quote
;main structure from dear Mac Lee
(setq D  (mapcar '(lambda (x)
       (* x 10))
      
     '(130 134 136 138 132 139)
     );end of mapcar
   );end of setq D
  (princ D)
  (princ)
and it gives this list : (1300 1340 1360 1380 1320 1390)
but when I use this one :

codes :

Quote
;main structure from dear Mac Lee
(setq D  (mapcar '(lambda (x)
       (* x 10))
      
     lst
     );end of mapcar
   );end of setq D
  (princ D)
  (princ)

I receive this error :
error: bad argument type: numberp: "130"
please tell me my mistakes
 :cry:

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: ssget filtering
« Reply #11 on: October 24, 2010, 03:08:41 PM »
It all depends on the variable lst. How have you initialized it?

Code: [Select]
(setq lst '(130 134 136 138 132 139))
(setq D (mapcar '(lambda (x) (* x 10)) lst)) ; => (1300 1340 1360 1380 1320 1390)

Code: [Select]
(setq lst '("130" "134" "136" "138" "132" "139"))
(setq D (mapcar '(lambda (x) (* x 10)) lst)) ; => error : bad argument type <"130"> ; expected <NUMBER> at [*]

Robert98

  • Guest
Re: ssget filtering
« Reply #12 on: October 24, 2010, 03:20:11 PM »
It all depends on the variable lst. How have you initialized it?

Code: [Select]
(setq lst '(130 134 136 138 132 139))
(setq D (mapcar '(lambda (x) (* x 10)) lst)) ; => (1300 1340 1360 1380 1320 1390)

Code: [Select]
(setq lst '("130" "134" "136" "138" "132" "139"))
(setq D (mapcar '(lambda (x) (* x 10)) lst)) ; => error : bad argument type <"130"> ; expected <NUMBER> at [*]



I receive (130 134 136 138 132 139) from Mr CAB latest routine , and at this time I like work with numbers no strings .
I want know that what differences are there between '(130 134 136 138 132 139) and lst at two mapcar functions above ?
Thanks for sticking with me .

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: ssget filtering
« Reply #13 on: October 24, 2010, 03:58:00 PM »
at this time I like work with numbers no strings
The problem is that the lst variable inside CAB's function contains strings not numbers!

To verify this change this line:
Code: [Select]
      (princ lst)   ;print  list of 3 digit numbers that found on drawingTo:
Code: [Select]
      ([color=red]print[/color] lst)   ;print  list of 3 digit numbers that found on drawing
You need to convert the strings to numbers before any mathematical operations. Change this line:
Code: [Select]
        (setq lst (cons (cdr (assoc 1 elst)) lst))To:
Code: [Select]
        (setq lst (cons (atoi (cdr (assoc 1 elst))) lst))

Robert98

  • Guest
Re: ssget filtering
« Reply #14 on: October 25, 2010, 08:07:44 AM »
at this time I like work with numbers no strings
The problem is that the lst variable inside CAB's function contains strings not numbers!

To verify this change this line:
Code: [Select]
      (princ lst)   ;print  list of 3 digit numbers that found on drawingTo:
Code: [Select]
      ([color=red]print[/color] lst)   ;print  list of 3 digit numbers that found on drawing
You need to convert the strings to numbers before any mathematical operations. Change this line:
Code: [Select]
        (setq lst (cons (cdr (assoc 1 elst)) lst))To:
Code: [Select]
        (setq lst (cons (atoi (cdr (assoc 1 elst))) lst))

Very thanks Roy for your helps

I've replaced your codes and the problem was solved .I thought that Since our function Will search the database for numbers so the results in the numbers form to be returned not in the form of strings moreover, I had read that members of string's list must have been surrounded with " , so I make mistakes, and I repeat it .I'm feeling sorry these and I hope you forgive me .

Thanks again from you and other friends , especially Mr.CAB  :wink: