循环访问 MS Access 中的连续记录

Posted

技术标签:

【中文标题】循环访问 MS Access 中的连续记录【英文标题】:Looping through continous record in MSAccess 【发布时间】:2015-06-23 14:33:25 【问题描述】:

背景: 我在我的数据库中创建了一个假期跟踪模块。员工可以要求在本年度提前起飞,并将从下一年的时间中扣除。

案例: 我正在尝试通过员工的记录集进行连续循环,以查看他们是否已获得提前工作时间,如果是,则将其添加到他们拥有的假期时间中。

问题: 我有逻辑,但我无法让它循环遍历我的连续表单上的每个员工。

With Me.RecordsetClone
    While Not .EOF
        adv = DLookup("advhours", "dbo_employees", "[empid] = txtempid")
        vac = DLookup("vhrs", "dbo_employees", "[empid] = txtempid")
        adate = DLookup("advdate", "dbo_employees", "[empid] = txtempid")
        andatestart = DLookup("anndate", "dbo_employees", "[empid] = txtempid")
        andateend = DateAdd("yyyy", AgeSimple([andatestart]), [andatestart])
        anddateend = DateAdd("yyyy", 1, andateend)
        morehours = DLookup("totalvachrs", "dbo_employees", "[empid] = txtempid")

        sum = adv + vac


        If adv > 0 And adate > DateAdd("yyyy", AgeSimple([andatestart]), [andatestart]) And adate < anddateend And morehours = 0 Then
            morehours = 1

            ' sets the flag to 1 if true.
            DoCmd.RunSQL "UPDATE dbo_employees " & "SET dbo_employees.totalvachrs='" & morehours & "' " & "WHERE dbo_employees.empid=" & txtempid & ";"

            'increment vacation hours
            DoCmd.RunSQL "UPDATE dbo_employees " & "SET dbo_employees.vhrs='" & sum & "' " & "WHERE dbo_employees.empid=" & txtempid & ";"

        End If

        'after Vac hours have been updated..

        If morehours = 1 And adate < andateend Then
            ' puts vacation hours back down to where they were.
            vac = vac - adv
            DoCmd.RunSQL "UPDATE dbo_employees " & _
                                "SET dbo_employees.vhrs='" & _
                                vac & "' " & _
                                "WHERE dbo_employees.empid=" & txtempid & ";"
            adv = 0
            DoCmd.RunSQL "UPDATE dbo_employees " & _
                                "SET dbo_employees.advhours='" & _
                                adv & "' " & _
                                "WHERE dbo_employees.empid=" & txtempid & ";"
             morehours = 0
            DoCmd.RunSQL "UPDATE dbo_employees " & _
                                "SET dbo_employees.totalvachrs='" & _
                                morehours & "' " & _
                                "WHERE dbo_employees.empid=" & txtempid & ";"

       End If
      Debug.Print txtempid ' CTRL G to see

      If Not .EOF Then .MoveNext
    Wend
End With
MsgBox "after loop: " & txtempid

我也试过这个,但是我在访问中得到了丢弃更改对话框

Set rs = Me.RecordsetClone

rs.MoveFirst


Do While Not rs.EOF
    Me.Bookmark = rs.Bookmark
    adv = DLookup("advhours", "dbo_employees", "[empid] = txtempid")
    vac = DLookup("vhrs", "dbo_employees", "[empid] = txtempid")
    adate = DLookup("advdate", "dbo_employees", "[empid] = txtempid")
    andatestart = DLookup("anndate", "dbo_employees", "[empid] = txtempid")
    andateend = DateAdd("yyyy", AgeSimple([andatestart]), [andatestart])
    anddateend = DateAdd("yyyy", 1, andateend)
    morehours = DLookup("totalvachrs", "dbo_employees", "[empid] = txtempid")

    sum = adv + vac


    If adv > 0 And adate > DateAdd("yyyy", AgeSimple([andatestart]), [andatestart]) And adate < anddateend And morehours = 0 Then
        morehours = 1

        DoCmd.RunSQL "UPDATE dbo_employees " & "SET dbo_employees.totalvachrs='" & morehours & "' " & "WHERE dbo_employees.empid=" & txtempid & ";"

        DoCmd.RunSQL "UPDATE dbo_employees " & "SET dbo_employees.vhrs='" & sum & "' " & "WHERE dbo_employees.empid=" & txtempid & ";"      

    End If

    If morehours = 1 And adate < andateend Then
        vac = vac - adv
        DoCmd.RunSQL "UPDATE dbo_employees " & _
                            "SET dbo_employees.vhrs='" & _
                            vac & "' " & _
                            "WHERE dbo_employees.empid=" & txtempid & ";"
        adv = 0
        DoCmd.RunSQL "UPDATE dbo_employees " & _
                            "SET dbo_employees.advhours='" & _
                            adv & "' " & _
                            "WHERE dbo_employees.empid=" & txtempid & ";"
        morehours = 0
        DoCmd.RunSQL "UPDATE dbo_employees " & _
                            "SET dbo_employees.totalvachrs='" & _
                            morehours & "' " & _
                            "WHERE dbo_employees.empid=" & txtempid & ";"

    End If

    Me.Bookmark = rs.Bookmark
    rs.MoveNext
