逻辑:
问题。 当循环过去了! StudentName =“学生姓名2”在“.Update”行中我收到错误。 错误: “由于索引,主键或关系中的重复值而无法进行更改。更改包含重复值的一个或多个字段中的数据会删除索引或通过允许重复值覆盖它,然后重试。”
换句话说,第一次错误处理程序正常工作,当我重新启动时,我收到一个错误。
题。 如何根据描述的逻辑使代码工作?
Private Sub btnAddRecord_Click()
Dim nameStud As String
Dim rstStud As DAO.Recordset '
Dim rstGroupStud As DAO.Recordset '
Set rstStud = CurrentDb.OpenRecordset("tbl_02_Students", dbOpenSnapshot) '
Set rstGroupStud = CurrentDb.OpenRecordset("tbl_03_GruopsStudents", dbOpenDynaset) '
' *** rstStud
With rstStud
Do Until .EOF = True
nameStud = !nameStud
On Error GoTo errend
' *** rstGroupStud
With rstGroupStud
.AddNew
!idGroup = Me.id_GroupFrm
!nameStud = nameStud
' nameStud
.Update
End With
rstGroupStud.Close
Me.frm_03_GruopsStudents_tbl.Requery
Exit Sub
errend:
.MoveNext
Loop
End With
On Error Resume Next
rstStud.Close
Set rstStud = Nothing
End Sub
Update_1 文件 - link
你需要解决执行路径;正常和错误执行状态交织在一起,这就是为什么无法处理超出第一个错误的错误的原因。
Private Sub btnAddRecord_Click()
Dim nameStud As String
Dim rstStud As DAO.Recordset '
Dim rstGroupStud As DAO.Recordset '
Set rstStud = CurrentDb.OpenRecordset("tbl_02_Students", dbOpenSnapshot) '
Set rstGroupStud = CurrentDb.OpenRecordset("tbl_03_GruopsStudents", dbOpenDynaset) '
' *** rstStud
With rstStud
Do Until .EOF = True
On Error GoTo ErrHandler
nameStud = !nameStud
' *** rstGroupStud
With rstGroupStud
.AddNew
!idGroup = Me.id_GroupFrm
!nameStud = nameStud
' nameStud
.Update
End With
rstGroupStud.Close
Me.frm_03_GruopsStudents_tbl.Requery
Exit Do
TryNext:
On Error Resume Next
.MoveNext
If Err.Number <> 0 Then Exit Do
On Error GoTo 0
Loop
End With
On Error Resume Next
rstStud.Close
Set rstStud = Nothing
On Error GoTo 0
Exit Sub
ErrHandler:
Resume TryNext
End Sub
这样ErrHandler
只能在错误状态下运行; TryNext
在“快乐的路径”中运行,并且Exit Do
突破循环(但不是在程序之外),因此清理代码可以运行任何结果。
不要在VBA中这样做。请在查询中执行此操作。
例如,您可以这样做:
创建名为qryAssignStudentsToGroup
的查询:
PARAMETERS id_GroupFrm INT;
INSERT INTO tbl_03_GruopsStudents (idGroup, nameStud)
SELECT id_GroupFrm, nameStud
FROM tbl_02_Students AS s
WHERE NOT EXISTS (
SELECT NULL
FROM tbl_03_GruopsStudents AS g
WHERE s.nameStud = g.nameStud
AND g.idGroup = id_GroupFrm
);
然后您的代码变为:
Private Sub btnAddRecord_Click()
With CurrentDb.QueryDefs("qryAssignStudentsToGroup")
.Parameters("id_GroupFrm") = Me.id_GroupFrm
.Execute
End With
Me.frm_03_GruopsStudents_tbl.Requery
End Sub
这为同样的事情提供了更少的代码,并且只需过滤掉行就可以消除错误处理的复杂性。更重要的是,您执行一次批量更新,而不是针对您触摸的每一行。这充分利用了数据库引擎的强大功能。使用DAO.Recordset在循环中执行操作很方便,但这是一行一行的编程。你真的想要了解基于集合的编程。
您必须调用Err.Clear
来重置错误状态
errend:
Err.Clear
.MoveNext
我会在循环后调用Me.frm_03_GruopsStudents_tbl.Requery
。一直没有重新征服形式的意义。
但跳转到另一个常规代码部分而不是去错误处理程序不是处理错误的常用方法。为了解决在MoveNext
上处理错误的可能性,请更改以下代码:
Private Sub btnAddRecord_Click()
Dim nameStud As String
Dim rstStud As DAO.Recordset
Dim rstGroupStud As DAO.Recordset
Set rstStud = CurrentDb.OpenRecordset("tbl_02_Students", dbOpenSnapshot)
Set rstGroupStud = CurrentDb.OpenRecordset("tbl_03_GruopsStudents", dbOpenDynaset)
' *** rstStud
With rstStud
Do Until .EOF = True
nameStud = !nameStud
On Error GoTo UpdateError
' *** rstGroupStud
With rstGroupStud
.AddNew
!idGroup = Me.id_GroupFrm
!nameStud = nameStud
' nameStud
.Update
End With
rstGroupStud.Close
Me.frm_03_GruopsStudents_tbl.Requery
Exit Sub
continue_loop:
On Error GoTo MoveNextError
.MoveNext
Loop
End With
CleanUp:
On Error Resume Next
rstStud.Close
Set rstStud = Nothing
Exit Sub
UpdateError:
Resume continue_loop
MoveNextError:
MsgBox Err.Description
Resume CleanUp
End Sub
这种模式是可扩展的。您可以根据需要添加任意数量的错误处理程序。