面对百万量级的数据,Excel VBA还能打吗?

15 篇文章 3 订阅
13 篇文章 1 订阅

工作中常用Excel处理数据,常常疑惑Excel能够应对的数据量上限是多少?

恰巧今天看到知乎有这么一个问题"处理 30 万行 × 20 列的数据 Excel + VBA 是否可以胜任,Access 是否可以胜任,有没有其他合适的软件推荐?"

关注者还挺多。

结合自己经验,发表一点粗浅看法:

1.先说结论:Excel VBA是可以处理的。

2.关于Excel还是数据库工具更好?

常看到关于Excel爱好者和其他技术流用户的争论,有的说Excel更简单,有的说PowerPivot、Access更强大,有的说数据库工具更专业。总之,众说纷纭。

其实,这是个见仁见智的问题。观点受很多因素的影响,比如知识背景、个人能力特点、所处行业、应用场景、使用习惯等。

Excel的优势是:使用门槛低,学习周期短,开箱即用。对于数据量不是特别大、数据关系不是特别复杂的场景,能够满足绝大多数人日常的工作需求。缺点是:由于所有数据都是以可视化的方式呈现的,当数据量大,尤其是公式多的时候,哪怕改一个数字也可能引起程序无响应或者重新计算页面刷新卡顿。

其他数据库和类数据库工具各有所长,优势是数据存储量大,功能强大,支持复杂逻辑功能多,计算速度快。缺点是:门槛高,对新手和非IT人员不够友好。

对于有一定数据库学习基础和专业背景的人来说,用数据库工作效率更高,但结构简单的数据可能也更愿意用Excel来处理;对于习惯用Excel的朋友们来说,99%的数据处理工作是可以使用Excel来完成的,剩下的1%难度超出自身能力范围了,大概率会委托更专业的同事来处理。如果能学一点公式和VBA,则能大大拓展自身应对数据处理工作的范畴。至少是小白之上,专家未满的水平。

3.Excel VBA处理大数据量的表格或文件的策略选择。

策略一:

表格数据格式尽量整齐统一,减少不必要的格式信息,避免文件过于臃肿。减少在单元格中保留公式。我做两个范例文件,内容完全一致,每个文件包含10000行数据,6列。其中一个所有单元格均保留为值,另一个仅有B、E两列为值,其他列均为公式填充计算出来的结果。可以看出两个文件大小相差还是很明显的。如果文件行列数多了,差距会更大。

策略二:

化整为零,将有规律的数据分类保存在若干不同的文件中,使用VBA处理时,采用循环遍历的方式逐个文件进行处理。每次处理一个小文件,避免将数十万、百万级数据量保存在同一个文件或表格中,造成读写或处理时程序卡死或无响应。

策略三:

将ExcelVBA程序代码与数据分离,数据处理的程序代码保存在支持宏功能的excel文件中(xls、xlsm格式文件等)。需要处理的数据保存在格式化的文本文件中,处理数据时,以文件对象的方式逐行读取文件中的数据,采取流式处理的模式,尽量避免一次性将全部数据读入内存。我曾经使用VBA处理过一个包含9700万+条数据的文件。文件仅3列数据,但数据条数多,文本文件也有3.1GB。逐行访问进行一次计算,用了25分钟(用时与电脑性能相关)。

Excel作为一个办公软件产品,由其定位决定了它本身不是个数据库处理工具。但软件是死的,人是活的。在VBA的加持下,如果能够巧妙设计,还是能够满足绝大多数人在工作中对数据处理的需求的。尤其是对于有规律的重复性工作,用VBA处理就是它的强项了。

能把VBA恰当使用,即使是大量的数据,程序写好,先用少量数据把程序功能测试好。然后就可以一键运行……泡杯咖啡等下班了。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
QTableView + QStandardItemModel适合处理中小型数据量的情况,当数据量过大时,可能会导致界面卡顿或者无法正常显示。为了解决这个问题,可以使用QTableView的分页显示功能,将数据分页加载,只显示当前页的数据,从而避免一次性加载过多数据导致的性能问题。下面是一个简单的示例代码: ```c++ // 创建QStandardItemModel对象 QStandardItemModel *model = new QStandardItemModel(this); // 设置表头 model->setHorizontalHeaderLabels(QStringList() << "Name" << "Age" << "Gender"); // 加载数据 int rows = 1000000; int pageSize = 10000; for (int i = 0; i < rows; i++) { // 分页处理 if (i % pageSize == 0) { int currentPage = i / pageSize + 1; int startRow = (currentPage - 1) * pageSize; int endRow = currentPage * pageSize - 1; model->setRowCount(endRow + 1); tableView->setModel(model); tableView->setRangeSelected(QTableWidgetSelectionRange(startRow, 0, endRow, 2), true); } // 添加数据 QList<QStandardItem*> items; items << new QStandardItem(QString("Name %1").arg(i + 1)); items << new QStandardItem(QString("%1").arg(qrand() % 100)); items << new QStandardItem(QString(qrand() % 2 == 0 ? "Male" : "Female")); model->insertRow(i, items); } ``` 上述示例中,首先创建一个QStandardItemModel对象,并设置表头。然后使用分页方式加载数据,每页显示pageSize条数据,加载完数据后,将当前页的数据设置为QTableView的数据模型。这样可以避免一次性加载过多数据导致的性能问题。在添加数据时,可以使用QStandardItem类来创建每一行数据的列,并将其添加到QStandardItemModel中。 需要注意的是,在处理大量数据时,还有其他一些优化策略可以使用,例如:使用多线程或者定时器进行数据加载、对数据进行缓存等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值