Author Topic: need code help  (Read 3076 times)

0 Members and 1 Guest are viewing this topic.

keshar

  • Guest
need code help
« on: June 28, 2018, 10:56:10 AM »
I have been trying to create lisp to export selected mtext to a csv file for use in excel and I am running into issues that I can't solve.

I am getting a too few arguments error. 

HELP please.

ChrisCarlson

  • Guest
Re: need code help
« Reply #1 on: June 28, 2018, 11:43:43 AM »
Step through the code, which line of code is throwing the error? You can either use VLIDE or incorporate princ's or alerts to see your code's progress.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #2 on: June 28, 2018, 02:21:13 PM »
Your issues are in the following code:
Code: [Select]
(setq a (ssget))
    (if (eq (get object 0) "MTEXT")
      (write-line txt fn)
    )

You are not actually stepping through each object and the other issue is (get object 0) isn't valid either. You can easily eliminate this IF statement though since you filter out everything that wasn't MTEXT when getting the selection set. As for stepping through each item, look at SSNAME.

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: need code help
« Reply #3 on: June 28, 2018, 02:50:41 PM »

keshar

  • Guest
Re: need code help
« Reply #4 on: June 28, 2018, 03:09:36 PM »
Thanks.  I have posted an up date at that link.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #5 on: June 28, 2018, 05:18:37 PM »
I personally would do the following, I would make sure I used Lee's routine to get the text from each object, this will ensure symbols and all get exported correctly. Since you already filtered the text with SSGET, you don't need to test to see if each object is still text.

IMPORTANT NOTE: This code will export any mtext formatting as well, there are various threads that discuss how to remove the formatting, so you could utilize one of them.

Code: [Select]
;----------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Created by Karl E. Sharp
; Date: 6/27/2018
;
; This Program was designed to copy mtext from a dwg
; to csv file for use in excel
;
;   Code Modified by: Chris Wade - 06/28/2018
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:MTO (/ elist en fn fname i ss mtxt Filter Ct Obj txt)
    ;Supporting Functions
    ;;--------------------=={ Get TextString }==------------------;;
    ;;                                                            ;;
    ;;  Returns the TexString associated with an object,          ;;
    ;;  retaining all special symbols.                            ;;
    ;;------------------------------------------------------------;;
    ;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
    ;;------------------------------------------------------------;;
    ;;  Arguments:                                                ;;
    ;;  object - VLA-Object/ename for which to return TextString  ;;
    ;;------------------------------------------------------------;;
    ;;  Returns:  TextString associated with object, else nil     ;;
    ;;------------------------------------------------------------;;

