Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

find string # matches

19 REPLIES 19
Reply
Message 1 of 20
Migumby
589 Views, 19 Replies

find string # matches

Hello,

I'm looking for a lisp routine that will draw a line between all matching numbers that are repeated 3 times or more in a selection.

I'm using AutoCad 2012.

thanks

19 REPLIES 19
Message 2 of 20
hgasty1001
in reply to: Migumby

Hi,

 

Please attach an example drawing and a description of the task, becouse to connect, say 4 points, can be made with 3,4,5 or even 6 edges, like a complete graph (Complete Graph) .

 

Gaston Nunez

Message 3 of 20
Migumby
in reply to: hgasty1001

I guess it doesn’t really need to have lines.

I just want the #’s highlighted somehow like color change.

I attached an example drawing of what I’m trying to do.

I need a routine that will double check me if I repeat connection points.

thanks

Message 4 of 20
Migumby
in reply to: Migumby

i fixed the example to explain better what I'm looking for.

thanks

Message 5 of 20
hgasty1001
in reply to: Migumby

Hi,

 

While someone try to figure a lisp solution, you can try with dataextraction command  or find command, the former will show you a list of entities with count, in this case a text object and its value (the text itself), find will er...find the text and allow interactive visual of the findings.

 

Gaston Nunez

Message 6 of 20
Migumby
in reply to: hgasty1001

Thanks for the ideas, but sometimes these numbers go into the hundreds and it gets very difficult to keep them organized.

I appriciate any help that I can get.

thanks

Message 7 of 20
Kent1Cooper
in reply to: Migumby


@Migumby wrote:

....

I'm looking for a lisp routine that will draw a line between all matching numbers that are repeated 3 times or more in a selection.

....

I guess it doesn’t really need to have lines.

I just want the #’s highlighted somehow like color change.

....


An approach [I may take a shot at working it out later]:

 

A.  Get the User to select objects with (ssget) and a filter for Text entities [and perhaps also for Layer and/or Style and/or height, etc.].

 

B.  Start some empty text strings as variables, one for all text-content values among the selection, another for those found twice, and another for those found more than twice;

 

