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

Autolisp to convert attribute and mtext to regular text

29 REPLIES 29
SOLVED
Reply
Message 1 of 30
Anonymous
2719 Views, 29 Replies

Autolisp to convert attribute and mtext to regular text

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

29 REPLIES 29
Message 2 of 30
M_Hensley
in reply to: Anonymous

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.

Message 3 of 30
Anonymous
in reply to: M_Hensley

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.

Message 4 of 30
Rx3&43
in reply to: Anonymous

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 ""))

 

Message 5 of 30
Anonymous
in reply to: Anonymous

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

Message 6 of 30
Rx3&43
in reply to: Anonymous

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))

 

Message 7 of 30
Rx3&43
in reply to: Anonymous

Sorry about formatting. You might want to use the attached is file instead.

Message 8 of 30
Anonymous
in reply to: Anonymous

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?

Message 9 of 30
Anonymous
in reply to: Anonymous

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

Message 10 of 30
Kent1Cooper
in reply to: Anonymous


@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 Cooper, AIA
Message 11 of 30
Anonymous
in reply to: Kent1Cooper

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                                                                                                                                                                                                                                                                                                                        

Message 12 of 30
Kent1Cooper
in reply to: Anonymous


@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.

Kent Cooper, AIA
Message 13 of 30
Kent1Cooper
in reply to: Anonymous


@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.

Kent Cooper, AIA
Message 14 of 30
Rx3&43
in reply to: Anonymous

I think you're right. It could be includng attributes with no value. Try the revised version attached.

Message 15 of 30
Rx3&43
in reply to: Rx3&43

Use this one instead as it includes fix noted above (replacing cs with str).

Message 16 of 30
Anonymous
in reply to: Rx3&43

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

Message 17 of 30
Rx3&43
in reply to: Anonymous

Try again using attached and let me know if error occurs.

Message 18 of 30
Anonymous
in reply to: Rx3&43

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

 

 

Message 19 of 30
Kent1Cooper
in reply to: Anonymous


@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.]

Kent Cooper, AIA
Message 20 of 30
Rx3&43
in reply to: Anonymous

Can you attach a DWG file that you're running this on and getting error?  Thanks.

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

Post to forums  

Autodesk Design & Make Report

”Boost