【问题标题】:Access-VBA For Loop Executes Only OnceAccess-VBA For 循环只执行一次
【发布时间】:2019-06-20 12:56:14
【问题描述】:

我正在尝试测量两次更新之间的持续时间。已经有一个表可以跟踪“lastvalue”、“newvalue”和“updatetime”。我的方法是搜索满足条件的实体并将相关的更新时间分配给变量然后计算。 但是,我的 for 循环不起作用,它们只执行一次。我是 access-vba 的新手,并使用 debug.prints 来查看事情的变化(它们是永久性的)。下面是我的代码,谢谢

Private Sub olcum()

Dim gs As Long
Dim db As Database
Dim rs As Recordset
Dim pt As Date
Dim ct As Date
Dim pc As String
Dim cc As String
Dim id As Integer
Dim i As Integer
Dim l As Integer
Dim k As Integer
'Dim a As Index
Dim strMessage As String


Set db = CurrentDb
Set rs = db.OpenRecordset("GecenSure", dbOpenSnapshot)
pc = "acilmasi bekleniyor"
cc = "onayda"


rs.MoveFirst
For i = 0 To (rs.RecordCount - 1)
    strMessage = "Burada: " & (rs.AbsolutePosition + 1)
    Debug.Print (strMessage)
    'Set a = rs.AbsolutePosition
    'Debug.Print (a)
    id = rs.Fields("Kimlik")
    rs.MoveFirst

    For l = 0 To (rs.RecordCount - 1)
        strMessage = "Burada: " & (rs.AbsolutePosition + 1)
        Debug.Print (strMessage)
        If (rs.Fields("Kimlik") = id) And (rs.Fields("PreviousCase") = pc) Then
        pt = rs.Fields("UpdateTime")
        Else
        End If

        For k = 0 To (rs.RecordCount - (1 + l))
            strMessage = "Burada: " & (rs.AbsolutePosition + 1)
            Debug.Print (strMessage)
        'If (rs.Fields("Kimlik") = id) And (rs.Fields("CurrentCase") = cc) Then
            'Debug.Print "rs.AbsolutePosition"
            If (rs.Fields("Kimlik") = id) And (rs.Fields("PreviousCase") = cc) Then
            ct = rs.Fields("UpdateTime")
            Else
            End If
        'Else
        'End If
        rs.MoveNext
        strMessage = "Burada: " & (rs.AbsolutePosition + 1)
        Debug.Print (strMessage)
        Next k
        'bu prosedurle 2 kere ct atıyor.

    rs.MoveFirst

    For z = 0 To i
    rs.MoveNext
    strMessage = "Burada: " & (rs.AbsolutePosition + 1)
    Debug.Print (strMessage)
    Next z

    Next l

    gs = ct - pt
    Debug.Print gs

    'Debug.Print rs.Fields("CurrentCase")
rs.MoveNext
strMessage = "Burada: " & (rs.AbsolutePosition + 1)
Debug.Print (strMessage)
Next i

rs.Close
Set rs = Nothing
db.Close

MsgBox "Simdiki durumlar gosterildi"

End Sub

【问题讨论】:

  • 我虽然可能是由于“dbOpenSnapshot”,但据我所知使用“rs.AbsolutePosition”,需要以快照或动态集打开

标签: sql for-loop ms-access vba


【解决方案1】:

rs.RecordCount 不返回记录集中的记录总数;而是返回已经访问过的记录数。

有多种选择;选项 3 通常被认为是最好的,并且是许多 Microsoft 示例中使用的方法:

  1. rs.MoveLast - 在循环之前;这不是一个高性能的选项
  2. 查询 SQL Count - 在循环之前,确定记录数
  3. 使用 WhileDo 循环检查 rs.EOF (见https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb243789(v=office.12)

Do 循环的一个例子:

Set rs = db.OpenRecordSet("GecenSure", dbOpenSnapshot)

Do Until rs.EOF
    ' do something
    rs.MoveNext
Loop

rs.Close
Set rs = Nothing

【讨论】:

  • Nitpick:我不想像 #3 中建议的那样做Do While Not rs.EOF。使用Do Until rs.EOF 的代码示例读起来更好,IMO。
【解决方案2】:

我建议使用这样的结构:

If Not (rs.BOF And rs.EOF) Then ' if not completely empty
    rs.MoveFirst                ' start at the beginning
    Do While Not rs.EOF         ' while not at end

        do something
        increment i if necessary

        ' error checking if needed:
        If i > ... Or SomethingUnwanted Then Exit Do

        rs.MoveNext
    Loop
End If
rs.Close

【讨论】:

  • 请注意,rs.MoveFirst 在技术上不是必需的,尤其是在您刚刚打开它的情况下。如果您对同一个记录集进行多次传递,这是有道理的,但在 95% 以上的情况下,我们只对记录集进行一次传递。消除 rs.MoveFirst 也消除了检查 BOF/EOF 的需要,切割 3 行并节省一定程度的缩进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多