C.  Step through the selection, and for each one:

  1.  Extract its text content;

  2.  Check with (wcmatch) whether that's already in the all-values string, and:

    a.  if not, add it to that, plus a comma, with (strcat);

    b.  if so, check with (wcmatch) whether it's already in the twice-occurring string, and:

      i.  if not, add it there plus a comma;

      ii.  if so, add it plus a comma to the more-than-twice-occurring string [you could add another check for whether it's already there first, but you could just add it regardless];

 

D.  Use (ssget) again with the more-than-twice-occurring string as a filter for text content.  That should give you a selection set of all Text entities among the selection with content that occurs three times or more.  You can then apply (sssetfirst) to that to highlight and grip them all, or you can use CHPROP on them to change their color or other properties, or you can highlight them each with (redraw), or you can draw circles around them, or....

Kent Cooper, AIA
Message 8 of 20
Migumby
in reply to: Kent1Cooper

Thank you,

that sounds really cool, but I don't have any idea how to put it all together.

I'm really new to lisp.

thanks

Message 9 of 20
alanjt_
in reply to: Migumby

Coded quickly, but this should get you started:

 

(defun c:test (/ ss i data filter string 4ten compare ss2 match ent)
  (princ "\nSelect text with numbers to find: ")
  (if (setq ss (ssget '((0 . "MTEXT,TEXT") (1 . "#*"))))
    (progn
      (repeat (setq i (sslength ss))
        (setq data    (entget (ssname ss (setq i (1- i))))
              4ten    (assoc 410 data)
              filter  (cons (list "," (setq string (cdr (assoc 1 data)))) filter)
              compare (cons (cons string (cdr (assoc 10 data))) compare)
        )
      )
      (if (setq ss2 (ssget "_A"
                           (list '(0 . "MTEXT,TEXT")
                                 4ten
                                 (cons 1 (apply 'strcat (cdr (apply 'append filter))))
                           )
                    )
          )
        (repeat (setq i (sslength ss2))
          (setq ent  (ssname ss2 (setq i (1- i)))
                data (entget ent)
          )
          (if (and (not (ssmemb ent ss))
                   (setq match (cdr (assoc (cdr (assoc 1 data)) compare)))
              )
            (entmakex (list '(0 . "LINE") (cons 10 match) (cons 11 (cdr (assoc 10 data)))))
          )
        )
      )
    )
  )
  (princ)
)

 

Select the first line of text objects you want to see if have matches, then it will do the searching.

Message 10 of 20
Migumby
in reply to: alanjt_

it does'nt seem to just select whats in the selection window.

thanks

Message 11 of 20
alanjt_
in reply to: Migumby

I know, I figured you'd want to select the numbers you wanted to search, (the line of text at the top of your posted drawing) then it would search the drawing for duplicates. If you only want to search duplicates within a specified selection, this can be accomplished.

Message 12 of 20
Migumby
in reply to: alanjt_

I'm looking for just whats been selected.

thanks

Message 13 of 20
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
....

An approach [I may take a shot at working it out later]:

....


This seems to accomplish that:

 

(defun C:TTH ; = Triple [or more] instances of same numerical Text content Highlighter
  (/ ss all two more txt)
  (princ "\nTo highlight numerical Text with content occurring more than twice,")
  (if (setq ss (ssget '((0 . "*TEXT") (1 . "#*"))))
    (progn
      (setq all "" two "" more "")
      (repeat (sslength ss)
        (setq txt (cdr (assoc 1 (entget (ssname ss 0))))); text content
        (if (wcmatch all (strcat "*" txt "*")); seen this content before?
          (if (wcmatch two (strcat "*" txt "*")); seen it twice or more before?
            (if (not (wcmatch more (strcat "*" txt "*"))); not yet seen it more than twice?
              (setq more (strcat more txt ",")); then -- add it + comma to 3+x string
            ); if [already more than twice -- no 'else' argument]
            (setq two (strcat two txt ",")); else [not yet twice] -- add it + comma to 2x string
          ); if [twice or more]
          (setq all (strcat all txt ",")); else [not yet seen] -- add it + comma to all-contents string
        ); if [first occurrence]
        (ssdel (ssname ss 0) ss)
      ); repeat
      (sssetfirst nil (setq tth (ssget "_P" (list (cons 1 more))))); all from previous with 3+ occurrences
        ;; that grips/highlights/saves them into a 'tth' variable, but you could instead, for instance:
;;      (command "_.chprop" (ssget "_P" (list (cons 1 more))) "" "_color" 12 ""); [edit color #]
    ); progn
  ); if
); defun

Kent Cooper, AIA
Message 14 of 20
Migumby
in reply to: alanjt_

Allan,

I think that your very close to fixing my problem.

I only want to search duplicates within a specified selection.

thank you for all of your efforts.

Message 15 of 20
3wood
in reply to: Migumby

For similar task, I used to do in following steps:

Use a routine to count selected texts and list them in command window (or in a txt file if required) in a format as below:

mcb.png

 

Then you only need quickly check the numbers behind comma ",", see  if there is any number great than 3.

Then you can write these texts down, use FIND command to locate them or use QSELCTE / FILTER to select them and change their property such as colours etc.

Message 16 of 20
pbejse
in reply to: Migumby


@Migumby wrote:

Allan,

I think that your very close to fixing my problem.

I only want to search duplicates within a specified selection.

thank you for all of your efforts.


...


(princ "\nWindow selection to search:")
(if (setq ss2 (ssget (list '(0 . "MTEXT,TEXT");<--- No "_A" 4ten (cons 1 (apply 'strcat (cdr (apply 'append filter)))) ) ) )
(repeat....

 

Message 17 of 20
hmsilva
in reply to: Migumby


@Migumby wrote:

Hello,

I'm looking for a lisp routine that will draw a line between all matching numbers that are repeated 3 times or more in a selection.

I'm using AutoCad 2012.

thanks


Migumby,
if I understood correctly, perhaps something like this.
A quick one, minimally tested...

 

(defun c:test (/ ENT HND HND1 I I1 I2 NUM OSM_OLD PT PTS SS SS1 SS2)
  (prompt "\nSelect text numbers to find triplicates or more: ")
  (IF (setq ss (SSGET ":L" '((0 . "TEXT") (1 . "#*"))))
    (progn
      (setq
	osm_old	(getvar "OSMODE")
	i	0
	num	(sslength ss)
	ss2	(ssadd))
      (setvar "OSMODE" 0)
      (while (< i num)
 (setq hnd (ssname ss i))
 (setq i1 0)
 (setq ss1 (ssadd))
 (while (< i1 num)
   (setq hnd1 (ssname ss i1))
   (if
     (and (not (equal hnd hnd1))
	  (= (cdr (assoc 1 (entget hnd))) (cdr (assoc 1 (entget hnd1))))
	  (not (ssmemb hnd1 ss2))
     );; and
      (progn
        (ssadd hnd ss1)
        (ssadd hnd1 ss1)
	 (ssadd hnd1 ss2)
      );; progn
   );; if
   (setq i1 (1+ i1))
 );; while
 (if (>= (sslength ss1) 3)
   (progn
     (setq i2 0)
     (repeat (sslength ss1)
       (setq ent (ssname ss1 i2)
      i2 (1+ i2)
      pt (cdr (assoc 10 (entget ent)))
      pts (append pts (list pt))
       )
     );; repeat
     (command "pline")
     (apply 'command pts)
     (command "cl")
     (setq pts nil)
   );; progn
 );; if
 (setq ss1 nil)
 (setq i (1+ i))
      );; while
      (setvar "OSMODE" osm_old)
    );; progn
  );; if
  (princ)
);; defun

hope that helps
Henrique

EESignature

Message 18 of 20
alanjt_
in reply to: Migumby

(defun c:MatchNums (/ ss i d s p a ptLst)
  ;; find Matching Numbers withing MText/Text objects and draw connecting lines to duplicates
  ;; Match line will be drawn on layer "MATCH" with a color of "RED".
  ;; Alan J. Thompson, 2013.05.23

  (if (and (setq ss (ssget '((0 . "MTEXT,TEXT") (1 . "#*")))) (> (setq i (sslength ss)) 1))
    (progn
      (repeat i

        (setq d (entget (ssname ss (setq i (1- i))))
              s (cdr (assoc 1 d))
              p (cdr (assoc 10 d))
        )

        (if (setq a (assoc s ptLst))
          (setq ptLst (subst (cons s (cons p (cdr a))) a ptLst))
          (setq ptLst (cons (list s p) ptLst))
        )
      )

      (foreach lst ptLst
        (if (> (length lst) 2)
          (foreach p (cdr (setq lst (vl-sort (cdr lst)
                                             (function (lambda (a b) (> (cadr a) (cadr b))))
                                    )
                          )
                     )
            (entmakex (list '(0 . "LINE") '(8 . "MATCH") '(62 . 1) (cons 10 (car lst)) (cons 11 p)))
          )
        )
      )
    )
  )

  (princ)
)

 

Message 19 of 20
Migumby
in reply to: alanjt_

Great!

That fixed it!

Thank you all very much for all of your efforts.

Message 20 of 20
alanjt_
in reply to: Migumby

You're welcome.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost