How to copy a word doc, delete a sentence and paste it keeping format

Get help with using AutoHotkey and its commands and hotkeys
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 06:58

Hi guys, I have a script that opens a word document, copies the contents and then after deleting a sentence pastes the content on another document. I use com functions to do it and everything works fine until I use the line "oWord.Selection.TypeText("text")" which makes the document lose the format (italic). I switched that line to "send ^v" and that works, the format is kept.

The problem now is that I need to delete the first 100 characters of the document (or any given sentence) and when I use stringmid to delete what I need, the document loses format again even if I use ^v.

Is there any way I can do it without losing format?

The process would be:

- open or read a word document
- copy the whole text
- delete characters 1-100
- close that doc, open another word doc
- paste the text keeping the format

here's the code:

Code: Select all

Run, test.doc
Sleep 2500
clipboard=
oWord := ComObjActive("Word.Application")
oDoc := oword.documents[1]
oDoc.Range.FormattedText.Copy  
ClipWait  
winclose, a ;  close document
StringGetPos , delst,clipboard, firstword
StringMid ,text2del,clipboard,1,%delst%

run document2.doc
WinActivate ,ahk_class OpusApp
try 
oWord := ComObjActive("Word.Application")
catch 
return 
oDoc := oword.documents[1] 
oWord.Selection.Font.Bold := 1
oWord.Selection.TypeText("`n`nsometext")
oWord.Selection.Font.Bold := false
oWord.Selection.ParagraphFormat.Alignment := 3
oWord.Selection.TypeText("`n`n")
;~ oWord.Selection.TypeText("`n`n"newtext)  ;THIS LOSES FORMAT
send ^v  ;THIS LOSES FORMAT TOO AFTER USING STRINGMID, OTHERWISE IT WORKS

A second minor problem, though I could for now live with it, is that when I paste the text the margins are different from the text already existing in the new doc. I would need the new text to have the exact same margins as the previous text. Can that be done??

Any help would be much appreciated.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 15:17

The trick is not to remove the stuff you want from the clipboard but to only put on the clipboard what you want.

Code: Select all

wdApp := ComObjActive("Word.Application")
wdDoc1 := wdApp.ActiveDocument
wdDoc1.Range(101,wdDoc1.Content.End).Copy

wdDoc2 := wdApp.Documents.Add
wdDoc2.Range(wdDoc2.Content.End -1, wdDoc2.Content.End -1).Paste
This will take the active document and copy on the clipboard only the characters from 101 position to the end of the document.

Then it will create a new document and paste the clipboard right before the end position of the new document.

Instead of a new document, you could open any document through COM and put the clipboard at any position.

The margins are a different issue. Text does not have margins, pages have margins. If needed you could get the margins of the first document and apply them to the second.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 15:25

Awesome, I didn't know you could copy content that easily from a certain position. Your script is going to be of much help for this and other scripts I have.
Thanks a lot, Fanaticguru.

As for the margins thing, I haven't the foggiest as to how I could find out about the margins and apply them to the second document, my COM knowledge is very very basic but I'll see if I can find some info on the forums. Thanks again.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 15:46

gonzax wrote:As for the margins thing, I haven't the foggiest as to how I could find out about the margins and apply them to the second document, my COM knowledge is very very basic but I'll see if I can find some info on the forums. Thanks again.
This will make the page setup of doc2 equal to the page setup of doc1.

Code: Select all

wdDoc2.PageSetup := wdDoc1.PageSetup
You can control everything individually but this gets it all.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 16:20

FanaticGuru wrote:
gonzax wrote:As for the margins thing, I haven't the foggiest as to how I could find out about the margins and apply them to the second document, my COM knowledge is very very basic but I'll see if I can find some info on the forums. Thanks again.
This will make the page setup of doc2 equal to the page setup of doc1.

Code: Select all

wdDoc2.PageSetup := wdDoc1.PageSetup
You can control everything individually but this gets it all.

FG
I can't try it right now because I need it for a script that I use at work but your solution seems so simple that it sounds even too good to be true, I can't wait to try it, I think I'm going to write a small script tomorrow just to see how it works. It's amazing what you can do via COM, it's even more powerful than I thought it was.

