【问题标题】:Loop through Table With Access VBA使用 Access VBA 循环遍历表
【发布时间】:2016-12-13 14:50:11
【问题描述】:

目前在 Access VBA 中,我在 Access 中有一个表“VolatilityOutput”的过滤器,如下所示:

Dim CurveID As Long
CurveID = 15
Dim strSQL As String
strSQL = "SELECT * FROM VolatilityOutput WHERE CurveID=" & CurveID & " AND MaxOfMarkAsofDate=#" & MaxOfMarkAsofDate & "# ORDER BY MaxOfMarkasOfDate, MaturityDate"

CurveID 是 VolatilityOutput 表中的一个字段。现在 CurveID = 15 是硬编码的。每个曲线 ID 对应于另一个字段 CurveShortName 中的一个标题。数据存储在这个表中,“tblCurve”:

设置 CurveID 后,代码会对该特定数据执行一些计算。

现在我不想一次选择一个 CurveID(例如 CurveID=15),而是想更改此代码,以便它对存储在表中的每个 CurveID 执行计算。因此它将为表中的每个 CurveID 计算 CurveID = 13、CurveID = 14、CurveID = 15 等。如何更改上述代码,使其循环遍历表格,而不是一次输入一条曲线?

编辑更新:此处发布完整代码

Public Sub CalculateVol()


Dim vol As Double
Dim rs As Recordset
Dim rs2 As Recordset
Dim iRow As Long, iField As Long
Dim strSQL As String
Dim CurveID As Long
Dim MarkRunID As Long
Dim MaxOfMarkAsofDate As Date
Dim userdate As String

DoCmd.RunSQL "DELETE * FROM HolderTable"
'Clears out the old array from the holder table.

CurveID = 15

Dim I As Integer
Dim x As Date

userdate = InputBox("Please Enter the Date (mm/dd/yyyy)")

x = userdate

Dim BucketTermAmt As Long
BucketTermAmt = InputBox("Please Enter the Term Amount")

For I = 0 To 150

MaxOfMarkAsofDate = x - I


strSQL = "SELECT * FROM VolatilityOutput WHERE CurveID=" & CurveID & " AND MaxOfMarkAsofDate=#" & MaxOfMarkAsofDate & "# ORDER BY MaxOfMarkasOfDate, MaturityDate"

Set rs = CurrentDb.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)
Set rs2 = CurrentDb.OpenRecordset("HolderTable")



If rs.RecordCount <> 0 Then

    rs.MoveFirst

    rs.MoveLast


    Dim BucketTermUnit As String
    Dim BucketDate As Date
    Dim MarkAsOfDate As Date
    Dim InterpRate As Double


    Dim b As String

    b = BucketTermAmt

    BucketTermUnit = "m"
    BucketDate = DateAdd(BucketTermUnit, b, MaxOfMarkAsofDate)
    InterpRate = CurveInterpolateRecordset(rs, BucketDate)

    rs2.AddNew
    rs2("BucketDate") = BucketDate
    rs2("InterpRate") = InterpRate
    rs2.Update


End If

Next I


vol = EWMA(0.94)

Debug.Print vol


End Sub