(defun LM:GetTextString ( object )
  ;; © Lee Mac 2010
  (
    (lambda ( entity / _type elist )   
      (cond
        (
          (wcmatch
            (setq _type
              (cdr
                (assoc 0
                  (setq elist
                    (entget entity)
                  )
                )
              )
            )
            "TEXT,*DIMENSION"
          )
          (cdr (assoc 1 elist))
        )
        (
          (eq "MULTILEADER" _type)

          (cdr (assoc 304 elist))
        )
        (
          (wcmatch _type "ATTRIB,MTEXT")

          (
            (lambda ( string )
              (mapcar
                (function
                  (lambda ( pair )
                    (if (member (car pair) '(1 3))
                      (setq string (strcat string (cdr pair)))
                    )
                  )
                )
                elist
              )
              string
            )
            ""
          )
        )
      )
    )
    (if (eq 'VLA-OBJECT (type object))
      (vlax-vla-object->ename object)
      object
    )
  )
)
;End of Supporting Functions
    (princ "\nSelect text to export:")
    (setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MTEXT") (-4 . "OR>")))
    (if (setq ss (ssget Filter))
        (progn
            (setq fname (getfiled "Save Text File As:" "" "csv" 1))
            (setq fn (open fname "w"))
            (if fn
                (progn
                    (setq Ct 0)
                    (while (< ct (sslength ss))
                        (setq Obj (vlax-ename->vla-object (ssname ss Ct)))
                        (if Obj
                            (progn
                                (setq txt (LM:GetTextString Obj))
                                (if txt
                                    (write-line txt fn)
                                )
                            )
                        )
                        (setq ct (+ ct 1))
                    )
                    (princ (strcat "\n* Text file " fname " \n has been created *"))
                    (close fn)
                    (startapp (strcat "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\EXCEL.exe" " " (chr 34) fname (chr 34)));Make sure you update the path to match where your installation of Excel is or write a routine to find the location of Excel.
                )
                (princ "\n* Text file was not created.")
            )
        )
        (princ "\n* No text was found to export.")
    )
    (princ)
)

You could also modify this code fairly easily to work with mleaders. blocks with attributes and while slightly more difficult, you could even add in tables if you wanted to.

You could also change (ssget Filter) to (ssget "_X" Filter) and export all text in the drawing at once.
« Last Edit: June 28, 2018, 07:23:30 PM by cmwade77 »

keshar

  • Guest
Re: need code help
« Reply #6 on: June 28, 2018, 05:32:38 PM »
Thanks for your help.  This code works but with the following results, please see the attached file.  would like to do this without the \H1.000000x;\W0.713913; that is at the beginning of each line of exported text, the H is a constant but the W varies.

ronjonp

  • Needs a day job
  • Posts: 7533
Re: need code help
« Reply #7 on: June 28, 2018, 05:45:48 PM »
Read the post above more closely: "IMPORTANT NOTE: This code will export any mtext formatting as well, there are various threads that discuss how to remove the formatting, so you could utilize one of them."

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

keshar

  • Guest
Re: need code help
« Reply #8 on: June 28, 2018, 05:53:22 PM »
thanks, did not see that.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #9 on: June 28, 2018, 07:29:17 PM »
Thanks once again to Lee (I really don't think many of my routines would work without some code from him), this should do the trick:

Code: [Select]
;----------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Created by Karl E. Sharp
; Date: 6/27/2018
;
; This Program was designed to copy mtext from a dwg
; to csv file for use in excel
;
;   Code Modified by: Chris Wade - 06/28/2018
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:MTO (/ elist en fn fname i ss mtxt Filter Ct Obj txt)
    ;Supporting Functions
    ;;-------------------=={ UnFormat String }==------------------;;
;;                                                            ;;
;;  Returns a string with all MText formatting codes removed. ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  str - String to Process                                   ;;
;;  mtx - MText Flag (T if string is for use in MText)        ;;
;;------------------------------------------------------------;;
;;  Returns:  String with formatting codes removed            ;;
;;------------------------------------------------------------;;

(defun LM:UnFormat ( str mtx / _replace rx )

    (defun _replace ( new old str )
        (vlax-put-property rx 'pattern old)
        (vlax-invoke rx 'replace str new)
    )
    (if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
        (progn
            (setq str
                (vl-catch-all-apply
                    (function
                        (lambda ( )
                            (vlax-put-property rx 'global     actrue)
                            (vlax-put-property rx 'multiline  actrue)
                            (vlax-put-property rx 'ignorecase acfalse)
                            (foreach pair
                               '(
                                    ("\032"    . "\\\\\\\\")
                                    (" "       . "\\\\P|\\n|\\t")
                                    ("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
                                    ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                                    ("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
                                    ("$1"      . "[\\\\]({)|{")
                                )
                                (setq str (_replace (car pair) (cdr pair) str))
                            )
                            (if mtx
                                (_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str))
                                (_replace "\\"   "\032" str)
                            )
                        )
                    )
                )
            )
            (vlax-release-object rx)
            (if (null (vl-catch-all-error-p str))
                str
            )
        )
    )
)
    ;;--------------------=={ Get TextString }==------------------;;
    ;;                                                            ;;
    ;;  Returns the TexString associated with an object,          ;;
    ;;  retaining all special symbols.                            ;;
    ;;------------------------------------------------------------;;
    ;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
    ;;------------------------------------------------------------;;
    ;;  Arguments:                                                ;;
    ;;  object - VLA-Object/ename for which to return TextString  ;;
    ;;------------------------------------------------------------;;
    ;;  Returns:  TextString associated with object, else nil     ;;
    ;;------------------------------------------------------------;;

(defun LM:GetTextString ( object )
  ;; © Lee Mac 2010
  (
    (lambda ( entity / _type elist )   
      (cond
        (
          (wcmatch
            (setq _type
              (cdr
                (assoc 0
                  (setq elist
                    (entget entity)
                  )
                )
              )
            )
            "TEXT,*DIMENSION"
          )
          (cdr (assoc 1 elist))
        )
        (
          (eq "MULTILEADER" _type)

          (cdr (assoc 304 elist))
        )
        (
          (wcmatch _type "ATTRIB,MTEXT")

          (
            (lambda ( string )
              (mapcar
                (function
                  (lambda ( pair )
                    (if (member (car pair) '(1 3))
                      (setq string (strcat string (cdr pair)))
                    )
                  )
                )
                elist
              )
              string
            )
            ""
          )
        )
      )
    )
    (if (eq 'VLA-OBJECT (type object))
      (vlax-vla-object->ename object)
      object
    )
  )
)
;End of Supporting Functions
    (princ "\nSelect text to export:")
    (setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MTEXT") (-4 . "OR>")))
    (if (setq ss (ssget Filter))
        (progn
            (setq fname (getfiled "Save Text File As:" "" "csv" 1))
            (setq fn (open fname "w"))
            (if fn
                (progn
                    (setq Ct 0)
                    (while (< ct (sslength ss))
                        (setq Obj (vlax-ename->vla-object (ssname ss Ct)))
                        (if Obj
                            (progn
                                (setq txt (LM:Unformat (LM:GetTextString Obj) T))
                                (if txt
                                    (write-line txt fn)
                                )
                            )
                        )
                        (setq ct (+ ct 1))
                    )
                    (princ (strcat "\n* Text file " fname " \n has been created *"))
                    (close fn)
                    (startapp (strcat "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\EXCEL.exe" " " (chr 34) fname (chr 34)));Make sure you update the path to match where your installation of Excel is or write a routine to find the location of Excel.
                )
                (princ "\n* Text file was not created.")
            )
        )
        (princ "\n* No text was found to export.")
    )
    (princ)
)

NOTE: You will still have some chracters that show as their code, like %%c for the diameter symbol or %%d for the degrees symbol, for these I would recommend doing a find and replace in Excel if necessary.

keshar

  • Guest
Re: need code help
« Reply #10 on: July 02, 2018, 08:49:36 AM »
Thanks a lot for the help.  It works and gets me to a usable point.  The only thing that is a bit different is that it exports my selection in reverse order (instead of 1-8 from the top down I will have 8-1 top down).  No big deal just one additional step.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #11 on: July 02, 2018, 12:15:53 PM »
I know there is a way to fix that, but I don't know what it is, Lee could probably assist there.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #12 on: July 02, 2018, 12:24:01 PM »
Warning: I have not tested this code fully, but it should export in the correct order.

Code: [Select]
;----------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Created by Karl E. Sharp
; Date: 6/27/2018
;
; This Program was designed to copy mtext from a dwg
; to csv file for use in excel
;
;   Code Modified by: Chris Wade - 06/28/2018
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:MTO (/ elist en fn fname i ss mtxt Filter Ct Obj txt)
    ;Supporting Functions
    ;;-------------------=={ UnFormat String }==------------------;;
;;                                                            ;;
;;  Returns a string with all MText formatting codes removed. ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  str - String to Process                                   ;;
;;  mtx - MText Flag (T if string is for use in MText)        ;;
;;------------------------------------------------------------;;
;;  Returns:  String with formatting codes removed            ;;
;;------------------------------------------------------------;;

(defun LM:UnFormat ( str mtx / _replace rx )

    (defun _replace ( new old str )
        (vlax-put-property rx 'pattern old)
        (vlax-invoke rx 'replace str new)
    )
    (if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
        (progn
            (setq str
                (vl-catch-all-apply
                    (function
                        (lambda ( )
                            (vlax-put-property rx 'global     actrue)
                            (vlax-put-property rx 'multiline  actrue)
                            (vlax-put-property rx 'ignorecase acfalse)
                            (foreach pair
                               '(
                                    ("\032"    . "\\\\\\\\")
                                    (" "       . "\\\\P|\\n|\\t")
                                    ("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
                                    ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                                    ("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
                                    ("$1"      . "[\\\\]({)|{")
                                )
                                (setq str (_replace (car pair) (cdr pair) str))
                            )
                            (if mtx
                                (_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str))
                                (_replace "\\"   "\032" str)
                            )
                        )
                    )
                )
            )
            (vlax-release-object rx)
            (if (null (vl-catch-all-error-p str))
                str
            )
        )
    )
)
    ;;--------------------=={ Get TextString }==------------------;;
    ;;                                                            ;;
    ;;  Returns the TexString associated with an object,          ;;
    ;;  retaining all special symbols.                            ;;
    ;;------------------------------------------------------------;;
    ;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
    ;;------------------------------------------------------------;;
    ;;  Arguments:                                                ;;
    ;;  object - VLA-Object/ename for which to return TextString  ;;
    ;;------------------------------------------------------------;;
    ;;  Returns:  TextString associated with object, else nil     ;;
    ;;------------------------------------------------------------;;

(defun LM:GetTextString ( object )
  ;; © Lee Mac 2010
  (
    (lambda ( entity / _type elist )   
      (cond
        (
          (wcmatch
            (setq _type
              (cdr
                (assoc 0
                  (setq elist
                    (entget entity)
                  )
                )
              )
            )
            "TEXT,*DIMENSION"
          )
          (cdr (assoc 1 elist))
        )
        (
          (eq "MULTILEADER" _type)

          (cdr (assoc 304 elist))
        )
        (
          (wcmatch _type "ATTRIB,MTEXT")

          (
            (lambda ( string )
              (mapcar
                (function
                  (lambda ( pair )
                    (if (member (car pair) '(1 3))
                      (setq string (strcat string (cdr pair)))
                    )
                  )
                )
                elist
              )
              string
            )
            ""
          )
        )
      )
    )
    (if (eq 'VLA-OBJECT (type object))
      (vlax-vla-object->ename object)
      object
    )
  )
)
;End of Supporting Functions
    (princ "\nSelect text to export:")
    (setq Filter '((-4 . "<OR") (0 . "TEXT") (0 . "MTEXT") (-4 . "OR>")))
    (if (setq ss (ssget Filter))
        (progn
            (setq fname (getfiled "Save Text File As:" "" "csv" 1))
            (setq fn (open fname "w"))
            (if fn
                (progn
(setq ct (sslength ss)); Code to process in reverse order came from: David Bethel - https://www.theswamp.org/index.php?topic=3162.msg39448#msg39448
(while (not (minusp (setq ct (1- ct))))
                        (setq Obj (vlax-ename->vla-object (ssname ss Ct)))
                        (if Obj
                            (progn
                                (setq txt (LM:Unformat (LM:GetTextString Obj) T))
                                (if txt
                                    (write-line txt fn)
                                )
                            )
                        )
                    )
                    (princ (strcat "\n* Text file " fname " \n has been created *"))
                    (close fn)
                    (startapp (strcat "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\EXCEL.exe" " " (chr 34) fname (chr 34)));Make sure you update the path to match where your installation of Excel is or write a routine to find the location of Excel.
                )
                (princ "\n* Text file was not created.")
            )
        )
        (princ "\n* No text was found to export.")
    )
    (princ)
)

keshar

  • Guest
Re: need code help
« Reply #13 on: July 03, 2018, 07:20:36 AM »
That does it!  It works great thanks.

cmwade77

  • Swamp Rat
  • Posts: 1449
Re: need code help
« Reply #14 on: July 03, 2018, 12:07:53 PM »
You are welcome, I am sure there are far more efficient ways to do this, but it gets the job done.