By the way, the document where I need to paste the cropped text is already open and it already contains some text. I had thought of a workaround consisting on copying the original text to a variable, deleting it, pasting the second text with format, deleting the first 100 characters from that once pasted and then inserting the orginal text at the beginning. I think it would work but your solution is much quicker and a million times more elegant, apart from the margins thing which I didn't know how to solve.

Thanks a lot for the help, I'll let you know how it goes.
User avatar
jeeswg
Posts: 5421
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to copy a word doc, delete a sentence and paste it keeping format

16 Mar 2018, 19:13

You can learn a lot by recording macros, doing things, and then reviewing the code.
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

17 Mar 2018, 05:09

jeeswg wrote:You can learn a lot by recording macros, doing things, and then reviewing the code.
Recording macros with ahk, you mean?
I tried reviewing visual basic code to learn some things but I was terrible at converting the code to ahk, the scripts would never work so I gave up. Seeing other people's scripts helps me a lot, though.
User avatar
jeeswg
Posts: 5421
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to copy a word doc, delete a sentence and paste it keeping format

17 Mar 2018, 05:16

- Recording macros in MS Word (no AutoHotkey), and then reviewing the code.
- The main difference is:

Code: Select all

Obj.Method Arg1:=Value1, Arg4:=Value4
;becomes:
Obj.Method(Arg1:=Value1,,, Arg4:=Value4)
;or:
Obj.Method(Value1,,, Value4)
- And you must define any constants e.g. wdStatisticPages := 2. You can retrieve these via macros within Word: MsgBox wdStatisticPages.
- Anyhow, recording the macros at least gives you some idea of what keywords to look up.
- Also, it's useful to know that true is -1 (unlike in AutoHotkey where it's 1, although using 1 will often work), and false is 0 (like in AutoHotkey). And also, often parameters accept variables, but sometimes they want safe arrays.
- You can search for something like: msdn word method, to find more info about a method.
Last edited by jeeswg on 17 Mar 2018, 10:48, edited 3 times in total.
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

17 Mar 2018, 07:51

jeeswg wrote:- Recording macros in MS Word (no AutoHotkey), and then reviewing the code.
- The main difference is:

Code: Select all

Obj.Method Arg1:=Value1, Arg4:=Value4
;becomes
Obj.Method(Arg1:=Value1,,, Arg4:=Value4)
;or:
Obj.Method(Value1,,, Value4)
- And you must define any constants e.g. wdStatisticPages.
- Anyhow, recording the macros at least gives you some idea of what key words to look up.
Well that's very interesting, I really have to look into that. Even if I can't convert the code correctly it certainly gives me an idea of what to do and how. Very useful tip, thanks a lot.
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

19 Mar 2018, 08:01

FanaticGuru wrote:The trick is not to remove the stuff you want from the clipboard but to only put on the clipboard what you want.

Code: Select all

wdApp := ComObjActive("Word.Application")
wdDoc1 := wdApp.ActiveDocument
wdDoc1.Range(101,wdDoc1.Content.End).Copy

wdDoc2 := wdApp.Documents.Add
wdDoc2.Range(wdDoc2.Content.End -1, wdDoc2.Content.End -1).Paste
This will take the active document and copy on the clipboard only the characters from 101 position to the end of the document.
FG
I just wanted to tell you that your code worked to perfection, thanks a lot, man, this was incredibly helpful for me, for this and other scripts I use

PS: I couldn't make the "wdDoc2.PageSetup := wdDoc1.PageSetup" line work but I can live with that.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

19 Mar 2018, 11:26

gonzax wrote:PS: I couldn't make the "wdDoc2.PageSetup := wdDoc1.PageSetup" line work but I can live with that.
If you post your code can probably solve that problem.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 05:40

FanaticGuru wrote:
gonzax wrote:PS: I couldn't make the "wdDoc2.PageSetup := wdDoc1.PageSetup" line work but I can live with that.
If you post your code can probably solve that problem.

FG
Here it is, it's part of a much bigger code but the part I need is this::

Code: Select all

; this is a gui for choosing the text I  need to paste later
gui,32: destroy
GUI, 32: Default
Gui, Font, S16
Gui, Add, Text,, SELECT TEXT
Gui, Add, ListBox, vSENT gCHOOSESENT w600 r25 0x100
Gui, Add, Button, Default gCOPY, OK
Loop, G:\FILESTOSELECT\*.*    
{
    GuiControl,, sent, %A_LoopFileName%
}
Gui,32: Show
return

