简体   繁体   English

调整Excel VBA函数以访问VBA

[英]Adapting an Excel VBA Function to Access VBA

I am revisiting some old code in Excel VBA and trying to convert it to Access VBA. 我正在重新查看Excel VBA中的一些旧代码,并尝试将其转换为Access VBA。

This code takes a range of numbers ("Zeros") and calculates a simple weighted average with a weight of "Lambda". 此代码采用一个数字范围(“零”),并计算权重为“ Lambda”的简单加权平均值。 This calculation and this code works fine and has been verified as correct. 此计算和此代码工作正常,并且已被验证为正确。

The Excel code is as follows. 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

Now I've tried to reproduce this same function in Access VBA. 现在,我尝试在Access VBA中重现此功能。 This code references a table ("HolderTable") which consists of the exact same numbers as the "Zeros" range in the above Excel code. 该代码引用一个表(“ HolderTable”),该表由与上述Excel代码中“ Zeros”范围完全相同的数字组成。 In Access, these are labelled "InterpRate". 在Access中,这些标记为“ InterpRate”。 Then it applies exactly the same calculation as in the Excel code, except adapted for Access syntax. 然后,它适用于与Excel代码完全相同的计算,只是适用于Access语法。

The Access code is as follows: 访问代码如下:

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

Ideally, these should produce the exact same numbers. 理想情况下,这些应该产生完全相同的数字。 The "Zeros" range and the "interpRate" numbers are identical. “零”范围和“ interpRate”数字相同。 I suspect the problem is with how I've defined my array in Access, however I can't seem to fix it. 我怀疑问题出在我如何在Access中定义数组,但是我似乎无法修复它。 Are there any inconsistencies between the two codes? 这两个代码之间是否有不一致之处?

For reference, I have attached the Excel spreadsheet w/ the VBA code. 作为参考,我随附了带有VBA代码的Excel电子表格。 http://www.filedropper.com/soewma_1 http://www.filedropper.com/soewma_1

The IMHO best readable way is to start with x=0 and put the x=x+1 at the beginning of each loop: 恕我直言,最好的可读性方法是从x = 0开始并将x = x + 1放在每个循环的开头:

Set rec = CurrentDb.OpenRecordset("SELECT InterpRate FROM HolderTable")
x = 0
Do While rec.EOF = False
    x = x + 1
    ReDim Preserve vInterpRate(x)
    vInterpRate(x) = rec("InterpRate")
    rec.MoveNext
Loop

And since you access vInterpRate(I - 1) , your second loop must be 并且由于您访问vInterpRate(I - 1) ,因此第二个循环必须是

For I = 2 To x

instead of For I = 1 To x . 而不是For I = 1 To x

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

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