Handling AddNew Key Violations ADODB.Recordset
我以前的标题在那里引起了一些混乱...更新
我最近在使用一些VBA桥接Excel和Access时遇到了此问题。
因此,我有一个电子表格,其中包含我需要导入到Access数据库的表。
该表是通用的,如下所示。
1 2 3 4 | EmployeeNumber Unused_Field2 Unused_Field3 1 @@@ @@@ 2 @@@ @@@ 3 @@@ @@@ |
Access中的唯一键设置为EmployeeNumber。
我在Excel中的VBA代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Sub test() Dim con As ADODB.Connection Dim rst As ADODB.Recordset strcon ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\temp\\mydb.mdb;" strsql ="SELECT * FROM Table1" Set con = New Connection Set rst = New Recordset con.Open strcon rst.Open strsql, strcon, adOpenStatic, adLockOptimistic For i = 0 To n On Error GoTo Errhdl rst.AddNew Array("Field1","Field2","Field3"), Array(Range("A" & i), Range("B" & i), Range("C" & i)) On Error GoTo 0 Next Exit Sub Errhdl: Debug.Print"Record" & i &"caused an error" Resume Next End Sub |
不幸的是,数据不是高质量的,而且我经常会有重复的值,从而始终导致密钥冲突。
虽然我虽然Resume Next会清除允许另一个" AddNew"运行的错误,但事实并非如此。
一键违反后的所有后续条目将返回相同的错误。
所以我的问题如下:
方法Errors.Clear。那并没有解决问题。错误集合是特定于ADO对象的属性-MSDN错误集合)
请让我知道是否需要进一步说明!
因此,如果Recordset.AddNew遇到错误,我找到了解决方案。
诀窍是使用CancelUpdate-MSDN
也可以使用Status属性来检查操作是否成功。
示例代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | Sub test() Dim con As ADODB.Connection Dim rst As ADODB.Recordset strcon ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\temp\\mydb.mdb;" strsql ="SELECT * FROM Table1" Set con = New Connection Set rst = New Recordset con.Open strcon rst.Open strsql, strcon, adOpenStatic, adLockOptimistic For i = 0 To n On Error GoTo Errhdl rst.AddNew Array("Field1","Field2","Field3"), Array(Range("A" & i), Range("B" & i), Range("C" & i)) On Error GoTo 0 Next Exit Sub Errhdl: Debug.Print"Record" & i &"caused an error" If rst.Status <> 0 Then rst.CancelUpdate End If Resume Next End Sub |
我不会使用错误处理(处理ADO错误很棘手),但是在执行插入操作之前,请使用"查找"来每次检查键是否不存在。如果键是索引字段(如您的描述所建议),则可以考虑
这是我发现的代码片段,概述了步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | If Not .EOF Then .MoveFirst .Find"TPItemNbr='" & m_TPItemNbr &"'", , adSearchForward End If If .EOF Then .AddNew !TPItemVendorID = m_TPItemVendorID !TPItemNbr = m_TPItemNbr !TPItemEUOM = m_TPItemEUOM !TPItemUOMFactor = m_TPItemUOMFactor !TPItemPUOM = m_TPItemPUOM !TPItemDescription = m_TPItemDescription !TPItemUnitCost = m_TPItemUnitCost !TPItemUnitLabor = m_TPItemUnitLabor .Update |
也就是说,每次在循环中执行一次查找,如果EOF(文件末尾)为true,则表中尚未包含该键,因此可以执行插入操作。
添加以响应有关复合键的更多信息。
我将创建一个
替代方案可能是
- 运行一个单独的SQL语句以获取重复项列表的记录集
- 循环遍历,将值存储在数组中
-
每次检查数组时执行
AddNew
这对我来说似乎很混乱,特别是搜索数组的方面。
- 执行注释中链接的多查找方法。