Select numbers by number value - greater than, less than

Select numbers by number value - greater than, less than

mpa-la
Advocate Advocate
5,219 Views
16 Replies
Message 1 of 17

Select numbers by number value - greater than, less than

mpa-la
Advocate
Advocate

This is probably easy, but I can't find a solution anywhere.  If I have a bunch of text or mtext entities in my drawing that are all numbers, I would like a way to select a subset based on the numbers so I can put them all on a different layer.  For example, there are 500 separate text entities that are various numbers from 1 to 10000, and I would like to select everything less than or equal to 463.  The number the selection is based on will change, so I need to input it each time.  Thanks in advance!!

0 Likes
Accepted solutions (1)
5,220 Views
16 Replies
Replies (16)
Message 2 of 17

jdiala
Advocate
Advocate
(defun C:test (/ ss n i v)
(if
  (setq n (getint "\nEnter number:")
        ss (ssget ":L" '((0 . "*TEXT")))
  )
  (repeat (setq i (sslength ss))
    (if 
      (and
        (>= n  (atoi (setq v (cdr (assoc 1 (entget (setq e (ssname ss (setq i (1- i))))))))))
        (not (wcmatch v "*@*"))
      )
      (vla-put-layer (vlax-ename->vla-object e) "NewLayer") ;;your layer here
    )
  )
)
(princ)
)
0 Likes
Message 3 of 17

ВeekeeCZ
Consultant
Consultant

Try this... and test it a little (I did slightly). You should be able to select any range you want...

 

Spoiler
(vl-load-com)

(defun c:SelectTextRange ( / o1 v1 o2 v2 ss ed no s1)

  (initget "L LE E GE G")
  (setq o1 (cond ((getkword "\nSelect operation for first condition [L </LE <=/E =/GE >=/G >] <Equal>: "))
		  ("E")))
  (initget 1)
  (setq v1 (getdist (strcat "\n" (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
				      '("Less than" "Less than or equal to" "Equal to" "Greater than" "Greater than or equal to"))
			    ": ")))
  (if (and (/= o1 "E")
	   (not (initget "L LE E GE G"))
	   (setq o2 (getkword (strcat "Select operation for first condition [" (if (wcmatch o1 "L*") "GE >=/G >" "L </LE <=") "] <no second condition>: ")))
	   )
    (setq v2 (getdist (strcat "\n" (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
					'("Less than" "Less than or equal to" "Equal to" "Greater than" "Greater than or equal to"))
			      ": "))))

  (princ "\nSelext text or Enter for ALL,")
  (if (setq s1 (ssadd)
	    ss (cond ((ssget '((0 . "*TEXT"))))
		     ((ssget "_A" '((0 . "*TEXT"))))))
    (repeat (setq i (sslength ss))
      (setq ed (entget (setq en (ssname ss (setq i (1- i))))))
      (setq no (atof (cdr (assoc 1 ed))))
      (if (and (apply (read (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
				 '("<" "<=" "=" ">=" ">")))
		      (list no v1))
	       (if v2
		 (apply (read (nth (vl-position o2 '("L" "LE" "E" "GE" "G"))
				   '("<" "<=" "=" ">=" ">")))
			(list no v2))
		 T)
	       )
	(ssadd en s1))))
  (if (entget (ssname s1 0)) (sssetfirst nil s1))
  (princ)
)
Message 4 of 17

mpa-la
Advocate
Advocate

Didn't work.  Wouldn't allow decimals, and when I tried a whole number it cancels out saying "automation error. key not found", even when I made sure that the number I gave it was one of the ones to be selected.

 

Here's a screenshot of a typical range of numbers I deal with.

 

Clipboard01.jpg

0 Likes
Message 5 of 17

mpa-la
Advocate
Advocate

Worked perfect BeekeeCZ!!  Two questions though, I almost always use less than, how do I change it to make that the default?  After I enter the number, it says again "select operation for first condition", which I can skip past, and it works, but what is that supposed to do?

0 Likes
Message 6 of 17

ВeekeeCZ
Consultant
Consultant
Accepted solution

Fixed version.

 

(defun c:SelectTextRange ( / o1 v1 o2 v2 ss ed no s1)

  (initget "L LE E GE G")
  (setq o1 (cond ((getkword "\nSelect operation for first condition [L </LE <=/E =/GE >=/G >] <LessThan>: "))
		  ("L")))
  (initget 1)
  (setq v1 (getdist (strcat "\n" (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
				      '("Less than" "Less than or equal to" "Equal to" "Greater than" "Greater than or equal to"))
			    ": ")))
  (if (and (/= o1 "E")
	   (not (initget "L LE E GE G"))
	   (setq o2 (getkword (strcat "Select operation for second condition [" (if (wcmatch o1 "L*") "GE >=/G >" "L </LE <=") "] <no second condition>: ")))
	   )
    (setq v2 (getdist (strcat "\n" (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
					'("Less than" "Less than or equal to" "Equal to" "Greater than" "Greater than or equal to"))
			      ": "))))

  (princ "\nSelext text or Enter for ALL,")
  (if (setq s1 (ssadd)
	    ss (cond ((ssget '((0 . "*TEXT"))))
		     ((ssget "_A" '((0 . "*TEXT"))))))
    (repeat (setq i (sslength ss))
      (setq ed (entget (setq en (ssname ss (setq i (1- i))))))
      (setq no (atof (cdr (assoc 1 ed))))
      (if (and (apply (read (nth (vl-position o1 '("L" "LE" "E" "GE" "G"))
				 '("<" "<=" "=" ">=" ">")))
		      (list no v1))
	       (if v2
		 (apply (read (nth (vl-position o2 '("L" "LE" "E" "GE" "G"))
				   '("<" "<=" "=" ">=" ">")))
			(list no v2))
		 T)
	       )
	(ssadd en s1))))
  (if (entget (ssname s1 0)) (sssetfirst nil s1))
  (princ)
)

 

Message 7 of 17

mpa-la
Advocate
Advocate

Oh, ok that's cool!  Thanks for this, it's exactly what I needed.

0 Likes
Message 8 of 17

symoin
Enthusiast
Enthusiast

Can this code be modified for using with alphanumeric text values. Such that the word has text at beginning and numbers at the end.

0 Likes
Message 9 of 17

Kent1Cooper
Consultant
Consultant

@symoin wrote:

Can this code be modified ... the word has text at beginning and numbers at the end.


One way [minimally tested]:

  ....

  (setq ed (entget (setq en (ssname ss (setq i (1- i))))))

  (setq str (cdr (assoc 1 ed)))

  (setq no (atof (substr str (1+ (strlen (vl-string-right-trim ".-0123456789" str))))))

  (if (and (apply (read ....

  ....

Kent Cooper, AIA
0 Likes
Message 10 of 17

Ten_Tol
Explorer
Explorer

I'm struggling with this second issue of having text in front of the number.

It gives a bad argument message.

An example of my MText:

L5U6006
BOS 36.047
CV 0.248
FCL 35.795
FTC 3.300
FFL 32.495
FV 0.476
TOC 32.019

I want to have all CV's under 0.250 selected or all FV under 0.480 selected.

 

 

 

0 Likes
Message 11 of 17

Kent1Cooper
Consultant
Consultant

@Ten_Tol wrote:

I'm struggling with this second issue of having text in front of the number.

It gives a bad argument message.

....

I want to have all CV's under 0.250 selected or all FV under 0.480 selected.


If you ignore the CV / FV limitation on the text part, does my suggested modification find all those with the right numerical relationship to a specified value?  What exactly is the bad argument message?

 

It would probably help if you post the actual code you're using and a small sample drawing.  My suggested modification seems to work in getting the numerical part to sort by, whether or not there's a space before the numerical part of the text string:

Command: (setq str "L5U6006")
Command: (setq no (atof (substr str (1+ (strlen (vl-string-right-trim ".-0123456789" str))))))
6006.0

Command: (setq str "FV 0.476")
Command: (setq no (atof (substr str (1+ (strlen (vl-string-right-trim ".-0123456789" str))))))
0.476

Kent Cooper, AIA
0 Likes
Message 12 of 17

Sea-Haven
Mentor
Mentor

I have used this often by Lee-mac so will return number.

 

 

 

 

;;-------------------=={ Parse Numbers }==--------------------;;`
;;                                                            ;;
;;  Parses a list of numerical values from a supplied string. ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  s - String to process                                     ;;
;;------------------------------------------------------------;;
;;  Returns:  List of numerical values found in string.       ;;
;;------------------------------------------------------------;;

(defun LM:ParseNumbers ( s )
  (
    (lambda ( l )
      (read
        (strcat "("
          (vl-list->string
            (mapcar
              (function
                (lambda ( a b c )
                  (if
                    (or
                      (< 47 b 58)
                      (and (= 45 b) (< 47 c 58) (not (< 47 a 58)))
                      (and (= 46 b) (< 47 a 58) (< 47 c 58))
                    )
                    b 32
                  )
                )
              )
              (cons nil l) l (append (cdr l) (list nil))
            )
          )
          ")"
        )
      )
    )
    (vl-string->list s)
  )
)

 

 

 

 

so LU5A6006 would return (5 6006) which is both numbers but could use (last to check for 6006 or (car for prefix 5.

 

 

0 Likes
Message 13 of 17

Ten_Tol
Explorer
Explorer

I might not have been clear enough, the text I sent is a label for a single point and there are many.

See sample data attached.

 Z9E3zK5E's code works on a simple numeric sample, and I added your edit, which then returns the error message: 
; error: bad argument type: (or stringp symbolp): nil

 

 

0 Likes
Message 14 of 17

Ten_Tol
Explorer
Explorer

Although in this sample some numbers seem to be constant, along the whole dataset they do vary.

0 Likes
Message 15 of 17

ВeekeeCZ
Consultant
Consultant

@Ten_Tol wrote:

I might not have been clear enough, the text I sent is a label for a single point and there are many.

See sample data attached.

 Z9E3zK5E's code works on a simple numeric sample, and I added your edit, which then returns the error message: 
; error: bad argument type: (or stringp symbolp): nil

 

 


 

Start a new thread. You can link this one. But your case is too specific. I'll post a solution there.

0 Likes
Message 16 of 17

Kent1Cooper
Consultant
Consultant

@Ten_Tol wrote:

....I want to have all CV's under 0.250 selected or all FV under 0.480 selected.....

....the text I sent is a label for a single point and there are many.

....


So it's a bunch of lines with different prefixes and number values within a single Mtext object.  In that case, what would it mean to have "all CV's under 0.250 selected or all FV under 0.480 selected"?  That's what made me think each line of your original list would be a separate Text [or Mtext] object.  You can't "select" a portion within an Mtext object, if by that you mean what object selection typically means in AutoCAD.  So if you want the entire Mtext object selected, what if its CV value is in the target range but its FV is not, or vice versa?  And in text editing, you can't select more than one non-adjacent portions within a larger Text/Mtext object at the same time.

Kent Cooper, AIA
0 Likes
Message 17 of 17

Ten_Tol
Explorer
Explorer

Given the specifics I started a new thread as @ВeekeeCZ recommended. I hope that clarifies the goal @Kent1Cooper.

 

Select numbers by number value - greater than, less than if there is a prefix text - Autodesk Commun...

 

N

0 Likes