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