【问题讨论】:

    标签: sql ms-access vba


    【解决方案1】:

    您可以使用whileDo 循环遍历记录集。比如:

    If rs.RecordCount <> 0 Then
        'set the cursor to the first row
        rs.MoveFirst
    
        Dim BucketTermUnit As String
        Dim BucketDate As Date
        Dim MarkAsOfDate As Date
        Dim InterpRate As Double
    
    
        Dim b As String
    
        'loop the rows
        Do Until rs.EOF 'endoffile
    
    
    
            b = BucketTermAmt
    
            BucketTermUnit = "m"
            BucketDate = DateAdd(BucketTermUnit, b, MaxOfMarkAsofDate)
            InterpRate = CurveInterpolateRecordset(rs, BucketDate)
    
            rs2.AddNew
            rs2("BucketDate") = BucketDate
            rs2("InterpRate") = InterpRate
            rs2.Update
    
            'to the next row for the next loop
            rs.movenext
        Loop
    
    
    End If
    

    现在您只需将所有记录加载到 rs 中,而不仅仅是一条记录,然后让循环完成工作。

    因为您的CurveInterpolateRecordset 函数需要一个记录集,并使用它来做一些事情(我不会开始猜测),所以添加一个不同curveID 的新记录集然后循环几乎整个原始记录集可能是一个更好的主意该记录集中的例程。类似的东西:

    Public Sub CalculateVol()
    
    
    Dim vol As Double
    Dim rs As Recordset
    Dim rs2 As Recordset
    Dim rsCurve as Recordset
    Dim iRow As Long, iField As Long
    Dim strSQL As String
    Dim CurveID As Long
    Dim MarkRunID As Long
    Dim MaxOfMarkAsofDate As Date
    Dim userdate As String
    
    DoCmd.RunSQL "DELETE * FROM HolderTable"
    'Clears out the old array from the holder table.
    
    CurveID = 15
    
    Dim I As Integer
    Dim x As Date
    
    userdate = InputBox("Please Enter the Date (mm/dd/yyyy)")
    
    x = userdate
    
    Dim BucketTermAmt As Long
    BucketTermAmt = InputBox("Please Enter the Term Amount")
    
    'get distinct curveIDs for the loop
    strSQL = "SELECT CurveID FROM VolatilityOutput GROUP BY CurveID;"
    
    'open up distinct curveID recordset
    Set rsCurve = CurrentDB.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)
    
    'loop through each distinct curveID
    Do Until rsCurve.EOF
    
        'Loop for your dates
        For I = 0 To 150
            MaxOfMarkAsofDate = x - I
    
            'Changed this to the new curveID from the rsCurve recordset.
            strSQL = "SELECT * FROM VolatilityOutput WHERE CurveID=" & rsCurve.Fields("CurveID") & " AND MaxOfMarkAsofDate=#" & MaxOfMarkAsofDate & "# ORDER BY MaxOfMarkasOfDate, MaturityDate"
    
            Set rs = CurrentDb.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)
            Set rs2 = CurrentDb.OpenRecordset("HolderTable")
    
    
            If rs.RecordCount <> 0 Then
    
                rs.MoveFirst
    
                rs.MoveLast
    
    
                Dim BucketTermUnit As String
                Dim BucketDate As Date
                Dim MarkAsOfDate As Date
                Dim InterpRate As Double
    
    
                Dim b As String
    
                b = BucketTermAmt
    
                BucketTermUnit = "m"
                BucketDate = DateAdd(BucketTermUnit, b, MaxOfMarkAsofDate)
                InterpRate = CurveInterpolateRecordset(rs, BucketDate)
    
                rs2.AddNew
                rs2("BucketDate") = BucketDate
                rs2("InterpRate") = InterpRate
                rs2.Update
    
    
            End If
        Next I
    
        'move to next curveID
        rsCurve.MoveNext
    Loop
    
    vol = EWMA(0.94)
    
    Debug.Print vol
    
    
    End Sub
    

    【讨论】:

    • 我需要更改 strSQL 语句对吗?因为我有 rs = CurrentDb.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)。还是我应该保持原样并制作一个新的 rs 来遍历我的所有记录?
    • 是的!您应该将 strSQL 更改为打开所有记录的任何内容,而不仅仅是 15
    • 所以我认为这意味着只删除 WHERE 语句,以便它打开包含所有记录的表,如 strSQL = "SELECT * FROM VolatilityOutput。但是,如果我遍历整个记录集,计算不起作用-它需要一次查看一个CurveID,而不是全部。所以我基本上需要用CurveID = 15进行计算,然后循环,CurveID = 16,循环等所有CurveID . 我需要做一些不同的事情来做到这一点,还是我误解了你的意思?感谢你的耐心
    • 这很好。我不确定你的 CurveInterpolateRecordset 在做什么,我想你必须调整它,或者重写它来处理这个问题。还有另一种选择,可能会更慢,但我会将其添加到答案中,以便您的代码更改最少。
    • 好的。我已使用新记录集 rsCurve 更新了答案,以从您的波动率表中保留不同的 curveID。然后它遍历该记录集,遍历您的日期,然后为该rsCurve 记录的CurveID 获取rs。这一切都感觉非常低效,因为我们在循环中做基于集合的东西,整个事情可以被废弃以进行编写良好的查询,但不知道这个子程序的下游是什么,我不能肯定地说。如果数据很小并且运行速度很快,那么它可能是一个清洗。
    猜你喜欢
    • 2013-11-30
    • 1970-01-01
    • 2017-04-26
    • 2017-10-19
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 2014-04-13
    • 2016-07-16
    相关资源
    最近更新 更多