Solved How to find/replace text in a .docx file using QAxObject ?
-
Hey there,
I wish if someone could help me, how we can find & replace text in a .docx file using QAxObject.
And Thanks. -
Hi, a solution in this forum here
-
@hskoglund Thanks for the quick reply, but inforutly that code seems not working "successfully", I'm wondering if you had tried to run it, because once I compile it, I got 4 problems (lignes: 6-7-8-10: -> /.), and even if you fix them, in the and you will have a .docx file that contains: "hello", instead of "word".
So anyway, thanks for your time. -
Hi, sorry no I didn't test it, and agreed it looks very complicated. There should be a simpler way, I can look later today.
-
@hskoglund Thanks so much for your help.
-
Hi, I got 2 examples for you. Note: they both require Word to be installed so it can open the .docx file, I forgot to ask if you wanted to manipulate the file without Word, i.e. only with Qt? (That's a different story altogether :-)
First the simple one, it assumes you already have started Word and opened the .docx file:
I created a vanilla Widgets app, added "axcontainer" to the .pro file, e.g.:QT += core gui axcontainer
#include "qaxobject.h" at the top of mainwindow.cpp and then inserted this code after "ui->setupUi(this);" :// connect to an existing opened docx file auto wApp = new QAxObject(this); wApp->setControl(("{000209FF-0000-0000-C000-000000000046}&")); wApp->setProperty("Visible",true); auto sel = wApp->querySubObject("Selection"); auto find = sel->querySubObject("Find"); QString sOld = "old"; // change from this QString sNew = "new"; // to this one at the time find->dynamicCall("Execute(QString)",sOld); sel->dynamicCall("TypeText(QString)",sNew);
The search sets the selection, which the TypeText() call just replace.
I'll post the more advanced example after this one.
-
The more advanced one uses the same Execute call is in my link above, but I managed to clean up and simplify it slightly.
The Execute call takes 15 (!) arguments:
findText,
matchCase, matchWholeWord, matchWildCards, matchSoundsLike, matchAllWordForms, forward,
wrap,
format,
replaceWithText
replace,
matchKashida, matchDiacritics, matchAlefHamza, matchControl.All the "matchXxxx", "forward" and "format" arguments are booleans, "wrap" and "replace" are integers and the rest are strings.
Let's look at the code, in this example I'm opening the .docx file and not using any selections (which makes it faster). Start with the same vanilla Widget example as above and add this after "ui->setupUi(this);":
// opens a .docx file auto wApp = new QAxObject("Word.Application"); auto docs = wApp->querySubObject("Documents"); auto doc = docs->querySubObject("Open(QString)","c:/temp/test.docx"); if (nullptr == doc) qFatal("File not found"); auto active = wApp->querySubObject("ActiveDocument()"); auto content = active->querySubObject("Content()"); auto find = content->querySubObject("Find"); QString sOld = "old"; QString sNew = "new"; bool bMatchCase = false; bool bMatchWholeWord = false; bool bMatchWildCards = false; bool bReplaceAll = true; QVariantList vl = { sOld, bMatchCase, bMatchWholeWord, bMatchWildCards, false, false, true, 1, false, sNew, bReplaceAll ? "2" : "1" }; find->dynamicCall("Execute(QString,bool,bool,bool,bool,bool,bool,int,bool,QString,int)",vl);
Because the dynamicCall accepts at most 9 arguments, instead I pack them in a variantlist. Also the last 4 arguments I didn't bother to fill in, and I assume Word defaults them to false.
-
Thanks so much @hskoglund , it's really working now.
Reputation++ , +Follower...