2016-06-13 9 views
0

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

+1

アクセスバージョンでxが1回増分されるのは単なるですか? –

+0

私はそれが可能かもしれないと思います、どうすればそれを修正することができますか? – beeba

+1

最も簡単な方法は、Do ... Whileループの後に "x = x - 1"を追加することです。 –

答えて

1

私見最善読める方法は、x = 0で始まり、各ループの先頭で、X = X + 1を置くことですbe

For I = 2 To x 

For I = 1 To xの代わりになります。

+0

ああ完璧にそれを完全に固定してくれてありがとう。 – beeba

+0

あなたは私のために1つのポイントを明確にできますか? vInterpRate(0)は配列の最初の要素を返し、vInterpRate(1)は2番目の要素を返します。私がI = 2に設定した場合、1つの要素をスキップしないのですか? – beeba

+0

"debug.Print vInterpRate(0)"は "0.38"を返します。これは配列の最初の要素です。 – beeba

関連する問題