Excel VBA UDF Array函数为所有cels返回相同的值

时间:2017-09-15 23:21:33

标签: arrays excel-vba user-defined-functions vba excel

我试图让我的Excel VBA UDF函数返回一个数组。截至目前,该函数返回#VALUE!如果我将参数定义为双数组或者如果我将参数定义为变量,则将参数定义为变量,即使我在VBE中检查了Locals窗口并且返回数组变量实际上包含不同的值。

这是我的代码:

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包含函数应返回的值,列G包含函数本身。如果我将dblRealRates()变量类型定义为double,则公式返回#VALUE!错误。如果我将其定义为变体,则电子表格中返回的值是相同的。 如果我暂停在End Function行执行代码并查看Locals WIndow,您实际上可以看到数组中的值不同,并不是全部等于0.000016287,因为电子表格中的输出表明:Function Array values in Locals Window

当dblRealRates()变量定义为double时,有人可以告诉为什么公式会返回错误,如果它被定义为变量,为什么它会返回相同的值?

2 个答案:

答案 0 :(得分:1)

将一维数组视为由 x 列整形为一行,这就是为什么您的值总是相同的原因。 (为整个结果列分配返回的第一列的值。)

以下代码适用于您的情况(但如果您更改要在行而不是列上工作,则无疑会产生问题):

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也返回一维数组(但仍需要将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

答案 1 :(得分:0)

根据@ 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

在电子表格中使用时效果很好,如果我想在VBA中专门使用,则只有函数VarScenariosTest和数组参数dblRealRates()的数据类型必须更改为double,而不是电子表格,虽然变体版本也适用于此。 @ YowE3K谢谢你的帮助!