2016-09-05 3 views
0

Я занимаюсь физическим упражнением для своего финансового класса, где я написал программу в Excel VBA, которая работает по назначению без использования MMULT или TRANSPOSE. Я хотел реализовать результаты в Листе Excel, адаптировав эту процедуру как UDF, но каким-то образом я получаю ошибку значения.Программа Excel VBA для UDF

Я вроде как что-то пропускаю ... какие-то намеки?

Здесь рутина:

Option Explicit 
Public Sub CalcVola2() 

Dim WeightedVola As Variant, Weights As Variant, Volatilities As Variant, Correlations As Variant 
Dim i As Double, j As Double, CorrSum As Double, VarSum As Double 
Dim CalcVola2 As Double 


'=================================================================================================== 
' Load data 
'=================================================================================================== 

Weights = ThisWorkbook.Worksheets("Stetig").Range("FR4:FR43") 
Volatilities = ThisWorkbook.Worksheets("Stetig").Range("FS4:FS43") 

Correlations = ThisWorkbook.Worksheets("Covar-Correl").Range("C13:AP52") 

'=================================================================================================== 
' Resize weighted volatility array to fit the inputs and clean the data 
'=================================================================================================== 

ReDim WeightedVola(1 To UBound(Weights, 1), 1 To 1) 

For i = 1 To UBound(Weights, 1) 
    If Weights(i, 1) = "" Then 
     Weights(i, 1) = 0 
    End If 
Next i 

For i = 1 To UBound(Volatilities, 1) 
    If Volatilities(i, 1) = "" Then 
     Volatilities(i, 1) = 0 
    End If 
Next i 

'=================================================================================================== 
' Perform weighted vola calculations 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    WeightedVola(i, 1) = Weights(i, 1) * Volatilities(i, 1) 
Next i 


'=================================================================================================== 
' Calculate the first sum of the portfolio volatility function by adding the squared weighted volas 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    CorrSum = CorrSum + WeightedVola(i, 1)^2 
Next i 


'=================================================================================================== 
' Calculate the second sum of the portfolio volatility function by the product of the weighted vola 
' and the correlation 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    For j = i + 1 To UBound(Weights, 1) 
     CorrSum = CorrSum + WeightedVola(i, 1) * 2 * WeightedVola(j, 1) * Correlations(i, j) 
    Next j 
Next i 

CalcVola2 = Sqr(CorrSum) 

ThisWorkbook.Worksheets("Stetig").Range("FS46").Value = CorrSum 
ThisWorkbook.Worksheets("Stetig").Range("FS47").Value = CalcVola2 


End Sub 

А вот ОДС:

Option Explicit 
Public Function CalcVola(Weights As Variant, Volatilities As Variant, Correlations As Variant) As Double 

Dim WeightedVola As Variant 
Dim i As Double, j As Double, CorrSum As Double, VarSum As Double 


'=================================================================================================== 
' Resize weighted volatility array to fit the inputs and clean the data 
'=================================================================================================== 

ReDim WeightedVola(1 To UBound(Weights, 1), 1 To 1) 

For i = 1 To UBound(Weights, 1) 
    If Weights(i, 1) = "" Then 
     Weights(i, 1) = 0 
    End If 
Next i 

For i = 1 To UBound(Volatilities, 1) 
    If Volatilities(i, 1) = "" Then 
     Volatilities(i, 1) = 0 
    End If 
Next i 


'=================================================================================================== 
' Perform weighted vola calculations 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    WeightedVola(i, 1) = Weights(i, 1) * Volatilities(i, 1) 
Next i 


'=================================================================================================== 
' Calculate the first sum of the portfolio volatility function by adding the squared weighted volas 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    CorrSum = CorrSum + WeightedVola(i, 1)^2 
Next i 


'=================================================================================================== 
' Calculate the second sum of the portfolio volatility function by the product of the weighted vola 
' and the correlation 
'=================================================================================================== 

For i = 1 To UBound(Weights, 1) 
    For j = i + 1 To UBound(Weights, 1) 
     CorrSum = CorrSum + WeightedVola(i, 1) * 2 * WeightedVola(j, 1) * Correlations(i, j) 
    Next j 
Next i 

CalcVola = Sqr(CorrSum) 


End Function 
+0

Какова будет формула примера с UDF, которая даст вам ошибку # VALUE? – Comintern

+2

Вам нужно установить контрольные точки и посмотреть, куда возвращается ошибка '#VALUE!'. Часто это происходит потому, что переменная неправильно напечатана, или функция VBA получает неправильные аргументы. Например, если вы передаете свой аргумент 'Weights' вашей функции в виде одномерного массива, ваша процедура выйдет из строя и вернет ошибку' #VALUE! 'На этой первой строке« Redim », так как она ищет 2D-массив , –

+0

@Comintern Ну, на самом деле формула - это волатильность портфеля с использованием корреляций: http://d3plit93wdq7ew.cloudfront.net/assets/covar-300x105.png –

ответ

1

Вы должны установить точки останова и увидеть, где получает возвращается ошибка #VALUE!. Часто это происходит потому, что переменная неправильно напечатана, или функция VBA получает неправильные аргументы. Например, если вы передадите свой аргумент Weights своей функции в виде одномерного массива, ваша процедура выйдет из строя и вернет ошибку #VALUE! на этой первой строке Redim, так как она ищет 2D-массив.

Если ваши аргументы передаются как диапазоны, аналогичная проблема возникнет.

Если это всегда будет случай, передавать аргументы в виде диапазонов, а затем, в вашем коде, что-то вроде:

Public Function CalcVola(rWeights As Range, rVolatilities As Range, rCorrelations As Range) As Double 

Dim Weights, Volatilities, Correlations 

Weights = rWeights 
Volatilities = rVolatilities 
Correlations = rCorrelations 

... 

End Function 

Если аргументы могут быть переданы либо как диапазоны или массивы, то вы будете должны иметь аргументы функции как тип Variant и проверить, чтобы они были, и сделать соответствующее преобразование, перед выполнением остальной части вашего UDF.

Смежные вопросы