CHOOSESENT:
if A_GuiEvent <> DoubleClick 
    return
COPY:
GuiControlGet, sent  
gui, destroy
Run, G:\FILESTOSELECT\%sent%,, UseErrorLevel
if ErrorLevel = ERROR
{
    MsgBox CAN'T BE READ
	return
}

; copying the contents of the chosen word doc
Progress, m2 b W400 H60 C1 ZY22 ct1A00FF CWC0C0C0  WM1000   zh0, ¡¡READING TEXT!!
Sleep 2500
clipboard=
oWord := ComObjActive("Word.Application")
oDoc := oword.documents[1]  
oDoc.Range.FormattedText.Copy  
Progress off

; finding out the position of the first word  from which I must copy the text
StringGetPos ,delpos,clipboard,FIRSTWORD  
delpos++

; final text without first X characters
oDoc.Range(delpos,oDoc.Content.End).Copy
ClipSen := ClipboardAll  ;empties clipboard in case it is too big and copies its contents for later use
clipboard=
winclose, a ; close current word doc
sleep 200

; 
WinActivate ,ahk_class OpusApp
; Gosub grabnames
; "Grabnames"  is a routine that deletes the contents of the current word document I am working on (which is already open, even  before the beginning of this script where I open the 2nd word doc and crop its text)  and pastes a different header which consists of about 10 lines of a predefined text.
; so just imagine the current word document as a few lines of text with names and the script continues to paste the cropped text 
; from before
; The text I am working on has wider margins than the text I am pasting later

Sleep 200
clipboard := ClipSen  ; retrieve the contents of the cropped text from before to paste on the already open document
oWord := ComObjActive("Word.Application")
oDoc2 := oword.documents[1]
;oDoc2 .PageSetup := oDoc .PageSetup   ; this line does nothing in my script

; this part pastes a few additional lines of text between the header and the cropped text
oWord.Selection.Font.Bold := 1
oWord.Selection.TypeText("`n`n"some predefined text)
oWord.Selection.Font.Bold := false
oWord.Selection.ParagraphFormat.Alignment := 3
oWord.Selection.TypeText("`n`n")

oDoc2.Range(oDoc2.Content.End -1, oDoc2.Content.End -1).Paste  ;paste the initial cropped text
Guest

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 07:18

Just in case:
if the source can be a HTML file you can simply use regular string commands/functions in AutoHotkey, afterwards you use WinClip() to set it as formatted text in the clipboard and paste as such - see #4 here https://autohotkey.com/boards/viewtopic.php?f=7&t=8977
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 08:08

Guest wrote:Just in case:
if the source can be a HTML file you can simply use regular string commands/functions in AutoHotkey, afterwards you use WinClip() to set it as formatted text in the clipboard and paste as such - see #4 here https://autohotkey.com/boards/viewtopic.php?f=7&t=8977
Pasting with format is not a problem anymore, that part is solved. The thing is the margins of the current document are different from the pasted text so I need a function that allows me to select the whole text and establish the same margins for the whole document.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 13:58

gonzax wrote:Here it is, it's part of a much bigger code but the part I need is this::

Code: Select all

; this is a gui for choosing the text I  need to paste later
gui,32: destroy
GUI, 32: Default
Gui, Font, S16
Gui, Add, Text,, SELECT TEXT
Gui, Add, ListBox, vSENT gCHOOSESENT w600 r25 0x100
Gui, Add, Button, Default gCOPY, OK
Loop, G:\FILESTOSELECT\*.*    
{
    GuiControl,, sent, %A_LoopFileName%
}
Gui,32: Show
return

CHOOSESENT:
if A_GuiEvent <> DoubleClick 
    return
COPY:
GuiControlGet, sent  
gui, destroy
Run, G:\FILESTOSELECT\%sent%,, UseErrorLevel
if ErrorLevel = ERROR
{
    MsgBox CAN'T BE READ
	return
}

; copying the contents of the chosen word doc
Progress, m2 b W400 H60 C1 ZY22 ct1A00FF CWC0C0C0  WM1000   zh0, ¡¡READING TEXT!!
Sleep 2500
clipboard=
oWord := ComObjActive("Word.Application")
oDoc := oword.documents[1]  
oDoc.Range.FormattedText.Copy  
Progress off

