c++qtms-wordqt5

How to add a new row to an existing MS Word table using QT5?


In general I am trying to transfer data from QTableView to a prepared .docx file, where I will use a placeholder to replace the data I need.

At the moment I stopped at adding a new row to an existing table in an MS Word document, but I can't understand the syntax (it keeps saying "No such property in" with different functions). The only thing that works correctly is getting the amount of tables in the document.

QAxObject *wApp = new QAxObject("Word.Application");
auto docs = wApp->querySubObject("Documents");
auto doc  = docs->querySubObject("Open(QString)","C:\\pathToFile\\qwe.docx");
if (doc == nullptr) {
    doc->dynamicCall("Close()");
    wApp->dynamicCall("Quit()");
    QMessageBox::information(this, "File opening", "File not found");
    return;
}

auto active  = wApp->querySubObject("ActiveDocument()");
auto tables  = active->querySubObject("Tables");

qDebug() << tables->dynamicCall("Count()");

// doc->dynamicCall("Save()");
doc->dynamicCall("Close()");
wApp->dynamicCall("Quit()");
delete wApp;

I also tried to get the amount of rows in the table but it outputs 0.

auto table = tables->querySubObject("Select(int)", 1);
qDebug() << table->dynamicCall("Rows");

Examples of errors:

QAxBase::dynamicCallHelper: Table: No such property in {000209ff-0000-0000-c000-000000000046} [Microsoft Word Application]
    Candidates are:
        TaskPanes
        Tasks
        Templates
        Top
QAxBase::dynamicCallHelper: Type(QString): No such property in  [unknown]
    Candidates are:
        TableDirection
        Tables
        Title
        TopPadding

Solution

  • I tried to select the wrong member of the Tables class, which led to strange results (https://learn.microsoft.com/en-us/office/vba/api/word.tables.item), but after a detailed review of all MS Word functions (open MS Word, press Alt+F11 and then F2) I realized that must select a table by index using Item(Index As Long) As Table which will return the Table class. The Table class has a Rows member in its properties (https://learn.microsoft.com/en-us/office/vba/api/word.table.rows) with the help of which I just added a row to the table.

    There is my solution

    QAxObject *wApp = new QAxObject("Word.Application");
    auto docs = wApp->querySubObject("Documents");
    auto doc  = docs->querySubObject("Open(QString)", "C:\\pathToFile\\qwe.docx");
    if (doc == nullptr) {
        QMessageBox::information(this, "File opening", "File not found");
        wApp->dynamicCall("Quit()");
        delete wApp;
        return;
    }
    
    auto active = wApp->querySubObject("ActiveDocument()");
    auto tables = active->querySubObject("Tables");
    auto table  = tables->querySubObject("Item(int)", 1); // First table in the document
    
    auto rows = table->querySubObject("Rows");
    rows->dynamicCall("Add()");
    
    doc->dynamicCall("Save()");
    doc->dynamicCall("Close()");
    wApp->dynamicCall("Quit()");
    delete wApp;
    

    Upd: Actually, to select the table you can just use auto table = doc->querySubObject("Tables(2)")
    Like this

    auto table = doc->querySubObject("Tables(2)"); // Row will be added to the second table
    auto rows = table->querySubObject("Rows");
    rows->dynamicCall("Add()");