Excel VBAで古いコードを再訪し、Access VBAに変換しようとしています。Excel VBA関数を使用してVBAにアクセスする
このコードでは、数値の範囲(「ゼロ」)をとり、重み「Lambda」を持つ単純な加重平均を計算します。この計算とこのコードは正常に動作し、正しいと確認されています。
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で再現しようとしました。このコードは、上記のExcelコードの "ゼロ"範囲と全く同じ数字で構成されるテーブル( "HolderTable")を参照します。 Accessでは、これらには "InterpRate"というラベルが付けられています。次に、Access構文に適合している点を除いて、Excelコードとまったく同じ計算を適用します。次のように
アクセスコードがある:
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
理想的には、これらは正確に同じ番号を生成すべきです。 「ゼロ」の範囲と「interpRate」の数は同じです。私は、Accessで配列をどのように定義したかに問題があると思われますが、修正できないようです。 2つのコードの間に矛盾がありますか?
参考として、VBAコード付きのExcelスプレッドシートを添付しました。
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
そして、あなたはvInterpRate(I - 1)
にアクセスするので、あなたの第2ループする必要があります。 http://www.filedropper.com/soewma_1
アクセスバージョンでxが1回増分されるのは単なるですか? –
私はそれが可能かもしれないと思います、どうすればそれを修正することができますか? – beeba
最も簡単な方法は、Do ... Whileループの後に "x = x - 1"を追加することです。 –