Loop
rs.Close
Set rs = Nothing

【问题讨论】:

你试过Do While Loop吗? 是的,我刚刚编辑了我的帖子以显示我的循环以进行 Do While 但仍然没有运气 显示查询..还确定记录集包含行吗? Right... 在调试模式下单步执行代码,看看它是否表明它是 EOF 太快了。如果是这种情况,您的记录集不是您所期望的——这意味着您的查询不正确 记录集是正确的,第一个例子也是EOF太快了,但在第二个例子中,它遍历了所有30条记录,但最后有一个drop change对话框。所以我的想法是这是一个循环问题,我做错了。 【参考方案1】:

DotyDot,

我认为您的问题是对记录集和表单(以及连续表单)如何工作的基本误解。

无论表单是常规表单(一次显示一条记录)还是连续表单(一次显示多条记录),引用表单上的值(字段)和/或使用的能力和限制记录集不会改变。

您不能像您尝试做的那样“循环”通过代码中的连续表单并引用表单上的控件 (txtempid) 并从每条记录中获取值。

每当您在表单上引用控件时,您将只能获得与当前记录关联的该控件的值。

循环通过记录集,即使您从表单记录集实例化记录集,也不会更改表单上的当前记录指针。

您的第二个代码示例最接近可行,但仍需要一些工作。首先,在代码中使用记录集时,您很可能不会引用表单控件,而是直接从记录集中引用字段值。我不知道你的表结构,但这里有一个例子可以让你走上正轨。

我假设此代码将在单击按钮或您想要评估所有员工的其他事件时运行。

Dim rst as DAO.Recordset
Set rst = Me.RecordsetClone
Do While Not rst.EOF
  adv = DLookup("advhours", "dbo_employees", "[empid] = " & rst("empid"))
  vac = DLookup("vhrs", "dbo_employees", "[empid] = " & rst("empid"))
  adate = DLookup("advdate", "dbo_employees", "[empid] = " & rst("empid"))
  andatestart = DLookup("anndate", "dbo_employees", "[empid] = " & rst("empid"))
  andateend = DateAdd("yyyy", AgeSimple(rst("andatestart")), rst("andatestart"))
  anddateend = DateAdd("yyyy", 1, rst("andateend"))
  morehours = DLookup("totalvachrs", "dbo_employees", "[empid] = " & rst("empid"))

  sum = adv + vac

  If adv > 0 And adate > DateAdd("yyyy", AgeSimple(rst("andatestart")), rst("andatestart")) And adate < anddateend And morehours = 0 Then      
    morehours = 1
    rst.Edit
    rst("totalvachrs") = morehours
    rst("vhrs") = sum
    rst.Update
  End If

  If morehours = 1 And adate < andateend Then
    vac = vac - adv
    rst.Edit
    rst("vhrs") = vac
    adv = 0
    rst("advhours") = adv
    morehours = 0
    rst("totalvachrs") = morehours
    rst.Update
  End If

  rst.MoveNext
Loop
Set rst = Nothing
'Refresh the screen
Me.Requery

你不需要使用DoCmd.RunSQL,你可以通过代码直接在Recordset中编辑数据。

请注意,在您的示例代码中,您似乎在引用表单上的控件的任何地方

[日期开始]

我将其更改为引用记录集中的该字段名称

rst("日期开始")

此代码将遍历表单上的每条记录,并执行您正在执行的计算和更新。

仅供参考,在您的原始代码中,通过设置表单书签 (Me.Bookmark) 到记录集书签,您正在强制表单移动 当前记录指针通过每条记录,但那真的不是 完成您正在尝试做的事情的最佳方法,IMO

我希望这会有所帮助。

【讨论】:

以上是关于循环访问 MS Access 中的连续记录的主要内容,如果未能解决你的问题,请参考以下文章

循环访问 MS Access 中所有记录的代码

如何根据每条记录的连续表单中 ms-access 中的其他值填充文本框上的值

解决 Ms Access 连续表格?

MS-Access 中的多个日期范围

循环访问 Access 中的两个记录集并更新条目

MS Access 中的条件选择语句