Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Lisp to copy mtext to clipboard in one step

mpa-la
Advocate

Lisp to copy mtext to clipboard in one step

mpa-la
Advocate
Advocate

Can anyone direct me to a lisp that will copy all the text inside an mtext entity by clicking on the entity, so that I can paste it into excel?  I grow tired of double clicking the text, ctrl A, ctrl C, then ctrl V into Excel.  Just want to cut down the number of keystrokes for something I have to do a lot.  Thanks!

0 Likes
Reply
Accepted solutions (2)
11,302 Views
41 Replies
Replies (41)

Š’eekeeCZ
Consultant
Consultant
;TEXT ------------------------------

(vl-load-com)

(defun c:CopyText2ClipBoard ( / en tx html) ; Copy Text To Clipboard
  
  (and (setq en (ssget ":S" '((0 . "*TEXT"))))
       (setq en (ssname en 0))
       (setq en (vlax-ename->vla-object en))
       (vlax-property-available-p en 'textstring)
       (setq tx (vla-get-textstring en))
       (vlax-invoke (vlax-get (vlax-get (setq html (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'setData "Text" tx)
       (vlax-release-object html)
       )
  
  (princ)
)

 

DannyNL
Advisor
Advisor

 

** never mind, code deleted **

Didn't refresh the page in time and didn't see BeekeeCZ's reply yet  Smiley Happy

0 Likes

mpa-la
Advocate
Advocate

When I issue the command and click the area in circle one, it should paste into circle 2 as shown, but instead, I'm getting what's in circle 3.Clipboard01.jpg

0 Likes

mpa-la
Advocate
Advocate

Let me give it a shot Danny, CZ's has a little issue.

0 Likes

ActivistInvestor
Advisor
Advisor

You're joking right? 

 

Using Internet Explorer (htlmfile) to copy something to the clipboard only increases AutoCAD's process memory usage by ~5 MB or so, which is akin to duck hunting with a 50 caliber Howitzer anti-aircraft gun.  

 

This has no cost in terms of process memory usage:

 

1. Write the text to a file (call it clipboard.txt in this example).

 

2. From LISP, execute the following: DOS command: "c:\windows\system32\clip.exe < clipboard.txt"

 

 


@Š’eekeeCZ wrote:
;TEXT ------------------------------

(vl-load-com)

(defun c:CopyText2ClipBoard ( / en tx html) ; Copy Text To Clipboard
  
  (and (setq en (ssget '((0 . "*TEXT"))))
       (setq en (ssname en 0))
       (setq en (vlax-ename->vla-object en))
       (vlax-property-available-p en 'textstring)
       (setq tx (vla-get-textstring en))
       (vlax-invoke (vlax-get (vlax-get (setq html (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'setData "Text" tx)
       (vlax-release-object html)
       )
  
  (princ)
)

 

See the SCREENCAST 


 

0 Likes

DannyNL
Advisor
Advisor
Accepted solution

Well, my code was basically the same as BeekeeCZ's, but I made a small modification to replace the \P with the right line break characters.

Try this.

 

(defun c:Test (/ T_Object T_HTMLObject)
   (if
      (and
         (setq T_Object (car (entsel "\nSelect text : ")))
         (vlax-property-available-p (setq T_Object (vlax-ename->vla-object T_Object)) 'TextString)
      )
      (progn
         (vlax-invoke (vlax-get (vlax-get (setq T_HTMLObject (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'SetData "Text" (ReplaceText (vla-get-TextString T_Object) "\\P" "\r\n"))
         (vlax-release-object T_HTMLObject)
      )
   )
   (princ)
)

(defun ReplaceText (RT_Text RT_Old RT_New)
   (while
      (vl-string-search RT_Old RT_Text)
      (setq RT_Text (vl-string-subst RT_New RT_Old RT_Text))
   )
   RT_Text
)

@ActivistInvestor it depends what you have installed as default internet browser, so it is not always Internet Explorer.

Kent1Cooper
Consultant
Consultant

Do you need to Paste them into an existing Excel file, or can a routine create a new one?

 

The latter would not be too difficult, with some breaking apart of the text content around the \P new-line triggers, and a (write-line) function for each piece.

Kent Cooper, AIA
0 Likes

mpa-la
Advocate
Advocate

Yours still put /p and pasted to one line instead of each text item going into a separate cell.

0 Likes

mpa-la
Advocate
Advocate

Yours also put /p and pasted to one line instead of each text item going into a separate cell.

0 Likes

mpa-la
Advocate
Advocate

Always pasting into an existing excel that I have open to the side.

0 Likes

ActivistInvestor
Advisor
Advisor

@DannyNL wrote:

Well, my code was basically the same as BeekeeCZ's, but I made a small modification to replace the \P with the right line break characters.

 

@ActivistInvestor it depends what you have installed as default internet browser, so it is not always Internet Explorer.


It has nothing to do what you have installed as the default internet browser.  Regardless of what browser that is, it will still gobble up ~5 MB of process memory. The component being used is part of Internet Explorer, which isn't loaded under normal use of AutoCAD, with or without IE being the default browser.

 

There are reasonable limits to everything, including how far LISP hackers are willing to go, in terms of the price their hacks have on the end user's experience.

0 Likes

lando7189
Advocate
Advocate
Accepted solution

Here is CZ's function, with an 'Unformat' utility added to it.  - Lanny

 

(defun c:CopyText2ClipBoard ( / Unformat en tx html) ; Copy Text To Clipboard

	(defun Unformat ( str AsMtext / _replace rx pair)  ;;;AsMtext arg:  T = mtext keep line breaks and tabs, 1 = make text single line
	    (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
	                                (list
	                                    (cons "\032"    "\\\\\\\\")
	                                    ;(cons " "       "\\\\P|\\n|\\t")
	                                    (if (= AsMtext 1) (cons " "       "\\n")   (cons "\n"         "\\n"))
	                                    (if (= AsMtext 1) (cons " "       "\\t")   (cons "\t"         "\\t"))
	                                    (if (= AsMtext 1) (cons " "       "\\\\P") (cons "\n"         "\\\\P"))
	                                    (cons "$1"      "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
	                                    (cons "$1$2/$3" "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
	                                    (cons "$1$2"    "\\\\(\\\\S)|[\\\\](})|}")
	                                    (cons "$1"      "[\\\\]({)|{")
	                                    (cons "%"       "%%%")
	                                    (cons (chr 176) "%%d")
	                                    (cons (chr 176) "%%D")
	                                    (cons (chr 177) "%%p")
	                                    (cons (chr 177) "%%P")
	                                    (cons (chr 216) "%%c")
	                                    (cons (chr 216) "%%C")
	                                    (cons ""        "%%o")
	                                    (cons ""        "%%O")
	                                    (cons ""        "%%u")
	                                    (cons ""        "%%U")            
	                                )
	                                (if pair (setq str (_replace (car pair) (cdr pair) str)))
	              ;(print (list "str" str))
	                            )
	                            (if AsMtext
	                                (_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str))
	                                (_replace "\\\\" "\032" str)
	                            )
	                        )
	                    )
	                )
	            )
	            (vlax-release-object rx)
	            (if (null (vl-catch-all-error-p str))
	                str
	            )
	        )
	    )
	)
  
  (and (setq en (ssget ":S" '((0 . "*TEXT"))))
       (setq en (ssname en 0))
       (setq en (vlax-ename->vla-object en))
       (vlax-property-available-p en 'textstring)
       (setq tx (vla-get-textstring en))
       (setq tx (Unformat tx T))
       (vlax-invoke (vlax-get (vlax-get (setq html (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'setData "Text" tx)
       (vlax-release-object html)
       )
  
  (princ)
)

Kent1Cooper
Consultant
Consultant

@DannyNL wrote:

.... I made a small modification to replace the \P with the right line break characters. ....


I do find it curious that if I make a piece of Mtext with Enters for separate lines, and the text content of it shows the \\P line breaks, when I Copy that content out as described in Post 1 and Paste it into an Excel workbook, it works as the OP desires -- the pieces go in cells each below the previous piece, not in one cell including \\P characters that don't operate as line breaks.  How the \\P gets converted into the "right" line-break characters for Excel in the Windows-Copy/Paste process, but not  in various transfer approaches suggested, I couldn't say.

Kent Cooper, AIA
0 Likes

mpa-la
Advocate
Advocate

DannyNL, I apologize, yours did work right!! Sorry, I had too many samples on my desk and I loaded the wrong one.  Winner winner chicken dinner!!  šŸ™‚

0 Likes

mpa-la
Advocate
Advocate

Yours works too Lando!

DannyNL
Advisor
Advisor

@Activist_Investor wrote:

It has nothing to do what you have installed as the default internet browser.  Regardless of what browser that is, it will still gobble up ~5 MB of process memory. The component being used is part of Internet Explorer, which isn't loaded under normal use of AutoCAD, with or without IE being the default browser.

There are reasonable limits to everything, including how far LISP hackers are willing to go, in terms of the price their hacks have on the end user's experience.


And what if Internet Explorer isn't installed at all?

 

But on the other hand I don't really care. Just launching AutoCAD 2014 without any drawing open yet will almost consume 200MB of memory, so I don't really care for the additional 5MB.

And I also find it hard to believe that it is 5MB, since when looking at the used memory resources it barely shows any difference on my system.

0 Likes

DannyNL
Advisor
Advisor

Good to hear and glad I could help Smiley Happy

0 Likes

ActivistInvestor
Advisor
Advisor

@DannyNL wrote:

And what if Internet Explorer isn't installed at all?

 

But on the other hand I don't really care. Just launching AutoCAD 2014 without any drawing open yet will almost consume 200MB of memory, so I don't really care for the additional 5MB.

And I also find it hard to believe that it is 5MB, since when looking at the used memory resources it barely shows any difference on my system.


The part of Internet Explorer that's being used must be installed, because Windows depends on it (it is used by every File Open/Save dialog in Windows), so the question is entirely moot, as the component involved is technically part of Windows, not Internet Explorer.

 

Insofar as whether you care about the extra 5 MB of baggage really has more to do with who you are writing code for, and/or who you have to answer to. If you're writing code for your own personal use, there's nothing more to say about it.

 

I have to write code for paying customers that expect me to use the right tools for the job, and not impose a significant penalty on them only because I don't know how to use the right tools for the job. So, as long as you only have to answer yourself, or to noobs who don't understand the implications of hacks like this one, you're all set to go.Smiley LOL

 

 

0 Likes

DannyNL
Advisor
Advisor

@Kent1Cooper wrote:

@DannyNL wrote:

.... I made a small modification to replace the \P with the right line break characters. ....


I do find it curious that if I make a piece of Mtext with Enters for separate lines, and the text content of it shows the \\P line breaks, when I Copy that content out as described in Post 1 and Paste it into an Excel workbook, it works as the OP desires -- the pieces go in cells each below the previous piece, not in one cell including \\P characters that don't operate as line breaks.  How the \\P gets converted into the "right" line-break characters for Excel in the Windows-Copy/Paste process, but not  in various transfer approaches suggested, I couldn't say.


Yes, I don't know either why it happens. Seems that copy to clipboard in AutoCAD does more than just copy the contents but also does some formatting, something that doesn't happen when you just extract the value with code.

0 Likes