我试图在For循环中的Access VBA中执行IF-THEN-ELSE条件。但是我似乎无法执行它,我做错了什么?代码如下。
If m < 12 Then
For I = 2 To x
Price1 = 1 / ((1 + vInterpRate(I - 1)) ^ (m / 12))
Price2 = 1 / ((1 + vInterpRate(I)) ^ (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Else
For I = 2 To x
Price1 = Exp((vInterpRate(I - 1)) * (m / 12))
Price2 = Exp((vInterpRate(I)) * (m / 12))
End If
执行此操作会给我一个&#34; Else Without If&#34;错误,这让我感到困惑,因为有一个If - Then语句。
对于上下文,这是整个函数。
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 = 0
Do While rec.EOF = False
x = x + 1
ReDim Preserve vInterpRate(x)
vInterpRate(x) = rec("InterpRate")
rec.MoveNext
Loop
If m < 12 Then
For I = 2 To x
Price1 = 1 / ((1 + vInterpRate(I - 1)) ^ (m / 12))
Price2 = 1 / ((1 + vInterpRate(I)) ^ (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Else
For I = 2 To x
Price1 = Exp((vInterpRate(I - 1)) * (m / 12))
Price2 = Exp((vInterpRate(I)) * (m / 12))
End If
Next I
EWMA = SumWtdRtn ^ (1 / 2)
End Function
答案 0 :(得分:5)
你离这儿很近,你只有循环部分或者#34;接下来我&#34;部分在错误的地方。尝试:
If m < 12 Then
For I = 2 To x
Price1 = 1 / ((1 + vInterpRate(I - 1)) ^ (m / 12))
Price2 = 1 / ((1 + vInterpRate(I)) ^ (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
Else
For I = 2 To x
Price1 = Exp((vInterpRate(I - 1)) * (m / 12))
Price2 = Exp((vInterpRate(I)) * (m / 12))
Next I
End If
答案 1 :(得分:0)
重新考虑使用记录集,数组或循环,并直接从MSAccess.exe(不是通过ODBC / OLEDB)允许的SQL查询中调用VBA函数。您需要的挑战是需要查看一行可以使用子查询处理行计数。下面假设一个自动编号ID字段。虽然查询使用派生表(SELECT
子句中的嵌套FROM
),但这样的派生表可以保存为自己的SQL存储查询。
SQL 查询(注意VBA函数在线调用标量Lambda值为0.015)
SELECT Sum(final.WtdRtn) ^ (1/2) As EWMA
FROM
(SELECT dT.CurrInterpRate, dT.LastInterpRate, dT.RowCount,
EWMA(0.015, dT.CurrInterpRate, dT.LastInterpRate, dT.RowCount) As WtdRtn
FROM
(SELECT HolderTable.ID, HolderTable.InterpRate As CurrInterpRate,
(SELECT TOP 1 HolderTable.InterpRate FROM HolderTable sub
WHERE sub.ID < HolderTable.ID
ORDER BY sub.ID DESC) As LastInterpRate,
(SELECT Count(*) FROM HolderTable sub
WHERE sub.ID < HolderTable.ID) As RowCount
FROM HolderTable
) As dT
) As final
VBA 函数(要保存在标准模块中而不是任何特定对象(表单/报表);注意在SQL中运行聚合时返回值的更改
Public Function EWMA(Lambda As Double, currRowIR As Double, _
lastRowIR As Double, rowCount As Long) As Double
Dim Price1 As Double, Price2 As Double
Dim SumWtdRtn As Double
Dim m As Double: m = 3
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
If m < 12 Then
Price1 = 1 / ((1 + lastRowIR) ^ (m / 12))
Price2 = 1 / ((1 + currRowIR) ^ (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (rowCount)
WtdRtn = WT * RtnSQ
Else
Price1 = Exp(lastRowIR * (m / 12))
Price2 = Exp(currRowIR * (m / 12))
End If
EWMA = WtdRtn
End Function
即使如此,您也可以在没有VBA的情况下在SQL中运行它。这里, Lambda 和 m 作为标量传递。当然没有数据,我无法完全测试:
SELECT Sum(final.WtdRtn) ^ (1/2) As EWMA
FROM
(SELECT 1 / ((1 + dT.lastRowIR) ^ (dT.m / 12)) As Price1,
1 / ((1 + dT.currRowIR) ^ (dT.m / 12)) As Price2,
Log(Price1 / Price2) As LogRtn, LogRtn ^ 2 As RtnSQ,
(1 - dT.Lambda) * dT.Lambda ^ (dT.rowCount) As WT,
WT * RtnSQ As WtdRtn
FROM
(SELECT HolderTable.ID, HolderTable.InterpRate As currRowIR,
(SELECT TOP 1 HolderTable.InterpRate FROM HolderTable sub
WHERE sub.ID < HolderTable.ID
ORDER BY sub.ID DESC) As lastRowIR,
(SELECT Count(*) FROM HolderTable sub
WHERE sub.ID < HolderTable.ID) As rowCount
3 As m,
0.015 As Lambda
FROM HolderTable
) As dT
) As final
答案 2 :(得分:0)
我同意其他评论。在所有情况下m=3
,所以为什么要烦恼if / else / end if。但是,如果你选择使用if / end,如果你选择使用它,那么这里应该得到if / end。
您使用for I=2 to x
的多个案例。据我所知,你只能使用它一次?
For I = 2 To x
If m < 12 Then
Price1 = 1 / ((1 + vInterpRate(I - 1)) ^ (m / 12))
Price2 = 1 / ((1 + vInterpRate(I)) ^ (m / 12))
LogRtn = Log(Price1 / Price2)
RtnSQ = LogRtn ^ 2
WT = (1 - Lambda) * Lambda ^ (I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Else
Price1 = Exp((vInterpRate(I - 1)) * (m / 12))
Price2 = Exp((vInterpRate(I)) * (m / 12))
End If
Next I