如果数据被 VBA 更改,则记录已更改错误

Record has been changed error if data is changed by VBA

我有一个 MS Access (2016) 数据库,它使用指向 MySQL 数据库的链接表。在访问数据库中,我有一个用于数据输入的表单。单击“重新计算”按钮时,我需要(手动)重新计算某些字段。

我遇到的问题是,当我 运行 VBA 代码更新表单上的字段时,如果我随后尝试导航到另一条记录,我会收到错误消息 "This record has been changed by another user since you started editing it...."

我是唯一访问此数据库的用户。如果我不更新表单上的绑定字段,一切正常。一旦我这样做,然后我在导航到下一条记录时收到该错误。

这是我的 vba 重新计算按钮代码:

Private Sub Recalculate()
    vendorID = Me.product_supplier_id
    supplierID = "supplier_id=" & vendorID

    supplierHandling = Me.product_handling
    vendorFee = Me.product_vendor_fee
    supplierMarkupPercent = DLookup("supplier_markup_percent", "suppliers", supplierID)
    supplierMarkupFixed = DLookup("supplier_markup_fixed", "suppliers", supplierID)

    productCost = Me.product_cost
    productShipping = Me.product_shipping
    totalCost = productCost + productShipping + supplierHandling
    totalCost = totalCost + vendorFee
    markup = supplierMarkupFixed + (totalCost * supplierMarkupPercent)
    productPrice = (totalCost + markup) / 0.85
    amzFee = productPrice * 0.15
    totalCost = totalCost + amzFee
    profit = productPrice - totalCost

    Me.product_total_cost = totalCost
    Me.product_price = productPrice
    Me.product_profit = profit

    SetPriceColor
End Sub

接近尾声的 3 个语句(在 SetPriceColor 之前)是罪魁祸首。

我不确定如何解决这个问题。我梳理了很多 google 搜索,但没有找到针对此特定案例的解决方案。

是的,问题是由于链接的 ODBC tables。加上浮点数列,当 Access 检查您在绑定表单中的更改(通过 VBA 或手动)是否与保存记录的先前版本冲突时,这可能会导致问题。

解决方案应该是在 table.

中添加带有 DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMPTIMESTAMP

来自here

ALTER TABLE myTable
ADD COLUMN updated_at 
  TIMESTAMP DEFAULT CURRENT_TIMESTAMP 
  ON UPDATE CURRENT_TIMESTAMP;

查看这些问题:

Write Conflict messages suddenly start happening in ODBC linked tables

对于从 SQL 服务器链接的 tables,添加 ROWVERSION 列绝对可以解决问题。对于 MySql(及其 ODBC 驱动程序),它应该可以工作,并且确实在这里工作。

当您将 SQL 数据库链接到 Access 数据库时,您需要确保一些事情到位。

在 SQL 方面,SQL table 必须有一个主键和一个数据类型为时间戳的时间戳字段。

在访问方面,当引用 tables 和使用记录集时,包括 dbOpenDynaset 和 dbSeeChanges。这是一个例子:

Dim qry As String
Dim rs As Recordset

qry = "SELECT * FROM yourtable"
Set rs = CurrentDB.OpenRecordset(qry, dbOpenDynaset, dbSeeChanges)

这应该可以阻止您的错误弹出。此外,如果您对 SQL table 进行更改,Access 数据库将不会始终捕获这些更改,因此您需要使用链接 Table 管理器刷新连接。