2012-01-14 79 views
3

我在使用列表对象(AKA Excel表格)的Excel应用程序中遇到问题。我怀疑这可能是一个错误,但尽管我谷歌搜索,我找不到任何它的参考。我已经为我的应用程序开发了一种解决方法,但是我感兴趣的是如果任何人都可以提供有关发生这种情况的信息。Excel列表 - 对象VBA性能错误?

注意:我在Windows Vista上使用Excel 2007。设置如下:我有一个电子表格,它将数据保存在List对象中,VBA代码可以通过命令按钮启动;此代码可能会对工作表上的任意数量的单元格进行编辑,因此Excel的计算模式在进行任何编辑之前都设置为手动。

我遇到的问题是,如果当前活动的单元格在列表对象内,那么将计算模式设置为手动似乎没有任何效果。因此,如果用户碰巧在同一个实例中打开繁重的计算工作簿,那么VBA代码运行速度非常缓慢。我实际上不得不拉开我的应用程序以发现这是由活动单元格引起的;我用这个场景的简单版本创建了一个新的工作手册,以确认我的应用程序没有出现某种腐败。

我已经做了一些测试案例这个问题,以下是从我所发现的结果:

  1. 虽然看上去一般与计算,仍然有时间差时,计算模式手动和自动之间切换...

    • 手册= 7.64秒
    • 自动= 9.39秒

    手动模式比自动模式快不到20%。但我的期望是他们会差不多,因为即使在手动模式下,这个问题似乎也是开始计算的。

  2. 与此相比,当活动单元格是不是在一个列表对象,结果有很大的不同......

    • 手册= 0.14秒
    • 自动= 3.23秒

    现在,手动运行速度提高了50倍,自动运行表明计算时间不应超过3.2秒!因此,现在第一个测试看起来像是在手动模式下可能会运行两次计算,而在自动模式下则会运行近三次。

  3. 再次重复这一试验,这一次是在与任何单元格不计算公式的情况下,突然它似乎并不那么糟糕,

    • 活动单元格列出对象& Calc是手动= 0.17秒
    • 活动单元格列出对象& Calc是自动= 0.20秒
    • 活动单元格是空& Calc是手动= 0.14秒
    • 活动单元格是空& Calc是Automatic = 0。18秒

    它仍然较慢,但现在只有10-20%,使它不明显。但是这确实表明问题必须以某种方式与计算相关,否则它应该与第一次测试一样长。

如果有人想创建这些测试,看看自己的设置如下:

  • 新工作簿添加了一个列表对象(没有链接到任何数据)
  • 添加一些公式,将需要一段时间来计算(我刚做'= 1 * 1'重复30,000次)
  • 写一个快速的VBA代码,通过细胞的简单编辑(I)环数百倍,(ii)和记录需要的时间
  • 然后只需运行该代码同时改变列表对象和空单元格之间的活动单元格

我会非常感兴趣的是,如果有人能够解释为什么Excel会以这种方式运行,并且如果有错误或者是否有一些与List对象有关的功能,这些功能实际上有一些真正的用途?

感谢, 斯图尔特

+0

我无法复制您的结果。在手动计算模式下编辑列表对象中的数据时,不会重新计算易失公式。如果Screenupdating处于打开状态,那么反复编辑列表对象中的列表对象并且列表对象中的活动单元格速度与预期的一样缓慢,但屏幕更新关闭时,我没有得到明显区别。你能发布一个链接到你的示例文件吗? – 2012-01-15 18:31:59

+0

@CharlesWilliams感谢您的回复。也许我没有完全解释我的设置,[链接到这里下载](http://dl.dropbox.com/u/3010466/Excel%20List-Object%20VBA%20Preformance%20Bug.xlsm) 我已经screenupdating转向在我的所有测试中关闭。我并没有完全知道什么时候excel会运行计算,但是我今天在worksheet_calculation事件上添加了一个计数器,看看它是如何表现的 - 当计算模式为手动计数时为0,并且形式为真。所以我可能是我在咆哮错误的树? – Skytunnel 2012-01-15 19:28:27

+2

感谢您的链接。为了获得放缓,你似乎需要3个条件:1.活动单元格必须在Listobject(Table)中。 2.正在更新的单元必须与Listobject在同一工作表上。 3.所用时间是公式数的函数(但公式不会被重新计算)。目前我无法想象为什么会发生这种情况。 – 2012-01-16 16:06:14

回答

1

这不是相对于“虫”你发现了,这是相当有趣和耐人寻味。

我想和大家分享,有避免延误计算一个伟大的方式。我在这方面有着出色的成绩,现在我一直都在使用它。

简而言之,Excel中需要较长的时间复制数据来回“VBA世界”和“电子表格世界”之间。

如果你做所有的“读”一次,过程,然后做一次所有的“写”,你就会得到惊人的表现。

http://msdn.microsoft.com/en-us/library/ff726673.aspx#xlFasterVBA

在部分标注:这是使用变长数组作为记录在这里完成读写大型数据块在单次操作

我能够重构一些代码,我有花费5分钟运行并将其降至1.5分钟。重构花费了我10分钟,这是惊人的,因为它是相当复杂的代码。

0

关于表的性能(和性能,在一般情况):

我知道这是一个老问题,但我想获得该记录。旧版本的Excel和2007年后的版本之间改变

的一件事是Excel中现在激活任何PasteSpecial的操作的靶纸。您无法通过关闭ScreenUpdating并手动进行计算来覆盖它。这种激活会使工作表可见,并导致无法控制的闪烁。

我原来的VBA代码跑得很快上运行Excel 2000中的一个现代化的机器上的变化到Excel 2013在代码执行的可怕的缓慢令人惊叹的一个古老的,单处理器XP框。杀死性能的三个方面是PasteSpecial从一个表单到另一个表单,以及需要激活表单的其他任何代码(缩放级别,高级过滤器,表单级范围名称等)以及自动执行表单保护/取消保护。

这太糟糕了,因为PasteSpecial帮助“清理”了您复制的数据(将.Copy直接用于目标会导致偶然的错误)。

因此,您需要检查您的代码,并确保您正在使用直接分配给您需要的数据类型(例如Value,Value2,Text和Formula中的数据类型)的正确属性,而不是PasteSpecial。

例如.Range(“MYRANGE”)。Value = .Cells(5,7).Value2

您还需要谨慎地抵制在整个代码中使用Select和Activate。

如上所述,您在Excel论坛中发现的关于最后一点的许多评论将会使您“从不”需要使用Activation的声明,这显然是不真实的,因为Excel中的一些内容仅适用于或需要激活床单。了解激活由特定方法或使用对象自动强制的情况也有助于编码。不幸的是,你不会看到这方面的文档。

更新:

关于条件格式,你会遇到大量的有条件格式的单元时,发现有关的Excel缓慢各种论坛的抱怨。我怀疑这会影响Excel表格,因为他们有很多表格格式选项。为了测试这一点,我拿了一个我们使用的大型工作簿,目前这些工作簿被格式化为几个工作表,并且他们的Excel表格样式相同。

将表格转换为常规范围之后,我注意到代码执行速度没有差别。这似乎表明,Excel表格格式的使用远远优于条件格式化自己的单元格阵列。