Way to replace string in word DOC ?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Way to replace string in word DOC ?

#1 Post by goodywp » 14 Jun 2018 08:11

Hi all,

I know that the word document is GUI application and obviously so far to my knowledge can not be replacing string directly in command line. Someone suggested using 3rd party utility.

Does anyone has some idea, suggestion or good experience on this matter?

Your input shall be greatly appreciated as always...

Thanks

goodywp

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Way to replace string in word DOC ?

#2 Post by aGerman » 15 Jun 2018 04:54

It's possible to automate MS Word, provided it was installed on the machine where you use the script. The ActiveX interface can't be accessed by Batch but a JScript hybrid could come in handy in that case. I'll try to write some lines of code this evening...

Steffen

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Way to replace string in word DOC ?

#3 Post by aGerman » 15 Jun 2018 10:54

Okay here it goes ...

Save with extension .bat

Code: Select all

@if (0)==(0) echo off &setlocal EnableExtensions DisableDelayedExpansion &set "wordrepl=cscript //nologo //e:jscript %~fs0"

:: Usage:
::  %wordrepl%  FileName  Find  Replace  [/i]  [/w]  [/a]  [/b]  [/e]  [/p]
::    FileName    path of the Word document
::    Find        text to search for
::    Replace     text used for the replacement
::    /i          ignore case
::    /w          match whole words only
::    /a          advanced: use wildcards and (kind of) regex
::                  http://office.microsoft.com/en-us/word-help/find-and-replace-text-by-using-regular-expressions-advanced-HA102350661.aspx
::    /b          match words beginning with the search string
::    /e          match words ending with the search string
::    /p          match phrase, ignore all white space and control characters between words
:: returns 0 if the script succeeded
::         1 if no replacement was performed (e.g. search string not found)
::         2 if an error occurred (e.g. MS Word not installed, file not found, file read-only, file password-protected, etc.)


:::::: BATCH ::::::
%wordrepl% "test.docx" "ABC" "xyz" /i /w
echo %errorlevel%
pause


:::::: JSCRIPT ::::::
goto :eof @end
if (WScript.Arguments.Unnamed.Count != 3 || WScript.Arguments.Count() > 9) WScript.Quit(2);

var namedParams = null, bMatchCase = true, bMatchWholeWord = false, bMatchWildcards = false, wdApp = null, wdDoc = null, wdFind = null, oFSO = null, oFile = null, bRet = false;

try {
  oFSO = WScript.CreateObject('Scripting.FileSystemObject');
  oFile = oFSO.OpenTextFile(oFSO.GetAbsolutePathName(WScript.Arguments.Unnamed(0)), 8, false);
  oFile.Close();

  wdApp = WScript.CreateObject('Word.Application'); /* open the Word application */
  wdApp.Visible = false; /* without window */
  wdApp.Application.DisplayAlerts = 0;

  wdDoc = wdApp.Documents.Open(oFSO.GetAbsolutePathName(WScript.Arguments.Unnamed(0))); /* open the document */
  if (wdDoc.ReadOnly == true) throw true;

  wdFind = wdDoc.Content.Find;
  namedParams = WScript.Arguments.Named

  /* https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.find_members.aspx */
  if (namedParams.Exists('b')) wdFind.MatchPrefix = true;
  if (namedParams.Exists('e')) wdFind.MatchSuffix = true;
  if (namedParams.Exists('p')) wdFind.MatchPhrase = true;

  /* replace text (https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.find.execute.aspx) */
  if (namedParams.Exists('i')) bMatchCase = false;
  if (namedParams.Exists('w')) bMatchWholeWord = true;
  if (namedParams.Exists('a')) bMatchWildcards = true;
  bRet = wdFind.Execute(
    WScript.Arguments.Unnamed(1), /* FindText */
    bMatchCase,                   /* MatchCase */
    bMatchWholeWord,              /* MatchWholeWord */
    bMatchWildcards,              /* MatchWildcards */
    false,                        /* MatchSoundsLike */
    false,                        /* MatchAllWordForms */
    true,                         /* Forward */
    1,                            /* Wrap (1 = wdFindContinue) */
    false,                        /* Format */
    WScript.Arguments.Unnamed(2), /* ReplaceWith */
    2                             /* Replace (2 = wdReplaceAll) */
  );

  wdDoc.Close(bRet == true ? -1 : 0); /* save (if the replacement was successful) and close the document */
  wdDoc = null;
  wdApp.Quit(); /* quit the Word application */
  wdApp = null;
  WScript.Quit(bRet == false ? 1 : 0);
}
catch (e) {
  if (wdDoc != null) wdDoc.Close(0); /* close unsaved */
  if (wdApp != null) wdApp.Quit();
  WScript.Quit(2);
}
The first line is mandatory and the JScript portion has to be the last part of the script as always in Batch-JScript-Hybrids.
It's only a proof of concept and I was only able to test using Word 2003.

