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

时间:2017-09-05 01:16:08

标签: arrays excel vba excel-vba excel-2016

我不是VBA新手,但我有新手问题。

我正在研究一个项目,我需要创建一个函数,它在电子表格中占用某个单元格,扩展范围然后对其进行求和。

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声明为范围,然后将其设置为工作表中的范围。

附加信息:参数 Sales 对应于(例如)工作表中的GJ5范围。 DataWindow 是一个整数变量,用于确定要求和的范围的长度。在这种情况下,它是12.因此,通过使用 Sales 范围的行号和列号,然后通过DataWindow + 1减少列索引来创建范围。

该函数在电子表格中输入“= Top_Performers(GJ5,Best_Clients_months)”(在本例中为HN列,单元格HN5),其中Best_Clients_months只是在此示例中对应于12的命名范围。

表单和列GJ的屏幕截图:

The screenshot of the sheet and column GJ

输入功能的HN列的屏幕截图:

The screenshot of column HN where the function is entered

我甚至逐步完成了第一个例子中的代码,并且locals窗口显示了数组中的正确值(98.32当第一个arg是GJ4时,即第4行,119.25和42.42,当第一个arg是GJ5时 - 第五个行)但仍然输出0.

在对数组进行求和时,我通常从未遇到过问题,所以我对此感到困惑。

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

2 个答案:

答案 0 :(得分:3)

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

如果您将MyArray分配更改为

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

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

答案 1 :(得分:0)

如果你打开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)