Does anyone know of an autolisp that will convert every non text item (like an attribute or mtext) to just be a text item? I currently have a program that is pulling all the text items out of my drawing and it is missing all of the mtext items.
I appreciate the help.
Thank you,
Brad Meissner
Solved! Go to Solution.
Solved by Rx3&43. Go to Solution.
EXPLODE command will convert mtext to text.
For blocks with attributes BURST cpmmand will convert them to text.
That being said, it would probably be easier to edit your program to pick up mtext and attributes as well as text.
The way that my current program runs is it identifies all of the text from three different layers and places them in seperate files and sorts them alpanumerically. So it is a lot going on in a single program so I was hoping I could maybe have it written as a seperate program. Do you know of anything like this or do you think it would be pretty easy to put into my program. If need be I can post the prgram I am currently using.
I don't see any problem adding it to your current program. Before the part that selects TEXT objects, you'll need to add something like this for MTEXT:
(if (setq ss (ssget "_X" '((0 . "MTEXT")(8 . "*"))));edit "*" to select MTEXT only on specific layer(s)
(progn
(setq x 0)
(while (< x (sslength ss))
(command "._EXPLODE" (ssname ss x))
(setq x (1+ x))
)
)
)
And this for ATTRIBUTES, which creates a TEXT object for every attribute:
(if (setq ss (ssget "_X" '((0 . "INSERT")(66 . 1)))) ;selects blocks with non-constant attributes
(progn
(setq x 0 sst (ssadd))
(while (< x (sslength ss))
(setq ne (entnext (ssname ss x))
x (1+ x)
)
(while (and ne (= (cdr (assoc 0 (setq ned (entget ne)))) "ATTRIB"))
(setq ned (reverse (member (assoc 210 ned)(reverse ned)))
ned (append ned '((100 . "AcDbText")(73 . 0)))
ned (subst '(0 . "TEXT")(assoc 0 ned) ned)
ne (entnext ne)
)
(entmake ned)
(ssadd (entlast) sst)
)
)
)
)
After your program selects TEXT, if you want to erase all TEXT created for ATTRIBUTES add the following line of code:
(if sst (command "._ERASE" sst ""))
I am having trouble inserting it into my program correctly. I was hoping you could help me out. The command srtan I use to sort the data is a seperate lisp if you need that let me know. Not sure where to add it or how to add it.
(defun prinFile(FileName ListName Repeater)
(setq fName(strcat FileName (substr (getvar "dwgname")1 (-(strlen (getvar "dwgname"))4 )) ".txt" ))
(setq fName (strcat "C:\\Documents and Settings\\Blmeissn\\Desktop\\" fName))
(if (setq fil(open fName "w"))
(progn
(foreach a ListName
(princ (strcat "\nOutput To File " fName ": " a))
(repeat repeater
(princ a fil)
(princ "\n" fil)
)
)
(close fil)
)
(alert (strcat "\nError - Could not create file: " fName))
)
)
;define program - listing your variable names here
; resets them to nil after the program finishes
;;;--- Main Application
(defun C:ESBTEXT2(/ lts ernote filen fil eset en enlist cntr)
(setq rep (getint "Please enter the number of times the wire number should output: "))
;;;--- Setup three list to hold the data
(setq TBNOList(list) WIRENOList (list) DEVIDList(list))
;turn echo off
(setvar "cmdecho" 0)
;get ltscale (Note: ltscale should always equal dimscale)
(setq lts(getvar "ltscale"))
;set the exit note to successful
(setq ernote "\n....ESBTEXT Complete.")
;if ssget returns a valid selection set
(if
(setq eset
(ssget "X"
'(
(-4 . "<OR")
(8 . "TBNO")
(8 . "WIRENO")
(8 . "DEVID")
(-4 . "OR>")
)
)
)
;progn necessary for multiple statements inside an if statement
(progn
;set the entity counter to zero [the first entity in a set is zero]
(setq cntr 0)
;step through each entity in the selection set
(while (< cntr (sslength eset))
;get the entity name indexed by cntr
(setq en(ssname eset cntr))
;get the DXF group codes for the entity
(setq enlist(entget en))
;check the group code 0 to see if entity type = TEXT
(if(= "TEXT" (cdr(assoc 0 enlist)))
;progn necessary for multiple statements inside an if statement
(progn
;get the text string from the entity's DXF Group Code 1
(setq str(cdr(assoc 1 enlist)))
;;;--- Add it to the appropriate list
(cond
((= (cdr(assoc 8 enlist)) "TBNO") (setq TBNOList (append TBNOList (list str))))
((= (cdr(assoc 8 enlist)) "WIRENO")(setq WIRENOList(append WIRENOList (list str))))
((= (cdr(assoc 8 enlist)) "DEVID") (setq DEVIDList(append DEVIDList (list str))))
)
) ;close the if progn
) ;close the if statement
;increment the counter to get the next entity
(setq cntr(+ cntr 1))
) ;close the while loop
;;;--- Sort the list
(setq TBNOList (srtAN TBNOList))
(setq WIRENOList (srtAN WIRENOList))
(setq DEVIDList (srtAN DEVIDList))
;;;--- Print the list (parameters = [FileName Prefix] [Name of List] [Print Repeat]
(prinFile "TBNO_" TBNOList 1)
(prinFile "WIRENO_" WIRENOList Rep)
(prinFile "DEVID_" DEVIDList 1)
);progn
);if
;turn the command echo back on
(setvar "cmdecho" 1)
;clear the command line
(princ "\n")
;supress last echo
(princ)
)
I appreciate the help,
Brad Meissner
Forget previous code, I've edited your C:ESBTEXT2 to get MTEXT and ATTRIBUTE string values. Try this out.
(defun C:ESBTEXT2(/ lts ernote filen fil eset en enlist cntr et ne ned) (setq rep (getint "Please enter the number of times the wire number should output: ")) ;;;--- Setup three list to hold the data (setq TBNOList(list) WIRENOList (list) DEVIDList(list)) ;turn echo off (setvar "cmdecho" 0) ;get ltscale (Note: ltscale should always equal dimscale) (setq lts(getvar "ltscale")) ;set the exit note to successful (setq ernote "\n....ESBTEXT Complete.") ;if ssget returns a valid selection set (if (setq eset (ssget "X" '( (-4 . "<OR") (8 . "TBNO") (8 . "WIRENO") (8 . "DEVID") (-4 . "OR>") ) ) ) ;progn necessary for multiple statements inside an if statement (progn ;set the entity counter to zero [the first entity in a set is zero] (setq cntr 0) ;step through each entity in the selection set (while (< cntr (sslength eset)) ;get the entity name indexed by cntr (setq en(ssname eset cntr)) ;get the DXF group codes for the entity (setq enlist(entget en)et (cdr (assoc 0 enlist))) ;check the group code 0 to see if entity type = TEXT (if (cond ((= et "TEXT")(setq str (cdr (assoc 1 enlist))))((= et "MTEXT");COMBINE GROUP 3's AND GROUP 1's INTO ONE STRING(setqstr (vl-remove-if-not '(lambda (q)(or (= (car q) 3)(= (car q) 1))) enlist)str (apply 'strcat (mapcar 'cdr cs))))((and (= et "INSERT")(= (cdr (assoc 66 enlist)) 1))(setq ne (entnext en))(while (and ne (= (cdr (assoc 0 (setq ned (entget ne)))) "ATTRIB"))(setq str (cdr (assoc 1 ned))ne (entnext ne))(cond((= (cdr(assoc 8 enlist)) "TBNO") (setq TBNOList (append TBNOList (list str))))((= (cdr(assoc 8 enlist)) "WIRENO")(setq WIRENOList(append WIRENOList (list str))))((= (cdr(assoc 8 enlist)) "DEVID") (setq DEVIDList(append DEVIDList (list str))))))nil)) ;progn necessary for multiple statements inside an if statement (progn ;;;--- Add it to the appropriate list (cond ((= (cdr(assoc 8 enlist)) "TBNO") (setq TBNOList (append TBNOList (list str)))) ((= (cdr(assoc 8 enlist)) "WIRENO")(setq WIRENOList(append WIRENOList (list str)))) ((= (cdr(assoc 8 enlist)) "DEVID") (setq DEVIDList(append DEVIDList (list str)))) ) ) ;close the if progn ) ;close the if statement ;increment the counter to get the next entity (setq cntr(+ cntr 1)) ) ;close the while loop ;;;--- Sort the list (setq TBNOList (srtAN TBNOList)) (setq WIRENOList (srtAN WIRENOList)) (setq DEVIDList (srtAN DEVIDList))
;;;--- Print the list (parameters = [FileName Prefix] [Name of List] [Print Repeat] (prinFile "TBNO_" TBNOList 1) (prinFile "WIRENO_" WIRENOList Rep) (prinFile "DEVID_" DEVIDList 1) );progn );if ;turn the command echo back on (setvar "cmdecho" 1) ;clear the command line (princ "\n") ;supress last echo (princ))
I am still having trouble with the program and I am not sure why. I am getting large spaces between my first and second text items. Not sure why this is. Could you help me troubleshoot the program?
The problem I am having with the program is coming from the section of code:
;check the group code 0 to see if entity type = TEXT
(if (cond ((= et "TEXT")(setq str (cdr (assoc 1 enlist))))
((= et "MTEXT")
;COMBINE GROUP 3's AND GROUP 1's INTO ONE STRING
(setq str (vl-remove-if-not '(lambda (q)(or (= (car q) 3)(= (car q) 1))) enlist)
str (apply 'strcat (mapcar 'cdr cs))
)
)
((and (= et "INSERT")(= (cdr (assoc 66 enlist)) 1))
(setq ne (entnext en))
(while (and ne (= (cdr (assoc 0 (setq ned (entget ne)))) "ATTRIB"))
(setq str (cdr (assoc 1 ned))
ne (entnext ne)
)
(cond
((= (cdr(assoc 8 enlist)) "TBNO") (setq TBNOList (append TBNOList (list str))))
((= (cdr(assoc 8 enlist)) "WIRENO")(setq WIRENOList(append WIRENOList (list str))))
((= (cdr(assoc 8 enlist)) "DEVID") (setq DEVIDList(append DEVIDList (list str))))
)
)
nil
)
)
I am not sure what is going on with it or why it is not working correctly. When adding it to the program it outputs some of the items but not all of them. Also the program is inserting a lot of blank spaces at the beginning. Could this code possibly be seeing these items then just interpretting them as being blank?
Any help with this would be appreciated.
Thank you,
Brad Meissner
@Anonymous wrote:....
;check the group code 0 to see if entity type = TEXT
(if (cond ((= et "TEXT")(setq str (cdr (assoc 1 enlist))))
((= et "MTEXT")
;COMBINE GROUP 3's AND GROUP 1's INTO ONE STRING
(setq str (vl-remove-if-not '(lambda (q)(or (= (car q) 3)(= (car q) 1))) enlist)
str (apply 'strcat (mapcar 'cdr cs))
)
)
((and (= et "INSERT")(= (cdr (assoc 66 enlist)) 1))
(setq ne (entnext en))
(while (and ne (= (cdr (assoc 0 (setq ned (entget ne)))) "ATTRIB"))
(setq str (cdr (assoc 1 ned))
ne (entnext ne)
)
(cond
((= (cdr(assoc 8 enlist)) "TBNO") (setq TBNOList (append TBNOList (list str))))
((= (cdr(assoc 8 enlist)) "WIRENO")(setq WIRENOList(append WIRENOList (list str))))
((= (cdr(assoc 8 enlist)) "DEVID") (setq DEVIDList(append DEVIDList (list str))))
)
)
nil
)
)
.... When adding it to the program it outputs some of the items but not all of them. Also the program is inserting a lot of blank spaces at the beginning. ....
I don't know whether these will explain your problems, but....
I don't understand what the
nil
line is there for.
It also looks [in the context of the larger routine] like the last attribute in any Block will be added to the list twice, because you add each one inside the (cond) that checks entity type, and you then add the 'str' variable [which would be the last attribute if the entity is a Block] after it's looked at all entity-type conditions.
Maybe instead of having that (if) function enclosing the (cond) function, you should skip the (if), and have the adding-to-the-appropriate-list happen within each entity-type condition, so that it adds just the single content for Text or Mtext, but adds each attribute for Blocks.
And I still think [as I suggested in one of your earlier threads] that you should try (write-line) instead of (princ) in your (prinFile) function [not included in this latest post, but earlier]. It will spare you the need to force the new-line "\n" with another (princ) there, and might possibly get rid of your blank-lines problem.
And I still think you can eliminate a (cond) function and add each piece of text content to the appropriate list with one line of code that builds the list name using the layer name, with a (set) function, as I suggested on one of your earlier threads.
Kent,
I am having a hard time following our intended changes do you think you could rewrite the script with the changes you thought should be? If so it would be awesome.
Than
@Anonymous wrote:Kent,
I am having a hard time following our intended changes do you think you could rewrite the script with the changes you thought should be? If so it would be awesome.
....
Very quickly, perhaps something like the attached. I eliminated some unused and unnecessary things, pared down some of the commentary, incorporated my earlier suggestions, and raised one question. I also realized there's an easier way to filter for things on multiple layers, using comma-delimited layer names, just as you can filter for multiple entity types, in (wcmatch) format. Only bits and pieces have been tested, since I don't have the drawing or directory setup you do.
@Anonymous wrote:The problem I am having with the program is coming from the section of code:
....
;COMBINE GROUP 3's AND GROUP 1's INTO ONE STRING
(setq str (vl-remove-if-not '(lambda (q)(or (= (car q) 3)(= (car q) 1))) enlist)
str (apply 'strcat (mapcar 'cdr cs))
)
....
I hadn't looked closely at that part before, since I must have a too-old version to have the 3 entry. But looking at it again, I notice that it calls for a 'cs' variable, which the routine does not set. Should that second setting of 'str' be:
str (apply 'strcat (mapcar 'cdr str))
instead? If so, that is not fixed in the test.lsp file I attached to my last post.
I think you're right. It could be includng attributes with no value. Try the revised version attached.
Kent,
Thanks again for all your help. When I ran the script it said error stringp nil. I tried removing the if command like you ahd commented on...could this be causing the error?
Thanks,
Brad Meissner
Yeah the same error is still showing. The program asks for the number of times wireno should output but then is guves me the error: ; error: bad argument type: stringp nil
@Anonymous wrote:Yeah the same error is still showing. The program asks for the number of times wireno should output but then is guves me the error: ; error: bad argument type: stringp nil
Since that's the last piece of User input, it could be anywhere after that. I looked for something, and didn't notice any obvious causes. I wondered whether I had gotten all the (set)/(read)/(eval) things right in my routine's consolidation of the list-making, but it shouldn't be from that, if you're getting the same problem with rbt's version that doesn't use that approach.
But it could even be in your srtAN or prinFile functions. Make yourself a valid list of text strings and try those on it, outside of the larger routine.
Or, comment out the localized variables list, like this if in my routine:
(defun C:ESBTEXT2 ();/ rep lts cntr eset en enlist et str laylist ne ned)
and run it. See how many of the variables have been set before it runs into trouble, by typing each variable name with an exclamation point before it:
!rep
!lts
etc., until one of those returns nil. That should give you some way of narrowing down where the problem lies.
[When it's been isolated and fixed, take out the ); in the altered line above.]