Steffen

//EDIT 2018-06-17: code slightly improved, return value changed
//EDIT 2018-06-18: added options /b, /e, and /p

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#4 Post by goodywp » 18 Jun 2018 14:18

aGerman wrote:
15 Jun 2018 10:54
Okay here it goes ...

Save with extension .bat

Code: Select all

@if (0)==(0) echo off &setlocal EnableExtensions DisableDelayedExpansion &set "wordrepl=cscript //nologo //e:jscript %~fs0"

:: Usage:
::  %wordrepl%  FileName  Find  Replace  [/i]  [/w]  [/a]  [/b]  [/e]  [/p]
::    FileName    path of the Word document
::    Find        text to search for
::    Replace     text used for the replacement
::    /i          ignore case
::    /w          match whole words only
::    /a          advanced: use wildcards and (kind of) regex
::                  http://office.microsoft.com/en-us/word-help/find-and-replace-text-by-using-regular-expressions-advanced-HA102350661.aspx
::    /b          match words beginning with the search string
::    /e          match words ending with the search string
::    /p          match phrase, ignore all white space and control characters between words
:: returns 0 if the script succeeded
::         1 if no replacement was performed (e.g. search string not found)
::         2 if an error occurred (e.g. MS Word not installed, file not found, file read-only, file password-protected, etc.)


:::::: BATCH ::::::
%wordrepl% "test.docx" "ABC" "xyz" /i /w
echo %errorlevel%
pause


:::::: JSCRIPT ::::::
goto :eof @end
if (WScript.Arguments.Unnamed.Count != 3 || WScript.Arguments.Count() > 9) WScript.Quit(2);

var namedParams = null, bMatchCase = true, bMatchWholeWord = false, bMatchWildcards = false, wdApp = null, wdDoc = null, wdFind = null, oFSO = null, oFile = null, bRet = false;

try {
  oFSO = WScript.CreateObject('Scripting.FileSystemObject');
  oFile = oFSO.OpenTextFile(oFSO.GetAbsolutePathName(WScript.Arguments.Unnamed(0)), 8, false);
  oFile.Close();

  wdApp = WScript.CreateObject('Word.Application'); /* open the Word application */
  wdApp.Visible = false; /* without window */
  wdApp.Application.DisplayAlerts = 0;

  wdDoc = wdApp.Documents.Open(oFSO.GetAbsolutePathName(WScript.Arguments.Unnamed(0))); /* open the document */
  if (wdDoc.ReadOnly == true) throw true;

  wdFind = wdDoc.Content.Find;
  namedParams = WScript.Arguments.Named

  /* https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.find_members.aspx */
  if (namedParams.Exists('b')) wdFind.MatchPrefix = true;
  if (namedParams.Exists('e')) wdFind.MatchSuffix = true;
  if (namedParams.Exists('p')) wdFind.MatchPhrase = true;

  /* replace text (https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.find.execute.aspx) */
  if (namedParams.Exists('i')) bMatchCase = false;
  if (namedParams.Exists('w')) bMatchWholeWord = true;
  if (namedParams.Exists('a')) bMatchWildcards = true;
  bRet = wdFind.Execute(
    WScript.Arguments.Unnamed(1), /* FindText */
    bMatchCase,                   /* MatchCase */
    bMatchWholeWord,              /* MatchWholeWord */
    bMatchWildcards,              /* MatchWildcards */
    false,                        /* MatchSoundsLike */
    false,                        /* MatchAllWordForms */
    true,                         /* Forward */
    1,                            /* Wrap (1 = wdFindContinue) */
    false,                        /* Format */
    WScript.Arguments.Unnamed(2), /* ReplaceWith */
    2                             /* Replace (2 = wdReplaceAll) */
  );

  wdDoc.Close(bRet == true ? -1 : 0); /* save (if the replacement was successful) and close the document */
  wdDoc = null;
  wdApp.Quit(); /* quit the Word application */
  wdApp = null;
  WScript.Quit(bRet == false ? 1 : 0);
}
catch (e) {
  if (wdDoc != null) wdDoc.Close(0); /* close unsaved */
  if (wdApp != null) wdApp.Quit();
  WScript.Quit(2);
}
The first line is mandatory and the JScript portion has to be the last part of the script as always in Batch-JScript-Hybrids.
It's only a proof of concept and I was only able to test using Word 2003.

Steffen

//EDIT 2018-06-17: code slightly improved, return value changed
//EDIT 2018-06-18: added options /b, /e, and /p
Thanks soooo..... much and I shall try it out in several word versions and let you know...

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Way to replace string in word DOC ?

#5 Post by aGerman » 18 Jun 2018 15:13

I found some kind of bug in the return value of the Find.Execute method that makes the return value of the script rather ambiguous. E.g if you have the word abcx in your document and you want to replace abc, but only the whole word (using option /w). The Execute method returns true because it found abc in abcx even though it didn't perform the replacement because the whole word consists of abc plus x. That means the script behaves correctly but it would return 0 without any replacement done. I can't fix it because I just use Microsoft's Execute method.
FWIW Meanwhile I was able to test the script at work with Office 2013 installed. It seems to work out.

