ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

干货|使用Qt将采集到的结果数据保存至Excel中

2021-09-25 19:02:40  阅读:325  来源: 互联网

标签:VBA Qt querySubObject excel Excel QAxObject 干货 QString


大家好,我是小哈哥,今天我们接着上一篇网文的内容,继续完成网友问答。

今天我们来分享第三个问题的解决方案:

  • 基于Modbus协议将电压数据上传至上位机
  • Qt程序解析Modbus协议,并将解析之后的结果显示在曲线中
  • 将声音强度数据保存至Excel中

本次分享的实例在 分享一个非常强大且好用的绘图控件QCustomPlot 的程序基础上完成。

要解决这个问题,我们要先了解一下,什么是VBA?

VBA

很多人听过大名鼎鼎的VBA,至于怎么用可能不太熟悉,那么VBA是什么呢?

VBA(Visual Basic for Applications)是Visual Basic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展Windows的应用程序功能,特别是Microsoft Office软件。它也可说是一种应用程式视觉化的 Basic 脚本。

Office取得巨大成功的一个重要原因就是VBA,使用VBA可以完成很多事情,基于Excel、Word的VBA小程序不计其数。掌握对VBA语言的使用,可以让复杂的工作简易化,减少不必要的重复性工作,大大提高我们的工作效率。

VBA 是基于Visual Basic 发展而来的,它们具有相似的语言结构。

我们来一个VBA小程序

VBA是依附于Office的。

在新工作表的Sheet1上点击右键,弹出菜单中选择“查看代码”。

或者直接使用快捷键 Alt+F11 ,打开VBA编辑器:

在编辑框中写入如下代码:

Sub TestDemo()
    MsgBox ("Hello world")
End Sub

我们点击运行按钮,可以查看此过程的运行结果。

这样我们的第一个VBA程序就完成了。

将上面的过程改成函数,我们还可以在单元格的双击事件中调用该函数,具体代码如下:

Function TestDemo()
    MsgBox ("Hello world")
End Function

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    ' Call TestDemo
    Application.Run TestDemo()
End Sub

这样,我们在Excel中,双击单元格,就可以弹出内容为Hello world的对话框了,具体演示效果如下:

VBA中的过程(Procedure)有两种,它们都是一个可以获取参数、执行一系列语句、以及改变其参数的值的独立过程。

一种叫函数(Function) '可调用代码block
一种叫子程序(Subroutine) '可执行代码block

VBA操作Excel单元格

目标:生成一个Excel,然后修改Sheet的名字并让单元格内填充内容,具体演示效果如下:

涉及的完整代码如下:

Sub AddWorkbooks()
    Set wb = Workbooks.Add
    Set ws = wb.Sheets(1)
    ws.Name = "嵌入式从0到1"
    ws.Cells(1, 1) = "序号"
    ws.Cells(1, 2) = "声音强度"
    For i = 2 To 10
        ws.Cells(i, 1) = i - 1
    Next i
    ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & Application.PathSeparator & "test.xlsx", FileFormat:=xlOpenXMLWorkbook
    ActiveWindow.Close
End Sub

.xlsx文件为什么不能保存VBA代码呢?

2003版(.xls文件)可以保存带VBA代码的文件,不用更改扩展名。但是,当你要运行宏时,必须在安全性设置里启用宏,比较麻烦。2007版以上进行了改进,可以直接把带VBA代码的文件另存为.xlsm文件。这样,打开这个文件,可以直接运行宏。

.xlsx文件保存带有VBA代码的文件会有提示,将此文件另存为.xlsm文件即可避免提示。

.xlsm文件是“启用宏的工作簿”,也就是含有VBA代码的表格。

Qt的Excel操作常用类

在VBA的参考手册中就可以看到具体函数、属性的用法,Qt操作Excel主要通过 QAxObject + Excel VBA来实现!

