Excel VBA UDF 数组函数 returns 所有单元格的相同值

Excel VBA UDF Array function returns the same value for all cels

我正在尝试将 Excel VBA UDF 函数设为 return 数组。截至目前,函数 returns #VALUE!如果我将参数定义为双数组或数组中的所有单元格都具有相同的值,如果我将参数定义为变体,即使我在 VBE 和 return 数组中签入了 Locals window,也会出错变量实际上包含不同的值。

这是我的代码:

Function VaRScenariosTest(ByRef dblRealRates() As Double/Variant) As Double()
'dblRealRates() is defined as either Double or Variant
Dim intCount As Integer
Dim dblTemp() As Double

For intCount = LBound(dblRealRates) To (UBound(dblRealRates) - 1)
  ReDim Preserve dblTemp(1 To intCount)
  dblTemp(intCount) = dblRealRates(intCount + 1) - dblRealRates(intCount)
Next intCount

VaRScenariosTest = dblTemp

End Function

Function Range2dblArray(ByRef rngRange As Range) As Double()

Dim dblTemp() As Double
Dim intCount As Integer

For intCount = 1 To rngRange.Count
  ReDim Preserve dblTemp(1 To intCount)
  dblTemp(intCount) = rngRange.Cells(intCount)
Next intCount

Range2dblArray = dblTemp

End Function

我按以下方式调用电子表格中的函数: function call in excel with dblRealRates() as Double/Variant

E 列包含函数的输入,F 列包含应由函数 return 编辑的值,G 列包含函数本身。如果我将 dblRealRates() 变量类型定义为双精度,则公式 returns #VALUE!错误。如果我将其定义为变体,则电子表格中的 returned 值是相同的。 如果我在 End Function 行暂停代码的执行并查看 Locals WIndow,您实际上可以看到数组中的值是不同的,并非全部等于 0.000016287,如电子表格中的输出所示:Function Array values in Locals Window

有人能告诉我为什么当 dblRealRates() 变量被定义为双精度时公式 return 会出错吗?如果它被定义为变体,为什么它 return 是相同的值?

一维数组被视为由 x 列构成的一行,因此这就是为什么您的值总是相同的原因。 (整个结果列都分配了第一列的值 returned。)

以下代码适用于您的情况(但如果您更改内容以处理行而不是列,无疑会出现问题):

Function VaRScenariosTest(ByRef dblRealRates() As Variant) As Variant()
    Dim intCount As Integer
    Dim dblTemp() As Double

    For intCount = LBound(dblRealRates) To (UBound(dblRealRates) - 1)
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = dblRealRates(intCount + 1, 1) - dblRealRates(intCount, 1)
    Next intCount

    VaRScenariosTest = Application.Transpose(dblTemp)
End Function

Function Range2dblArray(ByRef rngRange As Range) As Variant()
    Dim dblTemp() As Double
    Dim intCount As Integer

    For intCount = 1 To rngRange.Count
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = rngRange.Cells(intCount)
    Next intCount

    Range2dblArray = Application.Transpose(dblTemp)
End Function

或者,通过在 Excel 公式本身中对 Range2dblArray 的结果进行转置

{=VaRScenariosTest(TRANSPOSE(Range2dblArray(E2:E21)))}

你可以保留原来的 Range2dblArray 不变,只修改 VaRScenariosTest:

Function VaRScenariosTest(ByRef dblRealRates() As Variant) As Variant()
    Dim intCount As Integer
    Dim dblTemp() As Double

    For intCount = LBound(dblRealRates) To (UBound(dblRealRates) - 1)
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = dblRealRates(intCount + 1, 1) - dblRealRates(intCount, 1)
    Next intCount

    VaRScenariosTest = Application.Transpose(dblTemp)
End Function

Function Range2dblArray(ByRef rngRange As Range) As Double()
    Dim dblTemp() As Double
    Dim intCount As Integer

    For intCount = 1 To rngRange.Count
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = rngRange.Cells(intCount)
    Next intCount

    Range2dblArray = dblTemp
End Function

并且还通过在 Excel 公式本身中对 VaRScenariosTest 的结果进行转置

{=TRANSPOSE(VaRScenariosTest(TRANSPOSE(Range2dblArray(E2:E21))))}

您可以允许 VaRScenariosTest 也 return 一维数组(但仍然需要将 dblRealRates 作为二维 Variant 传递给函数数组):

Function VaRScenariosTest(ByRef dblRealRates() As Variant) As Double()
    Dim intCount As Integer
    Dim dblTemp() As Double

    For intCount = LBound(dblRealRates) To (UBound(dblRealRates) - 1)
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = dblRealRates(intCount + 1, 1) - dblRealRates(intCount, 1)
    Next intCount

    VaRScenariosTest = dblTemp
End Function

Function Range2dblArray(ByRef rngRange As Range) As Double()
    Dim dblTemp() As Double
    Dim intCount As Integer

    For intCount = 1 To rngRange.Count
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = rngRange.Cells(intCount)
    Next intCount

    Range2dblArray = dblTemp
End Function

根据@YowE3K 的指导,最终确定了以下版本:

Function VaRScenariosTest(ByRef dblRealRates() As Variant) As Variant()
    Dim intCount As Integer
    Dim dblTemp() As Double

    For intCount = LBound(dblRealRates) To (UBound(dblRealRates) - 1)
        ReDim Preserve dblTemp(1 To intCount)
        dblTemp(intCount) = dblRealRates(intCount + 1) - dblRealRates(intCount)
    Next intCount

    VaRScenariosTest = Application.Transpose(dblTemp)
End Function

Function Range2Array(ByRef rngRange As Range) As Variant()
    Dim varTemp() As variant
    Dim intCount As Integer

    For intCount = 1 To rngRange.Count
        ReDim Preserve varTemp(1 To intCount)
        varTemp(intCount) = rngRange.Cells(intCount)
    Next intCount

    Range2Array = varTemp
End Function

在电子表格中使用时效果很好,只有函数 VarScenariosTest 和数组参数 dblRealRates() 的数据类型必须改回 double 如果我想在 VBA,不在电子表格中,尽管变体版本也可以在这里使用。 @YowE3K 感谢您的帮助!