使用SUMPRODUCT和COUNTIFS的Excel VBA - 速度问题

时间:2016-09-19 06:08:19

标签: excel vba excel-vba

我有速度问题。 (长篇大论道歉)。我正在使用Excel 2013和2016 for Windows。

我有一个工作簿,可以在200,000个单元格表(1000行x 200列)上执行10,000多次计算。

每个计算返回一个整数(例如,过滤行的计数)或更多通常为百分比(例如,过滤行的值的总和除以行的值的总和)。计算的结构是SUMPRODUCT(COUNTIFS())想法的变化,沿着以下几行:

=IF($B6=0,
    0,
    SUMPRODUCT(COUNTIFS(
    Data[CompanyName], 
    CompanyName,
    Data[CurrentYear], 
    TeamYear,
    INDIRECT(VLOOKUP(TeamYear&"R2",RealProgress,2,FALSE)),
    "<>"&"",
    Data[High Stage],
    NonDom[NonDom]
    ))
    /$B6
)

上面解释:

  1. 对数据[公司名称]和CompanyName是表格中的列和第一个过滤器的条件值。
  2. 数据[当前年份]和TeamYear对与上述相同,构成第二个过滤器。
  3. 第三对查找中间表并返回列的名称,条件("<>"&"")为'非空白',即返回此列中具有值的所有行
  4. 最后,第四对类似于上面的3但是返回一组与
  5. 中的值集相匹配的值
  6. 最后,四个过滤器使用AND语句连接在一起。 重要的是要注意,在所有计算中,使用SUMPRODUCT(COUNTIFS())应用相同的原则 - 但是这个主题有很多变化。 目前,在选择的工作表范围内使用Calculate(而不是计算整个工作簿的速度较慢),计算速度大约为30-40秒。不坏,并且可以容忍,因为计算不会一直进行。
  7. 不幸的是,该模型将被扩展,现在可以接近20,000行而不是1,000行。计算性能直接与行数或单元格数相关联,因此我预计性能会直线下降!

    明显的解决方案[1]是使用数组,理想情况下将内存中保存的数组传递给单元格中的公式,然后将其与过滤器及其条件一起处理(查找过滤器也是数组)。 / p>

    替代解决方案[2]是使用数组编写UDF,但在互联网上阅读的意见是UDF比本机Excel函数慢得多。

    两个问题:

    1. 解决方案[1]是否可行,以及最好的方法,如果是这样,我将如何构建它?
    2. 如果解决方法[1]不可能或不是最好的方法,那么有没有人想过将解决方案[2]与我当前的解决方案相比有多快?
    3. 还有其他更好的解决方案吗?我了解Power BI Desktop,PowerPivot和PowerQuery - 但是这是一个供非Excel用户使用的商业应用程序,需要以行和列的当前Excel'网格'形式呈现。
    4. 非常感谢您的阅读!

      附录:我将尝试在Worksheet.Activate事件上为每个工作表运行一个数组计算,看看是否节省了一些时间。

1 个答案:

答案 0 :(得分:0)

如果想提高速度,将数据写入数组通常是一个好主意。做完这样:

Dim myTable As ListObject
Dim myArray As Variant

'Set path for Table variable
  Set myTable = ActiveSheet.ListObjects("Table1")

'Create Array List from Table
  myArray = myTable.DataBodyRange

Source