访问VBA功能虽然... Wend或Do ...循环

时间:2015-03-26 16:41:31

标签: vba access-vba ms-access-2010

我正在为我的访问数据库开发一个函数,该函数根据在产品表单中输入的数据自动填写我的任务表单中的表单字段。

    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

通常会有一个与任务表单相关的产品表单,并且会在不同时间收到产品。我希望&#34; IsProductReceived =&#34; no&#34;保留在任务表单上,直到收到与任务相关的所有产品。

只要尚未收到第一个产品,此代码似乎正在运行。我似乎可以弄清楚如何让它保持不变&#34;没有&#34;直到收到所有产品。

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

2 个答案:

答案 0 :(得分:1)

怎么样:

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

一些注意事项:

  • 更好地缩进代码。
  • 删除虚假的匈牙利表示法,使用描述性变量名称。
  • 避免深度嵌套,尤其是在确定返回值时。
  • 检查参数并在检查失败时提前退出。这将从函数中删除嵌套深度。
  • 避免使用Variant参数类型,除非函数必须处理不同的数据类型。这里IntegerLong类型可能更合适。 (使用类型化的函数参数完全不需要进行类型检查。)
  • While x = False是反模式。使用While Not x
  • 首先不需要在局部变量中保存记录集字段。直接使用它们。
  • 避免从字符串连接构建SQL。在IsNumeric()检查后,上述情况可能还可以,但you really should use parameterized queries

答案 1 :(得分:0)

我在您的代码中看到的问题是,您正在从表中获取记录集,循环访问集并测试&#34;已接收&#34;然后在每次测试后为函数指定返回值。实际上,您只需返回记录集中最后一条记录的值。也许不是在While循环中设置isProductRecieved的值,而是在遇到没有收到的产品时将bool值设置为false,然后在循环后设置函数的返回值: / p>

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

现在,如果&#34;收到&#34;一直到你的while循环结束,你知道每个产品都被收到,但如果没有收到任何产品,它将被设置为false。你也可以在那里建立一个短路,使其快一点。