2017-09-15 67 views
0

我想让Excel VBA UDF函数返回一个数组。截至目前,该函数要么返回#VALUE!如果我将参数定义为双数组,或者如果将参数定义为变体,则数组中的所有单元格都具有相同的值,即使我在VBE中的“本地”窗口中进行了检查,并且返回的数组变量实际上包含不同的值,也会出现错误。Excel VBA UDF数组函数为所有cels返回相同的值

这里是我的代码:

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!错误。如果我将其定义为变体,则电子表格中的返回值是相同的。 如果我暂停码在结束函数行的执行,并期待在本地窗口,你可以看到,该数组中的值是不同的,不是所有的等于0.000016287在电子表格中的输出表明:Function Array values in Locals Window

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

+0

是否有你需要使用'Range2dblArray'作为UDF的原因?如果它不需要在Excel单元格中可用,事情会变得更容易,而且我不确定它将作为独立的Excel函数使用。如果它不需要是UDF,那么你可以传递'Range'到'VaRScenariosTest',然后可以调用'Range2dblArray'作为它的第一件事。 – YowE3K

+0

'VaRScenariosTest'函数是一个更大计算的中间步骤,因此它将以vba变量作为参数而不是'Range'对象。然而,为了测试的目的,我希望能够看看所有的中间步骤,因此我实现了'Range2dblArray'函数以便能够将'Range'对象传递到中间函数中,我希望检查中间结果 – VBAEnthusiast

+0

这似乎是很多努力,以避免使用本地窗口查看中间结果。 – YowE3K

回答

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 

而且通过还做的VaRScenariosTest Excel公式本身

{=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 
+0

我看到你将'VaRScenariosTest'的变量类型从'Double()'改为'Variant()',这是否意味着'Double()'变量在这种情况下不起作用,甚至如果我应用转位?我可以在函数的开头引入验证检查来检查维度,以避免从行切换到列时出现问题,反之亦然。另外,你知道为什么函数返回一个#VALUE!即使'Range2dblArray'函数正好返回此类型(双'数组),dblRealRates()变量被定义为double时出错? – VBAEnthusiast

+0

@VBAEnthusiast将数组返回给Excel后,Excel将其转换为“Variant”,然后将该“Variant”数组传递给您的函数。因为它不能处理转换回'Double'并且崩溃,所以UDF返回一个'#VALUE!'错误(这只是UDF的说法“我崩溃了,我不告诉你为什么!”) – YowE3K

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 

作品在电子表格中使用的井时,只有功能VarScenariosTest和数组参数dblRealRates()的数据类型已经改变回如果我只想在VBA中使用,而不是在电子表格中,那么双倍,尽管变体版本也适用于此。 @ YowE3K感谢您的帮助!