【问题标题】:Updating a bound datatable in Excel using VSTO is slow使用 VSTO 在 Excel 中更新绑定数据表很慢
【发布时间】:2018-05-06 19:22:00
【问题描述】:

我有一个 Excel VSTO 应用程序,它在内存中存储一​​个大型数据表,并将其中的一部分绑定到工作表。用户可以更改他们选择显示的字段,并定期进行大规模更新。

大规模更新循环通过数据表更新几个字段。这个更新过程似乎很慢(即更新 40 条记录可能需要 20 秒)。

数据表非常大(10,000 行 x 450 列),并且绑定到隐藏工作表和绑定到可见工作表的较小视图(20 个字段)。

对数据表的所有更新都在代码中完成。

ProductRow = dt.Rows.Find(foundRows(i)("Primary Key"))
If IsNothing(ProductRow) = False Then
          ProductRow("DECISION") = "Some Value"
          Updated += 1
End If

我怀疑它只是绑定到工作表的大量数据减慢了这个过程,但是任何加快这个过程的建议都是非常受欢迎的。

【问题讨论】:

  • 可以选择 Open XML(github.com/OfficeDev/Open-XML-SDK) 吗?它将使用互操作库消除 COM 层的开销。我还没有看到任何比较,但对于这样的事情,它可能会更快。 COM 层是比文件大小更大的罪魁祸首。
  • 您能否详细说明“将其中的一部分绑定到工作表”的含义以及您是如何实现的?我不使用 VSTO,但使用 Excel 互操作。搜索 VSTO 绑定到工作表,让我相信这是读/写值的基本互操作,而不是更复杂的东西。人们经常以最昂贵的方式对这种读/写进行编码,因此查看该代码会很有用。此外,像ProductRow("DECISION") 这样的模式可能看起来很无辜,但每次执行时都需要进行字符串查找以找到“DECISION”的索引;而是查找索引一次并使用该值。
  • 嗨杰米迈耶。我将不得不看看 Open XML。我没有将其视为一种选择。不幸的是,这是一个托管在 Excel 中的应用程序,所以我有点卡在 COM 层上。我尽可能使用 VSTO 和非 com 代码,但我认为这是我在 Excel 中工作的事实,这使得其中一些东西变慢了。
  • 谢谢 TnTinMn。 VSTO 具有将数据表绑定到工作表的本机功能。这意味着对数据表的任何更新都会立即反映在工作表中,并且您可以确定显示哪些字段。例如,在这个应用程序中,有 400 多个字段,我们允许用户选择他们想要显示的内容,通常约为 20 个。
  • 我在下面提到的另一个快速评论。我为该过程关闭了屏幕更新,这大大提高了性能。我认为每条记录更改都会促使 Excel 更新绑定的工作表 - 由于这些工作表很大,操作需要时间。

标签: c# excel vb.net datatable vsto


【解决方案1】:

使用 VSTO 循环遍历电子表格几乎在任何具有这么多行/列的情况下都会很慢。即使是 VBA 也不会那么擅长这项任务。

我建议您实施穷人的状态模型。换句话说,添加一列(必要时隐藏)来指示每一行的状态——特别是它是否已被更改。进行任何更改时,请确保更新行状态的列以显示该行已更改。如果您还没有办法完成此操作,您可以通过工作表更改事件来完成此操作。

然后,当您循环浏览电子表格时,只关注状态已更改的值。我的猜测是您正在检查和更新每一行,即使是那些不需要更新的。

作为最后的想法,这是否必须在 Excel 中完成?标准 .NET 网格中的数据绑定几乎可以开箱即用地处理这个问题。

【讨论】:

  • 嗨哈姆伯恩。当我设置数据表时,我将字段“主键”指定为主键。上面的代码应该只找到那一条记录?我确实以与您建议的方式类似的方式维护了已编辑记录的列表。即便如此,循环完成这 40 个奇怪的变化也需要一段时间。
  • 我尝试过的一件事是关闭屏幕更新。我认为这可能是罪魁祸首。由于数据表已绑定,我认为每条记录都会更改屏幕更新。关闭进程的屏幕更新有很大的不同。
  • 我很乐意将其开发为应用程序,而不是 Excel 插件,但这正是用户迫切想要的 :)
  • 感谢您的反馈。我理解——用户非常喜欢 Excel。我没有考虑屏幕更新;好主意啊。我实际上建议您将其发布为答案(回答您自己的问题)并将其标记为已接受;我会投赞成票——这将有助于未来可能遇到类似问题的其他人。如果您将interop 添加到您的标签中,这将有助于有问题的人找到它。
猜你喜欢
  • 2013-07-14
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2021-11-07
  • 1970-01-01
  • 2022-10-13
相关资源
最近更新 更多