Comatosis 发表于 2022-7-6 08:58:28

Utilizing AutoCAD's FIND

Hello all,
 
I'm trying to come up with a lisp routine to do something I've been doing so far with the find feature.Essentially, I'm searching for a string of text in block attributes and in a single, somewhat large MTEXT object--large enough for its content to be split into multiple "type 3" group codes (sorry for the poor description, I'm a lisp noob ).For those of you in construction design/drafting, I'm checking to make sure that I'm not missing any keyed notes or their references in my drawings.
 
The find feature gets me close to what I want, but ideally I'd like to be able to just spit out a table that tells me whether or not I'm missing keyed notes/references.I imagine there should be a way to replicate the functionality of Find in lisp such that I can tweak the code to suit my needs.
 
Unfortunately, I don't have any code to share at the moment because I'm home and all my stuff is at work.Plus, I started messing with lisp literally yesterday and am a complete novice.I might swing by the office later on and show you guys what I've been working on, but in the meantime I figured I'd check with the pros whether or not this is even doable in the first place.
 
Thanks in advance.

Lee Mac 发表于 2022-7-6 09:03:19

Hi Comatosis, welcome to the CADTutor forums
 
A little overkill for your task, but you could use my Batch Find & Replace program which may be found here with the 'Search Only' option ticked to produce a report detailing the occurrences of your search strings.
 
AFAIK, there is no way to call the Find command from within LISP, so you would have to create your own Find function. This can be accomplished using such functions as vl-string-search, vl-string-subst, wcmatch, substr, etc. But there are other factors to consider such as formatting codes embedded in MText strings. I've spent many hours trying to overcome such difficulties with my BFind program, which should be successfully with all but the most heavily formatted objects.
 
Hope this helps,
 
Lee

Comatosis 发表于 2022-7-6 09:06:45

Thanks for the program and the suggestions.I'll keep trying to write this up on my own to get the practice, heh.
 
Speaking of which, is there a way to gather up all the group code 3 attributes/subentities (or whatever they're called) and combine them into one?
This is more or less what I was trying to do:
 

(setq entList (entget (car (entsel))));choose the MTEXT(setq ent_text (assoc 3 entList))
 
But all I could get into ent_text was the first one (or multiple copies of the first one after trying to use a foreach loop).How can I tell it to move on to the next group code 3 items and add them to ent_text?The way I was envisioning this was first making a huge list/string with all the text and then extracting the substrings I want (assuming it lets me use wildcards) into another list that I would then manipulate into a table or output of sorts.

pBe 发表于 2022-7-6 09:08:58

We are using Architectural/Engineering units working with MTEXTS formatting .
 
Try changing all 1/4" to 3/8" with stack properties turned ON using _find
 
EDIT:
Apparently it doesnt work with Bfind as well
 
Lee,
 
Is there a way to include this option your code? for the meantime i'll try to write a routine for this if i can.
 
Cheers
 
 
 
 
 
 
1/4
1/4

Lee Mac 发表于 2022-7-6 09:12:55

 
Yeah, there are still some bugs with stacking formatting codes

Lee Mac 发表于 2022-7-6 09:15:21

 
You could use a 'massoc' function, which may be something along the lines of:
 

(defun mAssoc ( key lst )   (apply 'append (mapcar '(lambda ( x ) (if (eq key (car x)) (list (cdr x)))) lst)))Or, recursively:
 

(defun mAssoc ( key lst / item )   (if (setq item (assoc key lst))       (cons (cdr item) (mAssoc key (cdr (member item lst))))   ))Example:
 

_$ (setq l '((1 . "ABC") (2 . "DEF") (3 . "GHI") (2 . "JKL") (2 . "MNO")))((1 . "ABC") (2 . "DEF") (3 . "GHI") (2 . "JKL") (2 . "MNO"))_$ (mAssoc 2 l)("DEF" "JKL" "MNO")So, for combining the strings:
 

_$ (apply 'strcat (mAssoc 2 l))"DEFJKLMNO"
 
Or, you could construct the string whilst iterating through the entity data:
 

(defun gettextstring ( ent / str )   (setq str "")   (foreach x (entget ent)       (if (member (car x) '(1 3))         (setq str (strcat str (cdr x)))       )   )   str)
 

(if (setq en (car (entsel)))   (gettextstring en))

Comatosis 发表于 2022-7-6 09:18:28

Maaaan, that response is completely awesome.I'll see about heading to work tomorrow and coming up with something.My guess is I'll be back for help soon afterwards.
 
Thanks a lot for the help.

irneb 发表于 2022-7-6 09:22:06

The old way of getting to same named assoc items would be to use the member function. It basically returns the list starting from the first occurrence of the item. Then you get the "remainder" of the list with cdr. And then performing an assoc again.
 
Lee's suggestion of using the massoc (user defined function) helps by extracting all code 3 (say) tags. Then you could use a foreach on that.
 
In both cases you'd then use strcat to concatenate them into a single string. Remember to split into multiple 3 codes of 255 (max length) again if you then want to entmake or entmod.

pBe 发表于 2022-7-6 09:26:04

 
Here's a draft
 

(defun c:FindFrac(/ aDoc OldFrac NewFrac objs sstr strt str _old _new )(vl-load-com)   (setq aDoc (vla-get-activedocument (vlax-get-acad-object)))   (cond ((and       (setq OldFrac (getstring "\nEnter Fraction to Replace: "))       (setq NewFrac (getstring "\nEnter New Fraction to Substitute: "))       (ssget ":L" '((0 . "MTEXT")))            (vlax-for                   txts(setq objs (vla-get-activeselectionset aDoc))                  (setq sstr (vla-get-textstring txts) strp 1)                  (while                        (setq strt (vl-string-search "\\S" sstr strp))                           (setq _old OldFrac _new NewFrac)                           (setq str(substr (setq val(substr sstr                                                                   (+ strt 3)))                                                1                                                (vl-string-search ";" val)))                           (if (vl-string-search "#" str)                                 (setq _new (vl-string-subst "#" "/" _new)                                       _old (vl-string-subst "#" "/" _old)))                           (if (equal _old str)                                 (progn                                       (setq sstr (vl-string-subst                                                          _new                                                          str                                                          sstr))                                       (vla-put-textstring txts sstr))                                 )                           (setq strp (+ strt 3))                           )                  )            (vla-delete objs)         )               )            )            (princ)   )
 
command: _FindFrac
Enter Fraction to Replace: 1/8
Enter New Fraction to Substitute: 3/4
select objects:
 
I works exclusively on MTEXT with stacked format. (horizonatl/diagonal)
 
You may wonder what this line is for (setq _old OldFrac _new NewFrac). some of our guys here tends to combine diagonal and vertical stacking on one pharagraph/sentence. the value "/" will be change to "#" once the if statement is true and revert back to "/" after the loop (its one or the other)
 
For your comments and suggestions.
Need you guys to try it out so i can make improvements...
 
Cheers

Lee Mac 发表于 2022-7-6 09:27:07

 
You're very welcome, glad it helps
页: [1] 2
查看完整版本: Utilizing AutoCAD's FIND