; finding out the position of the first word  from which I must copy the text
StringGetPos ,delpos,clipboard,FIRSTWORD  
delpos++

; final text without first X characters
oDoc.Range(delpos,oDoc.Content.End).Copy
ClipSen := ClipboardAll  ;empties clipboard in case it is too big and copies its contents for later use
clipboard=
winclose, a ; close current word doc
sleep 200

; 
WinActivate ,ahk_class OpusApp
; Gosub grabnames
; "Grabnames"  is a routine that deletes the contents of the current word document I am working on (which is already open, even  before the beginning of this script where I open the 2nd word doc and crop its text)  and pastes a different header which consists of about 10 lines of a predefined text.
; so just imagine the current word document as a few lines of text with names and the script continues to paste the cropped text 
; from before
; The text I am working on has wider margins than the text I am pasting later

Sleep 200
clipboard := ClipSen  ; retrieve the contents of the cropped text from before to paste on the already open document
oWord := ComObjActive("Word.Application")
oDoc2 := oword.documents[1]
;oDoc2 .PageSetup := oDoc .PageSetup   ; this line does nothing in my script

; this part pastes a few additional lines of text between the header and the cropped text
oWord.Selection.Font.Bold := 1
oWord.Selection.TypeText("`n`n"some predefined text)
oWord.Selection.Font.Bold := false
oWord.Selection.ParagraphFormat.Alignment := 3
oWord.Selection.TypeText("`n`n")

oDoc2.Range(oDoc2.Content.End -1, oDoc2.Content.End -1).Paste  ;paste the initial cropped text
Things I would suggest:

Code: Select all

oWord := ComObjActive("Word.Application")
oDoc := oword.documents[1]  
StringGetPos, delpos, oDoc.Range.Text, FIRSTWORD
delpos++
; delpos := InStr(oDoc.Range.Text, FIRSTWORD) + 1 ; Recommend using functions when possible
You don't need to copy to clipboard and then use clipboard like a variable. You can get the text from Word directly.

Code: Select all

winclose, a ; close current word doc
If you close the first document you cannot access it later which is why ;oDoc2 .PageSetup := oDoc .PageSetup fails. oDoc is closed and no longer accessable.

Code: Select all

WinActivate ,ahk_class OpusApp
I don't know how this Word document got open but I would have opened it with COM and kept a handle to it to start with. Something like:

Code: Select all

wdDoc2 := wdApp.Documents.Open(filename)
You would not normally use this twice oWord := ComObjActive("Word.Application"). Once you have a handle to the Word application, you can close and open as many documents as you need without shutting down or opening a new version of Word program.

For example: oDoc2 := oword.documents[1] this does not have to be "1". You can refer to documents by index number or by name.

You could do something like this to get handles to open documents:

Code: Select all

oDoc1 := oWord.Documents("Report.doc")
oDoc2 := oWord.Documents("Summary.doc")
This does not open documents it just gets handles to ones already open.

It is important to realize that I often use wdApp (Word Application). Some use oWord (Object Word). The first "thing" before the dot is just a variable name and can be whatever helps you to keep things straight. AnotherVariableName := VariableName.Documents[1]

Don't think that I am being too critical. You are doing great compared to alot of people. Just trying to help you and others see the power of COM. AHK is often alot about working with the right window which is great when people get a good handle on that but then COM takes it to a different level where it is no longer about windows but working with objects. The various Win commands are rarely needed with COM. Send, Sleep, even Clipboard, are rarely needed. This make COM very fast and efficient as it is one program talking directly to another program (directly like talking to someone on the telephone, Windows is doing alot of work like the phone company to make it happen).

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 18:12

FanaticGuru wrote: Don't think that I am being too critical. You are doing great compared to alot of people. Just trying to help you and others see the power of COM. AHK is often alot about working with the right window which is great when people get a good handle on that but then COM takes it to a different level where it is no longer about windows but working with objects. The various Win commands are rarely needed with COM. Send, Sleep, even Clipboard, are rarely needed. This make COM very fast and efficient as it is one program talking directly to another program (directly like talking to someone on the telephone, Windows is doing alot of work like the phone company to make it happen).