Steffen

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#6 Post by goodywp » 20 Jun 2018 06:09

aGerman wrote:
18 Jun 2018 15:13
I found some kind of bug in the return value of the Find.Execute method that makes the return value of the script rather ambiguous. E.g if you have the word abcx in your document and you want to replace abc, but only the whole word (using option /w). The Execute method returns true because it found abc in abcx even though it didn't perform the replacement because the whole word consists of abc plus x. That means the script behaves correctly but it would return 0 without any replacement done. I can't fix it because I just use Microsoft's Execute method.
FWIW Meanwhile I was able to test the script at work with Office 2013 installed. It seems to work out.

Steffen
Thanks Steffen!!! not find time to try it out yet...

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#7 Post by goodywp » 22 Jun 2018 08:50

goodywp wrote:
20 Jun 2018 06:09
aGerman wrote:
18 Jun 2018 15:13
I found some kind of bug in the return value of the Find.Execute method that makes the return value of the script rather ambiguous. E.g if you have the word abcx in your document and you want to replace abc, but only the whole word (using option /w). The Execute method returns true because it found abc in abcx even though it didn't perform the replacement because the whole word consists of abc plus x. That means the script behaves correctly but it would return 0 without any replacement done. I can't fix it because I just use Microsoft's Execute method.
FWIW Meanwhile I was able to test the script at work with Office 2013 installed. It seems to work out.

Steffen
Thanks Steffen!!! not find time to try it out yet...
I tried these steps as below:
1) open Word2013
2) type ABC then save it as wordtest.doc in the same folder as WINWORD.exe C:\Program Files\Microsoft Office\Office15
3) Modify your script as

Code: Select all

.............
%wordrepl% "wordtest.doc" "ABC" "xyz" /i /w
echo %errorlevel%
pause
.............
4) and save it as word_convert.bat in C:\Program Files\Microsoft Office\Office15
5) under C:\Program Files\Microsoft Office\Office15 run word_convert.bat
return 2 (if an error occurred (e.g. MS Word not installed, file not found, file read-only, file password-protected, etc.)

My questions to you, Do I need to save the word document as wordtest.docx as in your scripts via save as type Strict OpenXML Document or Word XML DOcument ?
Anyway, tried both saving and after run, still got the return 2 value same as first time...

Could you please let me know your works fine scenarios or point out my wrong doing...

Thanks

Tried in another computer and works!!!! :o
Last edited by goodywp on 22 Jun 2018 09:24, edited 1 time in total.

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Way to replace string in word DOC ?

#8 Post by Squashman » 22 Jun 2018 09:22

Don't try and read and write to any type of system or Program Files folder. You need elevated privileges to do that.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Way to replace string in word DOC ?

#9 Post by aGerman » 22 Jun 2018 09:25

It doesn't matter if you saved the document as .doc or as .docx as long as you specify the same file name and extension in the script. But why did you save the document in the program files directory? Usually you'd need elevated permissions to do any write operations there (and saving the changed file is a write operation). Also there is no need to have the script in this folder.
If you don't have both the script and the document in the same folder then you need to specify the whole path of your document in the script.

Steffen

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#10 Post by goodywp » 22 Jun 2018 11:41

Squashman wrote:
22 Jun 2018 09:22
Don't try and read and write to any type of system or Program Files folder. You need elevated privileges to do that.
Thanks for your reminding. I just a temporary used for a testing. Did the rest on another folder.

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#11 Post by goodywp » 22 Jun 2018 11:46

aGerman wrote:
22 Jun 2018 09:25
It doesn't matter if you saved the document as .doc or as .docx as long as you specify the same file name and extension in the script. But why did you save the document in the program files directory? Usually you'd need elevated permissions to do any write operations there (and saving the changed file is a write operation). Also there is no need to have the script in this folder.
If you don't have both the script and the document in the same folder then you need to specify the whole path of your document in the script.

Steffen
Thanks Steffen!

Is any way to replace more than one string in the scripts?
say I want to replace ABC to xyz
and also EFG to uvw
Thanks

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Way to replace string in word DOC ?

#12 Post by aGerman » 22 Jun 2018 13:01

Just use the %wordrepl% macro twice in your script. Follow the link in the Usage comment to learn more about the capabilities of a single call.

Steffen

goodywp
Posts: 265
Joined: 31 Jul 2017 09:57

Re: Way to replace string in word DOC ?

#13 Post by goodywp » 22 Jun 2018 14:20

aGerman wrote:
22 Jun 2018 13:01
Just use the %wordrepl% macro twice in your script. Follow the link in the Usage comment to learn more about the capabilities of a single call.

Steffen
Yes!! works perfectly...

Post Reply