vba - 为什么 DLookup 不返回事务期间更新的值?
问题描述
我在我的 MS Access VBA 代码中使用事务。我更新了我的一个字段,即Incoming_Pieces
我的 Inventory 表中的字段。然后,在提交事务之前,我DLookup
在更新的字段上使用。该DLookup
函数将返回事务之前的值,而不是提交之前事务期间更新的值。
这是故意的吗?没有错误消息或任何警告表明我正在检索的数据与事务中正在更新的数据不同步。
是生成SELECT
语句而不是 DLookup 的唯一解决方法吗?
这是我的测试代码来证明这一点。
Public Function testTransaction()
Dim pieces As Variant
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces) ' <------------ prints 0
DAO.DBEngine.BeginTrans
Dim sql As String
sql = "UPDATE Inventory SET Incoming_Pieces = 10 WHERE Code='MT-1-1000x1x1'"
CurrentDb.Execute (sql)
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces) ' <------------ prints 0
DAO.DBEngine.CommitTrans
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces) ' <------------ prints 10
End Function
解决方案
DLookUp
在应用程序范围内执行,而BeginTrans
只影响数据库引擎范围,并且只影响DAO。
在查询中,我们可以区分 2 个作用域:
- 应用。这些查询可以使用用户定义的函数,并且可以引用基于表单的参数(例如
WHERE MyField = Forms!SomeForm!SomeControl
)。 - 数据库引擎(DAO/ODBC/Others):这些查询不能引用应用程序中发生的任何事情,因此不能使用 VBA 中定义的函数或基于表单的参数,但如果它们操作的连接/工作空间会受到事务的影响在开始一个。
如果我们想查询事务中发生的事情,我们需要在同一个范围内。这意味着您需要重写您DLookUp
的使用记录集。
pieces = CurrentDb.OpenRecordset("SELECT Incoming_Pieces FROM Inventory WHERE Code='MT-1-1000x1x1'")(0).Value
一个更简单的例子来证明这一点:
DAO.DBEngine.BeginTrans
CurrentDb.Execute "INSERT INTO Table1(Field1) VALUES(1)"
Debug.Print CurrentDb.OpenRecordset("SELECT COUNT(*) FROM Table1")(0) 'Prints 1 assuming the table was empty
Debug.Print DCount("*", "Table1") 'Prints 0
DAO.DBEngine.Rollback
推荐阅读
- javascript - 如何在节点旁边添加图像或 svg?
- excel - 索引函数从关闭的工作簿中提取值,但使用单元格值作为工作表名称
- ruby-on-rails - 访问子字段时如何让 graphql-ruby 使用连接?
- javascript - 锚标记可在屏幕宽度上单击
- gitlab-ci - 使用 gitlab ci,我可以做类似“if tag == 'xx'”的事情吗?
- python - 是否有任何功能可以从多个列表中选择多个项目
- java - 在 SQL 语句列表中查找元素
- macos - 在 Mojave 上为 Mac OS Catalina 公证 Qt 应用程序
- java - 在给定的情况下,什么是“最好的”可能的方法?
- java - 引用类型中的有界通配符