2017-09-15 49 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感謝您的幫助!