Access 2013 VBA - 后续 SELECT 查询未找到来自 INSERT INTO 的新记录

Posted

技术标签:

【中文标题】Access 2013 VBA - 后续 SELECT 查询未找到来自 INSERT INTO 的新记录【英文标题】:Access 2013 VBA - new records from INSERT INTO not found by subsequent SELECT query 【发布时间】:2018-03-11 00:15:22 【问题描述】:

我正在通过 VBA 更新 Access 2013 表。我的任务需要在循环期间将某些记录添加到表中,然后从(更新的)表中读取记录。如果我在调试模式下逐行运行代码,我发现我的代码按预期工作。但是,如果我使用 F5 运行代码,我的结果将是不可预测的。有时代码按预期工作,有时循环提前结束。看起来好像新添加的记录没有被选择查询找到,即使它们已添加到表中。参考下面的代码,执行了最下面的INSERT INTO语句,但是后续打开adrsb记录集有时找不到更新的记录,导致循环提前终止。尽管我在调试方面尽了最大努力,但我已经为此困扰了好几天。任何帮助将不胜感激。 :)

Do
i = i + 1
'Debug.Assert i <> 4

If adrsb.State = 1 Then
    adrsb.Close
    Set adrsb = Nothing
    Set adrsb = New ADODB.Recordset
    adrsb.ActiveConnection = CurrentProject.Connection
    adrsb.CursorType = adOpenStatic
End If

'adrsb.CursorType = adOpenDynamic
adrsb.Open "SELECT tblInScopeRestructures.Code1, tblInScopeRestructures.Gen " & _
"FROM tblInScopeRestructures " & _
"GROUP BY tblInScopeRestructures.Code1, tblInScopeRestructures.Gen " & _
"HAVING (((tblInScopeRestructures.Gen)=" & i & "))" & _
"ORDER BY tblInScopeRestructures.Code1;"
adrsb.Requery

Dim adrsc As ADODB.Recordset

Set adrsc = New ADODB.Recordset
adrsc.ActiveConnection = CurrentProject.Connection
adrsc.CursorType = adOpenStatic

If Not adrsb.EOF Then
    adrsb.MoveLast
    adrsb.MoveFirst
End If

If adrsb.RecordCount <> 0 Then
    adrsb.MoveFirst
    'strPrevCode1 = adrsb.Fields("Code1")

    Do While Not adrsb.EOF

    strPrevCode1 = adrsb.Fields("Code1")
        If adrsc.State = 1 Then
            adrsc.Close
        End If
        adrsc.CursorType = adOpenStatic
        adrsc.Open "SELECT tblRestructure.Code1, tblRestructure.Code2, tblRestructure.RecDate " & _
        "FROM tblRestructure " & _
        "WHERE (((tblRestructure.Code2)='" & strPrevCode1 & "'));"
        If adrsc.RecordCount <> 0 Then
        adrsc.MoveFirst
        Do While Not adrsc.EOF
       adConn.Execute ("INSERT INTO tblInScopeRestructures(Code1,Code2,RecDate,Gen) VALUES ('" & adrsc.Fields("Code1") & "','" & adrsc.Fields("Code2") & _
       "',#" & Format(adrsc.Fields("RecDate"), "mm/dd/yyyy") & "#," & i + 1 & ")")
       Debug.Print adrsc.Fields("Code1") & adrsc.Fields("Code2")
       Debug.Print i + 1

       For j = 1 To 100000
       Next j

       adrsc.MoveNext

        Loop

       End If

      adrsb.MoveNext

      If adrsc.State = 1 Then
           adrsc.Close
      End If

    Loop

End If

   Debug.Assert adrsb.RecordCount <> 0
Loop While adrsb.RecordCount <> 0

【问题讨论】:

【参考方案1】:

我估计问题可能出在这里

   adrsb.CursorType = adOpenStatic

改成

   adrsb.CursorType = adOpenDynamic

而不是这段代码:

   For j = 1 To 100000
   Next j

你可以尝试一些稍微不那么粗暴的东西,例如:

   DoEvents

也许在 DoEvents 命令之后,您可以尝试在 ADODB 记录集上添加 Requery 命令。

除非您可能会丢失所需的光标位置,因此在执行刷新之前,您可以将主键的 ID 记录在变量中,然后在记录集中找到该光标位置

    intID = adrsb.Fields("MyKey")
    adrsb.Requery
    rs.Find "MyKey = " & intID

【讨论】:

谢谢 - 我会试试你提到的东西。我之前曾尝试过 adOpenDynamic 游标类型,但它给我带来了其他问题(内存记录计数通常显示为 -1)。我的代码中的 for-next 循环是一个绝望的 hack,试图为后续的选择查询找到插入的记录留出时间,我的意思是在发布之前将其删除。我会阅读 DoEvents 嗨 - 我尝试了 Mike 关于光标类型和使用 DoEvents 的建议,但无法修复。 我现在有了一个解决方案,方法是使用 adrsc 字段在 EXECUTE INTO 之后立即添加以下暂停代码:'TWait = Time TWait = DateAdd("s", 5, TWait) Do Until TNow >= TWait TNow = 时间循环'【参考方案2】:

好的,我有各种各样的解决方案。我在第二次 EXECUTE INTO 操作后插入了以下代码以立即暂停:

       TWait = Time
       TWait = DateAdd("s", 5, TWait)
       Do Until TNow >= TWait
          TNow = Time
       Loop

这会显着降低代码速度,但它确实有效。我尝试过更短的暂停,但有时会在循环提前退出时遇到相同的问题。虽然眼前的问题得到了解决,但我对这是必要的感到有点震惊,并且担心这样的问题何时会再次出现。

【讨论】:

以上是关于Access 2013 VBA - 后续 SELECT 查询未找到来自 INSERT INTO 的新记录的主要内容,如果未能解决你的问题,请参考以下文章

通过 Access 2013 VBA 编辑后无法打开 Excel 2013 文件

Access 2013 VBA 自动化 Excel 丢失窗口

Access 2013 - VBA - 记录集插入获取 ID

在 Access 2013 VBA 中从 Subform 动态设置 SourceObject 和 RecordSource

在列表框 ms-access 2013 VBA 中将多个不同的字段作为列表项返回

使用 vba/macros 将多个 CSV 文件中的特定列导入 Access 2013