上下文 我在我的数据库中制作了一个假期跟踪模块。员工可以要求在当前年度提前退休,并将从下一年度扣除。
案例: 我正在尝试通过员工的记录集连续循环,看看他们是否已获得高级时间,如果是,则将其添加到他们的假期时间。
问题: 我有逻辑,但我不能让它以我的连续形式循环每个员工。
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
答案 0 :(得分:1)
DotyDot,
我认为您的问题是对记录集和表单(以及连续表单)如何工作的基本误解。
无论表单是常规表单(一次显示一条记录)还是连续表单(一次显示多条记录),表格和/或使用中引用值(字段)的能力和限制记录集不会改变。
你不能循环播放&#34;通过代码中的连续表单并引用表单上的控件(txtempid)并从您尝试的每个记录中获取值。
无论何时引用表单上的控件,您只能获得与当前记录关联的该控件的值。
循环遍历记录集,即使从表单recordsetclone中实例化记录集,也不会更改表单上的当前记录指针。
你的第二个代码示例最接近可行的东西,但仍需要一些工作。首先,在代码中使用记录集时,您很可能不会引用表单控件,您将直接从记录集引用字段值。我不知道你的桌子结构,但这里有一个例子可以让你走上正确的轨道。
我假设此代码将在按钮单击或其他您想要评估所有员工的事件上运行。
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中编辑数据。
请注意,在您的示例代码中,您似乎在表单中引用控件的任何位置
[andatestart]
我将其更改为引用记录集中的字段名称
RST(&#34; andatestart&#34)
此代码将遍历表单上的每条记录,并执行您正在进行的计算和更新。
仅供参考,在您的原始代码中,通过设置表单书签(Me.Bookmark) 到记录集书签,你强迫表格移动 当前记录指针通过每条记录,但实际上并非如此 完成你想要做的事情的最佳方式,IMO
我希望这会有所帮助。