4

我在 MS Access 2002 中有一个表单,在命令按钮后面有以下代码片段。

'Requery subform to make sure total is calculated
Me.fsubUpdateShipments.Requery
DoEvents

'Confirm quantities have been entered
If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then
    MsgBox "Cannot create shipment, no quantities have been entered", vbCritical
    Exit Sub
End If

几个月来这一直运行良好,但今天一位同事来找我并解释说,即使他们输入了数量,错误消息也会显示。

经过一番挖掘后,我确定.Value <= 0在相关文本框完成计算其值之前正在评估表达式=Sum([QtyToShip]):这似乎只发生在子表单有大量记录(大约 10 条或更多)并且显然是一个严重问题时。

在包含语句的行上添加断点If可以使代码正确运行,但我显然不能永久使用此方法。

有什么方法可以强制代码暂停,直到子窗体控件完成重新计算它们的值?

4

2 回答 2

4

我会完全跳过使用用户界面并查看表格。如果这是在主窗体命令按钮上运行的,则子窗体失去焦点并保存其值。重新查询是不必要的。只需在 DSum 的标准(第三个参数)中重新创建父子关系:

If DSum("QtyToShip", "ShipmentDetails", "ShipmentID = " & Me!ShipmentID) <= 0 Then
    MsgBox "Cannot create shipment, no quantities have been entered", vbCritical
    Exit Sub
End If
于 2014-10-13T14:56:22.157 回答
1

有两个选项,其他人都已经确定了,但是由于他们的建议不完整或不整洁(缓慢),我正在发布这篇文章。

A. 您可以强制等待以延迟 IF 测试:

把它放在一个模块中:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
...
Public Sub GoSleep(millisecondDelay as long)
    Sleep (millisecondDelay)
End Sub

并以您的形式:

'Requery subform to make sure total is calculated
Me.fsubUpdateShipments.Requery
DoEvents

GoSleep 1000 '1 second delay. Or 2000, whatever is required really

'Confirm quantities have been entered
If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then
   MsgBox "Cannot create shipment, no quantities have been entered", vbCritical
   Exit Sub
End If

B. 正如另一个答案所说,您可以自己重新计算,并在此结果的基础上进行测试。

但是,我建议不要像 pteranodon 建议的那样使用 DSum,而是建议使用比 DSum 更快的东西,因为 DSum(DCount 等)非常慢。

我通常使用 ADO 进行数据操作,尽管我的代码可以很容易地适应 DAO。要使用此代码,如果您还没有 Microsoft activeX 2.8,则需要参考:

在一个模块中:

Public Function GetDBValue(qry as string) as variant
    dim rst as new adodb.recordset
    rst.open qry, currentproject.connection, adOpenKeyset, adLockReadOnly
    if rst.eof then
        GetValue = null
    else
        GetValue = rst.fields(0)
    end if
end function

public Function IsNullSQL(basevalue as variant, replacementvalue as variant) as variant
    isNullSQL = iif(isnull(basevalue), replacementvalue, basevalue)
end function

以您的形式:

''Requery subform to make sure total is calculated
'Me.fsubUpdateShipments.Requery
'DoEvents

'Confirm quantities have been entered
If IsNullSQL(GetValue("SELECT Sum(QtyToShip) FROM tbl WHERE ..."), -1) < 0 Then
    MsgBox "Cannot create shipment, no quantities have been entered.", vbCritical, "No Quantities to Ship"
    Exit Sub
End If

'If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then
'    MsgBox "Cannot create shipment, no quantities have been entered", vbCritical
'    Exit Sub
'End If
于 2014-10-13T21:44:10.900 回答