VBA WorksheetFunction.Sum 不适用于数组但适用于范围?

VBA WorksheetFunction.Sum doesn't work with array but works with range?

我不是 VBA 新手,但我遇到了新手问题。

我正在做一个项目,我需要创建一个函数来获取分布中的某个单元格sheet,扩展范围然后对其求和。

Function Top_Performers(Sales As Range, DataWindow As Integer)

Dim MyArray () As Variant
Dim c As Integer, r As Integer


r = Sales.Row
c = Sales.Column

MyArray = Range(Worksheets("Data").Cells(r, c - DataWindow + 1), 
Worksheets("Data").Cells(r, c))

Top_Performers = Application.WorksheetFunction.Sum(MyArray)

但是,即使对于非零范围,此函数也会输出零值。 但是,下面的代码有效。

Function Top_Performers(Sales As Range, DataWindow As Integer)

Dim MyArray As Range
Dim c As Integer, r As Integer


r = Sales.Row
c = Sales.Column

Set MyArray = Range(Worksheets("Data").Cells(r, c - DataWindow + 1), 
Worksheets("Data").Cells(r, c))

Top_Performers = Application.WorksheetFunction.Sum(MyArray)

唯一不同的是,在第二个例子中,我将MyArray声明为范围,然后将其设置为工作中的范围sheet。

附加信息:参数 Sales 对应于(例如)sheet 中的范围 GJ5。 DataWindow是一个整型变量,它决定了求和范围的长度。在本例中为 12。因此,通过使用 Sales 范围的行号和列号,然后将列索引减去 DataWindow + 1.

来创建范围

函数在传播sheet中输入为“=Top_Performers(GJ5, Best_Clients_months)”(在本例中为 HN 列,单元格 HN5),其中 Best_Clients_months 只是一个命名范围,对应于本例中的 12。

sheet 和 GJ 栏的屏幕截图:

输入函数的HN列截图:

我什至单步执行了第一个示例中的代码,局部变量 window 在数组中显示了正确的值(当第一个 arg 为 GJ4 时为 98.32,即第 4 行,而 119.25 和 42.42 当第一个参数是 GJ5 - 第五行)但仍然输出 0。

我通常在对数组求和时从来没有问题,所以我对此感到困惑。

P.s。该工作簿是机密的,因此我只能使用这些屏幕截图来显示使用第二个示例中的代码时的结果,而不是使用第一个示例中可以找到的零。

如果你打开Locals Window,我想你会发现正在创建的数组是二维的。您可以使用 Transpose 将其转换为一维数组。下面的代码应该可以工作,尽管有时您必须使用 Transpose 两次。

Function Top_Performers(Sales As Range, DataWindow As Integer)

Dim MyArray () As Variant
Dim c As Integer, r As Integer


r = Sales.Row
c = Sales.Column

MyArray = Range(Worksheets("Data").Cells(r, c - DataWindow + 1), 
Worksheets("Data").Cells(r, c))

MyArray  = Application.Transpose(MyArray)

Top_Performers = Application.WorksheetFunction.Sum(MyArray)

问题是范围被格式化为货币,因此您的数组包含 Variant/Currency 个值,因为您隐式使用默认值 属性,它将格式为货币的单元格转换为 VBA货币数据类型。
SUM(和其他工作表函数)不理解 VBA 货币或日期数据类型,因此您得到零。

如果将 MyArray 赋值更改为

MyArray = Range(Worksheets("Data").Cells(r, c - DataWindow + 1), _
Worksheets("Data").Cells(r, c)).Value2

然后它将起作用(.Value2 不会转换为货币和日期 VBA 数据类型)。
当您使用 Range 变量而不是变体数组时,转换永远不会发生,因为您将 Range 对象传递给 SUM。