FG
Thanks again FanaticGuru, very interesting and useful info and I don't think you're being critical at all, quite the opposite. I love to learn new things and you explain them very well.
COM is really powerful, I realised that a while ago when I first learned to do some things that I used to do in a different way, it was a night and day difference. My knowledge of COM is very limited though and watching your tips and your code I realise that, as you said before, you don't really need to use send, clipboard and all that stuff, there are far better ways to get things done. It's baby steps for me but seeing the way you do things is very very helpful, in fact I am updating parts of my main script to do things your way as anything that can be done with COM is much faster and reliable than say, something like send ^e or similar.

As for this script, I will try to leave the first document open to see if it works that way though it's not much of a problem, it's a simple click to get the margins right, anyway. By the way, the second word document is part of the app we use at work so there is not much I can do about it, I can't open those documents, it's the app that does and that can't be changed but pasting text the way you said works perfectly so it's great.

Thanks a lot for your help, much appreciated, honestly.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

20 Mar 2018, 19:14

Just for future searches, instead of copying margins, you can also specifically set the margins.

Code: Select all

wdApp := ComObjActive("Word.Application")
wdDoc := wdApp.ActiveDocument
wdDoc.PageSetup.Orientation := 1		; wdOrientPortrait := 0 ; wdOrientLandscape := 1
wdDoc.PageSetup.TopMargin := wdApp.InchesToPoints(0.6)
wdDoc.PageSetup.BottomMargin := wdApp.InchesToPoints(0.5)
wdDoc.PageSetup.LeftMargin := wdApp.InchesToPoints(0.4)
wdDoc.PageSetup.RightMargin := wdApp.InchesToPoints(0.3)
These are only the 5 most common properties. There are 30 or 40 PageSetup properties that can be set to control every aspect of the page setup.

https://msdn.microsoft.com/en-us/librar ... mbers.aspx

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

21 Mar 2018, 05:40

FanaticGuru wrote:Just for future searches, instead of copying margins, you can also specifically set the margins.

https://msdn.microsoft.com/en-us/librar ... mbers.aspx

FG
My problem with MS documentation and properties is that I rarely get the syntaxis right when I try to convert to ahk, unless it's something I have used before or I can see someone's ahk code using that particular property.
I tried some of those examples and they work great, It's amazing how simple it is when you know what to do.

One question:
Is there any difference between 'oDoc := oword.ActiveDocument' and 'oDoc := oword.documents[1]'? Both work without problems but I don't know if there is any particular advantage to using one over the other, I thought they both referred to the current active document.
FanaticGuru
Posts: 1228
Joined: 30 Sep 2013, 22:25

Re: How to copy a word doc, delete a sentence and paste it keeping format

21 Mar 2018, 11:07

gonzax wrote:Is there any difference between 'oDoc := oword.ActiveDocument' and 'oDoc := oword.documents[1]'? Both work without problems but I don't know if there is any particular advantage to using one over the other, I thought they both referred to the current active document.
No, they are not necessarily the same.

Say you start Word. Then you open a document, then you open another document. Now you have one application of Word running but with two documents open. Those will be Documents[1] and Documents[2]. There could be documents 3, 4, 5, etc. Usually in the order that you open them but if you open and close documents the order can be mixed up. This is an index numbe. It can also use the name of the documents, ie. Documents["Report.doc"]. One of those documents will also be the ActiveDocument but this can change depending on the last one that you had active, basically meaing the one that if you just switched to Word and started typing, the one the text would appear in. The window does not have to be active. If you are in Outlook but Word is running, then there is an ActiveDocument even if the Word window is not activated.

If you start Word and only have one document open then Documents[1] and ActiveDocument will always be the same.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
gonzax
Posts: 12
Joined: 15 May 2015, 11:31

Re: How to copy a word doc, delete a sentence and paste it keeping format

21 Mar 2018, 11:35

Ah ok, I get it now, the difference is quite obvious. Great explanation, I think I'm going to use "activedocument" from now on to avoid problems in case more than one doc. is open, it makes it clearer to see which document I am working on.

Thanks again

Return to “Ask For Help”

Who is online

Users browsing this forum: ineuw, vvhitevvizard and 96 guests