简体   繁体   English

Excel VBA UDF数组函数对所有cel返回相同的值

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

I'm trying to make my Excel VBA UDF function to return an array. 我正在尝试使我的Excel VBA UDF函数返回一个数组。 As of now the function either returns #VALUE! 到目前为止,该函数要么返回#VALUE! error if I define the argument as double array or all of the cells in the array have the same value if I define the argument as variant even though I checked in the Locals window in VBE and the return array variable actually contains different values. 如果我将参数定义为双精度数组,或者即使我在VBE中的“本地”窗口中检查了返回数组变量实际上包含不同的值的情况下,即使将参数定义为变量,则将数组中的所有单元格都具有相同的值,也会发生错误。

Here is my code: 这是我的代码:

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

I call the function in the spreadsheet in the following way: function call in excel with dblRealRates() as Double/Variant 我通过以下方式在电子表格中调用该函数: 在excel中使用dblRealRates()作为Double / Variant进行函数调用

Column E contains the input to function, column F the values that should be returned by the function and column G the function itself. E列包含函数的输入,F列包含函数应返回的值,G列包含函数本身。 If I define the dblRealRates() variable type as double, the formula returns the #VALUE! 如果将dblRealRates()变量类型定义为double,则该公式将返回#VALUE! error. 错误。 If I define it as variant, the returned values in the spreadsheet are the same. 如果我将其定义为变体,则电子表格中的返回值相同。 If I pause the execution of the code at End Function line and look in the Locals WIndow, you can actually see that the values in the array are different, not all equal to 0.000016287 as the output in the spreadsheet suggests: Function Array values in Locals Window 如果我在“结束功能”行中暂停执行代码,并查看“局部变量”窗口,则实际上可以看到数组中的值是不同的,并非全部等于0.000016287,这是电子表格中的输出所提示的: 局部变量中的函数数组值窗口

Can someone please advise why does the formula returns an error when the dblRealRates() variable is defined as double, and why does it return identical values if it's defined as variant? 有人可以告诉我为什么当dblRealRates()变量定义为double时,该公式为什么会返回错误;如果将其定义为variant,为什么它会返回相同的值?

A one-dimensional array is treated as being shaped as one row by x columns, so that is why your values are always coming out the same. 一维数组被视为由x列整形为一行,因此这就是为什么您的值总是相同的原因。 (The entire result column is assigned the value of the first column returned.) (为整个结果列分配了返回的第一列的值。)

The following code works for your situation (but will undoubtedly give issues if you change things to work on rows instead of columns): 以下代码适用于您的情况(但是,如果您将内容更改为在行而不是列上工作,无疑会出现问题):

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

Alternatively, by doing the transpose of the results of Range2dblArray in the Excel formula itself 或者,通过在Excel公式本身中对Range2dblArray的结果进行转置

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

you can leave the original Range2dblArray untouched and only modify VaRScenariosTest : 您可以保持原始的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

And by also doing the transpose of the results of VaRScenariosTest in the Excel formula itself 并通过在Excel公式本身中对VaRScenariosTest的结果进行转置

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

you can allow VaRScenariosTest to also return a one-dimensional array (but will still need to pass dblRealRates into the function as a two-dimensional Variant array): 您可以允许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

Finally settled on the following version, as per @YowE3K guidance: 最终根据@ 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

Works well when used in a spreadsheet, and only the data types of the function VarScenariosTest and array argument dblRealRates() have to be changed back to double if I want to use exclusively in VBA, not in the spreadsheet, although the variant version would work here as well. 在电子表格中使用时效果很好,并且如果我想仅在VBA中使用而不是在电子表格中使用,则只有变量VarScenariosTest和数组参数dblRealRates()的数据类型必须改回两倍,尽管变体版本也可以使用这里也是。 @YowE3K thank you for your help! @ YowE3K谢谢您的帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM