Я пересматриваю старый код в Excel VBA и пытаюсь преобразовать его в Access VBA.Адаптация функции Excel VBA для доступа к VBA
Этот код принимает ряд чисел («нули») и вычисляет простое взвешенное среднее значение с весом «Лямбда». Этот расчет и этот код отлично работают и были проверены как правильные.
Код Excel выглядит следующим образом.
Option Explicit
Function EWMA(Zeros As Range, Lambda As Double, MarkDate As Date, MaturityDate As Date) As Double
Dim vZeros() As Variant
Dim Price1 As Double, Price2 As Double
Dim SumWtdRtn As Double
Dim I As Long
Dim m As Double
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
vZeros = Zeros
m = Month(MaturityDate) - Month(MarkDate)
For I = 2 To UBound(vZeros, 1)
Price1 = 1/((1 + vZeros(I - 1, 1))^(m/12))
Price2 = 1/((1 + vZeros(I, 1))^(m/12))
LogRtn = Log(Price1/Price2)
RtnSQ = LogRtn^2
WT = (1 - Lambda) * Lambda^(I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn^(1/2)
End Function
Теперь я попытался воспроизвести эту же функцию в Access VBA. Этот код ссылается на таблицу («HolderTable»), которая состоит из тех же чисел, что и диапазон «Zeros» в вышеуказанном коде Excel. В Access они обозначаются как «InterpRate». Затем он применяет точно такой же расчет, как и в коде Excel, за исключением адаптированного для синтаксиса Access.
Код доступа выглядит следующим образом:
Function EWMA(Lambda As Double) As Double
Dim Price1 As Double, Price2 As Double
Dim vInterpRate() As Variant
Dim SumWtdRtn As Double
Dim I As Long
Dim m As Double
Dim rec As Recordset
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
m = 3
Dim x As Integer
Set rec = CurrentDb.OpenRecordset("SELECT InterpRate FROM HolderTable")
x = 1
Do While rec.EOF = False
ReDim Preserve vInterpRate(x + 1)
vInterpRate(x) = rec("InterpRate")
x = x + 1
rec.MoveNext
Loop
For I = 1 To x
Price1 = 1/((1 + vInterpRate(I - 1))^(m/12))
Price2 = 1/((1 + vInterpRate(I))^(m/12))
LogRtn = Log(Price2/Price1)
RtnSQ = LogRtn^2
WT = (1 - Lambda) * Lambda^(I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn^(1/2)
End Function
В идеале, они должны производить ту же цифру. Диапазон «Zeros» и номера «interpRate» идентичны. Я подозреваю, что проблема связана с тем, как я определил свой массив в Access, однако я не могу его исправить. Существуют ли какие-либо несоответствия между этими двумя кодами?
Для справки, я прилагаю таблицу Excel с кодом VBA. http://www.filedropper.com/soewma_1
Это просто, что x увеличивается в 1 раз слишком много в вашей версии доступа? –
Я думаю, что это возможно, как я могу изменить его, чтобы исправить это? – beeba
Простейшим способом было бы добавить «x = x - 1» после вашего Do ... While loop –