QAxObject *excel = NULL;
excel = new QAxObject(“Excel.Application”);

  1. 设置当前进程界面不可见:
    excel->dynamicCall(“SetVisible(bool)”, false);
  2. 获取工作簿集合:
    QAxObject *workbooks = NULL;
    workbooks = excel->querySubObject(“WorkBooks”);
  3. 打开已存在的工作簿:
    QAxObject *workbook = NULL;
    QString templateFilePath = qApp->applicationDirPath() + “/template.xlsx”;
    workbook = workbooks->querySubObject(“Open(QString&)”,templateFilePath);
  4. 获取所有的工作表:
    QAxObject * worksheets = workbook->querySubObject(“WorkSheets”);
  5. 获取第一个工作表:
    QAxObject * worksheet = worksheets->querySubObject(“Item(int)”, 1);
  6. 获取表范围:
    QAxObject * usedrange = worksheet->querySubObject(“UsedRange”);
  7. 获取行数:
    QAxObject * rows = usedrange->querySubObject(“Rows”);
    int iRows = rows->property(“Count”).toInt();
    //获取起始行
    int iStartRow = rows->property(“Row”).toInt();
  8. 获取列数:
    QAxObject * columns = usedrange->querySubObject(“Columns”);
    int iColumns = columns->property(“Count”).toInt();、
    //获取起始列
    int iColumn = columns->property(“Column”).toInt();
  9. 设置某单元格的值:
    QString cora = “A” + QString::number(iStartRow+iRows+i);
    QAxObject *rangea = worksheet->querySubObject(“Range(QString)”, cora);
    rangea->setProperty(“Value”, arrX[i]);

将声音强度保存至Excel中

首先需要在pro文件中添加axcontainer

QT       += core gui printsupport axcontainer
QT       += serialport

然后添加包含文件

#include <QAxObject>

如下是代码的具体实现:

void MainWindow::on_btnExportData_clicked()
{
    QAxObject *excel = NULL;
    QAxObject *workbooks = NULL;
    QAxObject *workbook = NULL;
    excel = new QAxObject("Excel.Application");
    excel->dynamicCall("SetVisible(bool)", false);
    workbooks = excel->querySubObject("WorkBooks");

    QString templateFilePath = qApp->applicationDirPath() + "/template.xlsx";

    workbook = workbooks->querySubObject("Open(QString&)",templateFilePath);

    //获取活动工作簿
    QAxObject * worksheets = workbook->querySubObject("WorkSheets");        //获取所有的工作表

    QAxObject * worksheet = worksheets->querySubObject("Item(int)", 1);

    //表格范围和行数列数
    QAxObject * usedrange = worksheet->querySubObject("UsedRange");

    QAxObject * rows = usedrange->querySubObject("Rows");
    int iRows = rows->property("Count").toInt();

    QAxObject * columns = usedrange->querySubObject("Columns");
    int iColumns = columns->property("Count").toInt();

    int iStartRow = rows->property("Row").toInt();

    int iColumn = columns->property("Column").toInt();

    //写入数据
    for(int i = 0;i<arrY.size();i++)
    {
        QString cora = "A" + QString::number(iStartRow+iRows+i);
        QAxObject *rangea = worksheet->querySubObject("Range(QString)", cora);
        rangea->setProperty("Value", arrX[i]);

        QString corb = "B" + QString::number(iStartRow+iRows+i);
        QAxObject *rangeb = worksheet->querySubObject("Range(QString)", corb);
        rangeb->setProperty("Value", arrY[i]);
    }

    workbook->dynamicCall("Save()");   //!保存文件
    workbook->dynamicCall("Close()");
    excel->dynamicCall("Quit()");

    if (excel)
    {
        delete excel;
        excel = NULL;
    }

    QMessageBox::information(0 ,"提示" ,"数据保存成功", QMessageBox::Ok | QMessageBox::Default , 0 );
}

结果测试

本实例实现的功能是打开一个模板文件,把传入的记录写到指定的单元格,并自动完成保存和关闭的操作。

下次导出的数据会追加到上次导出数据的尾部。

具体演示效果如下:

对于简单的数据保存,可以使用 .csv 文件,操作简单。如果想要使用Excel的复杂功能,可以使用本文的方法进行操作。

参考阅读

上位机如何获得环境声音强度的大小

分享一个非常强大且好用的绘图控件QCustomPlot

欢迎关注

小伙伴们可加微信[chengxuyuanxiaoha]进技术交流群,与更多同道中人一起成长。

长按关注

标签:VBA,Qt,querySubObject,excel,Excel,QAxObject,干货,QString
来源: https://blog.csdn.net/rsd102/article/details/118683953

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有