Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to find/replace text in a .docx file using QAxObject ?
Forum Updated to NodeBB v4.3 + New Features

How to find/replace text in a .docx file using QAxObject ?

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 3.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SamurayH
    wrote on 21 Aug 2017, 19:51 last edited by
    #1

    Hey there,
    I wish if someone could help me, how we can find & replace text in a .docx file using QAxObject.
    And Thanks.

    "قال رسول الله صلى الله عليه وسلم : " أحب الناس إلى الله أنفعهم للناس

    1 Reply Last reply
    0
    • H Offline
      H Offline
      hskoglund
      wrote on 21 Aug 2017, 21:19 last edited by
      #2

      Hi, a solution in this forum here

      S 1 Reply Last reply 22 Aug 2017, 09:13
      2
      • H hskoglund
        21 Aug 2017, 21:19

        Hi, a solution in this forum here

        S Offline
        S Offline
        SamurayH
        wrote on 22 Aug 2017, 09:13 last edited by
        #3

        @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.

        "قال رسول الله صلى الله عليه وسلم : " أحب الناس إلى الله أنفعهم للناس

        1 Reply Last reply
        0
        • H Offline
          H Offline
          hskoglund
          wrote on 22 Aug 2017, 10:57 last edited by
          #4

          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.

          S 1 Reply Last reply 22 Aug 2017, 11:34
          1
          • H hskoglund
            22 Aug 2017, 10:57

            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.

            S Offline
            S Offline
            SamurayH
            wrote on 22 Aug 2017, 11:34 last edited by
            #5

            @hskoglund Thanks so much for your help.

            "قال رسول الله صلى الله عليه وسلم : " أحب الناس إلى الله أنفعهم للناس

            1 Reply Last reply
            0
            • H Offline
              H Offline
              hskoglund
              wrote on 23 Aug 2017, 04:26 last edited by
              #6

              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.

              1 Reply Last reply
              2
              • H Offline
                H Offline
                hskoglund
                wrote on 23 Aug 2017, 04:56 last edited by
                #7

                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.

                S 1 Reply Last reply 23 Aug 2017, 15:16
                6
                • H hskoglund
                  23 Aug 2017, 04:56

                  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.

                  S Offline
                  S Offline
                  SamurayH
                  wrote on 23 Aug 2017, 15:16 last edited by SamurayH
                  #8

                  Thanks so much @hskoglund , it's really working now.
                  Reputation++ , +Follower...

                  "قال رسول الله صلى الله عليه وسلم : " أحب الناس إلى الله أنفعهم للناس

                  1 Reply Last reply
                  0

                  1/8

                  21 Aug 2017, 19:51

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved