访问 VBA 函数 While...Wend 或 Do ...Loop

Access VBA function While...Wend or Do ...Loop

我正在为我的 access 数据库开发一个功能,该功能会根据产品表单中输入的数据自动填写任务表单中的表单域。

    Function IsProductReceived(varID As Variant) As String

    Dim rst As New ADODB.Recordset
    Dim strSQL As String
    Dim lngTOID As Long
    Dim strReceiveDate As Date
    Dim bAcceptable As Boolean

    On Error GoTo ErrorHandler

    If IsNull(varID) Then
      IsProductReceived = "TBD"
    Else
        lngTOID = varID
        strSQL = "SELECT tblProduct.TaskID, tblProduct.Received, tblProduct.Acceptable FROM tblProduct WHERE tblProduct.TaskID = " & lngTOID

       rst.Open strSQL, CurrentProject.Connection, adOpenDynamic, adLockOptimistic

    If rst.BOF And rst.EOF Then
    IsProductReceived = "TBD"
    Exit Function
     Else
     While rst.EOF = False

     If rst![Received] <> "" Then
        strReceiveDate = rst![Received]
        bAcceptable = rst![Acceptable]
        If IsDate(strReceiveDate) Then
            If bAcceptable = False Then
                IsProductReceived = "YES/NOT ACCEPTED"
            Else
                IsProductReceived = "YES/ACCEPTED"
            End If
        Else
            IsProductReceived = "NO"
        End If
    Else
        IsProductReceived = "NO"
    End If
    rst.MoveNext
    Wend
End If


rst.Close
Set rst = Nothing
End If
 Exit Function


    ErrorHandler:
MsgBox Err.Description
Err.Clear
If rst.State = adStateOpen Then
    rst.Close
    Set rst = Nothing
End If
End Function

任务表单相关的产品表单往往不止一个,而且产品在不同的时间收到。我希望 "IsProductReceived = "no" 保留在任务表单上,直到收到与该任务相关的所有产品。

只要未收到第一个产品,此代码似乎就可以正常工作。我似乎可以弄清楚如何让它保持 "no" 直到收到所有产品。

我目前正在使用 while/wend,我尝试过 Do/loop,但仍然没有令人满意的结果。任何帮助将不胜感激

我在您的代码中看到的问题是您从 table 获取记录集,遍历该集并测试 "Recieved",然后分配 return 每次测试后您的功能的价值。实际上,您只是 returning 记录集中最后一条记录的值。也许不是在 While 循环中设置 isProductRecieved 的值,而是在遇到未收到的产品时将 bool 值设置为 false,然后在循环后设置函数的 return 值:

Dim receive As Boolean
Dim accept As Boolean
receive = True
accept = False

If rst![Received] <> "" Then
        strReceiveDate = rst![Received]
        bAcceptable = rst![Acceptable]
        If IsDate(strReceiveDate) Then
            If bAcceptable = False Then
                accept = False
            Else
                accept = True
            End If
        Else
            receive = False
        End If
    Else
        receive = False
    End If

所以现在,如果 "receive" 一直到 while 循环的末尾,您就会知道每个产品都已收到,但如果没有收到任何产品,则会将其设置为 false。你也可以在那里建立一个短路来让它更快一点。

怎么样:

Function IsProductReceived(TaskID) As String
    Dim product As New ADODB.Recordset
    Dim sql As String
    Dim countAll As Integer
    Dim countReceived As Integer
    Dim countAccepted As Integer

    IsProductReceived = "TBD"

    If Not IsNumeric(TaskID) Then Exit Function

    sql = "SELECT Received, Acceptable FROM tblProduct WHERE TaskID = " & TaskID
    product.Open sql, CurrentProject.Connection, adOpenDynamic, adLockOptimistic

    While Not product.EOF
        countAll = countAll + 1
        If IsDate(product!Received) Then countReceived = countReceived + 1
        If product!Acceptable Then countAccepted = countAccepted + 1
        product.MoveNext
    Wend

    product.Close

    If countAll = 0 Then
        IsProductReceived = "No"
    ElseIf countAll = countAccepted Then
        IsProductReceived = "YES/ACCEPTED"
    ElseIf countAll = countReceived Then
        IsProductReceived = "YES/NOT ACCEPTED"
    Else
        IsProductReceived = "No"
    End If
End Function

一些注意事项:

  • 更好地缩进代码。
  • 放弃假的匈牙利符号,使用描述性变量名。
  • 避免深度嵌套,尤其是在确定 return 值时。
  • 检查参数,检查不通过则提前退出。这从函数中删除了嵌套深度。
  • 避免使用 Variant 参数类型,除非函数 必须 处理不同的数据类型。这里 IntegerLong 类型可能更合适。 (使用类型化函数参数完全不需要类型检查。)
  • While x = False 是一种反模式。使用 While Not x.
  • 无需先将记录集字段保存在局部变量中。直接用就行了。
  • 避免通过字符串连接构建 SQL。在 IsNumeric() 检查之后,上面的内容可能没问题,但是 you really should use parameterized queries.