2016-10-25 18 views
1

'H' Column is the year data column, 'I' Column is the month data column, 'D' Column is the 10-year bond yield we want to calculate the monthly volatility.これは、この問題の別の改善されたコードです。リターンはまだ#NAMEです。 @Cominternからの回答に感謝します。 @ Cominternのアドバイスによると、コードを改訂しました。ネーム・マネージャーでは、「Yr」は年の列(H3:H3696)、「M」は月の列(I3:I3696)、「C_10」は中国の10年の元のデータ財務省債券。Excel VBAで月間ボラティリティを計算する方法列時系列シリーズ

今、私は利回りの毎月のボラティリティを求めています。

Function Volatility(n As Variant) As Variant 
'this function uses to calculate volatility of a bond yield 
'"n" is the number of data/date we need to calculate 
'please manage the data name in the name manager of formulas 
Dim i As Integer, dnum As Integer, mnum As Integer, vectornum As Integer 
'dnum count day number, mnum count month number 
Dim Result(), TempSave() As Variant 
Dim Yr, M As Range 
vectornum = Int(n/20) + 1 
ReDim Result(vectornum) As Variant 

Yr = ActiveWorkbook.Names("Yr").Value 
M = ActiveWorkbook.Names("M").Value 
Bond = ActiveWorkbook.Names("C_10").Value 

For i = 1 To n 
    If Yr(i) = Yr(i + 1) And M(i) = M(i + 1) Then 
     dnum = dnum + 1 
     ReDim Preserve TempSave(1 To dnum) 
     TempSave(dnum) = Bond(i) 
     'this is the temporary data container for the same month bond yield 
    Else 
     TempSave(dnum + 1) = Bond(i) 
     'because there is a gap between two month, so, we add the last 'same month bond yield' back 
     dnum = 0 
     mnum = mnum + 1 
     Result(mnum) = Application.WorksheetFunction.StDev_S(TempSave) 
    End If 
Next i 

Volatility = Result 
End Function 
+0

あなたの質問は正確ですか?あなたは#Nameに解決する理由を尋ねていますか? –

+0

はい、コードの問題を知りたいのですが。私は、債券利回りデータの年を示すために「年」を使用し、債券利回りデータの月を参照するために「月」を使用しました。「C_10」は、債券利回りの元のデータです。 –

答えて

0

このコードには複数の問題があります。 #NAMEエラーについては、関数をモジュールに移動するだけでよいでしょう。私はまた、それが明示的に公表することをお勧めしたい:私もOption Base 0を削除したい

Public Function Volatility(n As Variant) As Variant 

- それはデフォルトのベースです。あなたが使用している唯一の配列は、Excel(そう、彼らはは常にベース1になるだろう)、あなたはここで明示的に1の下限と宣言しTempSave、によって生成されています:

ReDim Preserve TempSave(1 To dnum) 

私は名前を変更したいですYearMonthの変数。どちらもVBA関数の名前で、ローカル変数はそれらを隠しています。

このコード...

dnum = 0 
mnum = 0 

は...何もしません - 変数は常にデフォルトに初期化されます。

Dim i, j, dnum, mnum, vectornum As Integer 

それらは全てIntegerことになっている場合は、あなたがする必要があります:あなたは(おそらく誤って)ここにVariantとして宣言するので、この場合には、デフォルトでは、(暗黙的に0にキャストされます)Emptyですが、明示的に宣言:

Dim i As Integer, j As Integer, dnum As Integer, mnum As Integer, vectornum As Integer 

をあなたのループカウントからStep 1を削除することができます - (再び、Excelの配列はベース1です)ここでは0なく、それがデフォルトだが、それはまた1で開始する必要があります。

For i = 0 To n Step 1 

この行は... Range.Valueが複数のセルを参照する場合、あなたは次元2を取得しますので、

If Year(i) = Year(i + 1) And Month(i) = Month(i + 1) Then 

は...、「インデックスが有効範囲にありません」エラーが発生しますアレイ。つまり、の両方をとする必要があります。私はそれがあるべきように、これらは、同じ列内のすべてであると仮定しています:

If Year(I, 1) = Year(i + 1, 1) And Month(I, 1) = Month(i + 1, 1) Then 

あなたがここに逆の問題があります:あなたは1次元配列が、試みとしてTempSaveを宣言

ReDim Preserve TempSave(1 To dnum) 
    TempSave(i, 1) = Bond(i) 

をそれを2次元で索引付けする。最高の次元はReDim Preserveしかないことに注意してください。動的な境界線を持つ列を作成する必要がある場合は、ソース配列から長さを計算するか、または転置する必要があります。 Bondも2次元配列になります(が複数のセルであると仮定します)。

あなたの範囲のいずれか 1セルしている場合は、これらの割り当ては、あなたのタイプの不一致を与える:あなたはそれのように宣言したので、

Year = ActiveWorkbook.Names("Year").Value 
Month = ActiveWorkbook.Names("Month").Value 
Bond = ActiveWorkbook.Names("C_10").Value 

は最後に、Volatility = Resultはおそらく、何それが必要帰国されていません。

ReDim Result(vectornum, 1) As Variant 

あなたはUDFからVariantの配列を返すときに、あなただけの配列の最初の値を取得します - この場合Result(1, 1)に。

+0

あなたの提案によると、私はコードを改訂しました。ネーム・マネージャーでは、「Yr」は年の列(H3:H3696)、「M」は月の列(I3:I3696)、「C_10」は中国の10年の元のデータ財務省債券。今、私は利回りの毎月のボラティリティを求めています。 –