访问 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
参数类型,除非函数 必须 处理不同的数据类型。这里 Integer
或 Long
类型可能更合适。 (使用类型化函数参数完全不需要类型检查。)
While x = False
是一种反模式。使用 While Not x
.
- 无需先将记录集字段保存在局部变量中。直接用就行了。
- 避免通过字符串连接构建 SQL。在
IsNumeric()
检查之后,上面的内容可能没问题,但是 you really should use parameterized queries.
我正在为我的 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
参数类型,除非函数 必须 处理不同的数据类型。这里Integer
或Long
类型可能更合适。 (使用类型化函数参数完全不需要类型检查。) While x = False
是一种反模式。使用While Not x
.- 无需先将记录集字段保存在局部变量中。直接用就行了。
- 避免通过字符串连接构建 SQL。在
IsNumeric()
检查之后,上面的内容可能没问题,但是 you really should use parameterized queries.