【问题标题】:Unexpected behaviour with .FindFirst VBA MS Access function: .NoMatch always returns true.FindFirst VBA MS Access 函数的意外行为:.NoMatch 始终返回 true
【发布时间】:2013-01-21 19:20:32
【问题描述】:

查看下面的代码行。

Dim rst As DAO.Recordset
Dim strSql As String

strSql = "SELECT * FROM MachineSettingsT;"
Set rst = DBEngine(0)(0).OpenRecordset(strSql)

rst.FindFirst "Microwave = " & "'" & Me.Microwave & "'" & " AND WashingMachine =" & "'" & Me.WashingMachine & "'" & " AND Element1 =" & "'" & Me.Element1 & "'" _
               & "AND Element3 =" & "'" & Me.Element3 & "'" & "AND Dryer =" & "'" & Me.Dryer & "'" & "AND SettingID <>" & "'" & Me.SettingID & "'"

If Not rst.NoMatch Then  
    Cancel = True
    If MsgBox("Setting already exists; go to existing record?", vbYesNo) = vbYes Then
        Me.Undo
        DoCmd.SearchForRecord , , acFirst, "[SettingID] = " & rst("SettingID")
    End If
End If
rst.Close

问题:如果 rst.FindFirst 表达式中的任何值为 Null,则 rst.NoMatch 始终返回 true,即使正在评估的字段中存在具有匹配 Null 值的记录。这种行为是可以预期的还是可能存在另一个潜在问题。我检查了msdn 页面,但它没有提供有关此类行为的信息。

【问题讨论】:

    标签: ms-access duplicates vba findfirst


    【解决方案1】:

    考虑一种不同的方法。请注意,这是一组文本数据类型字段。

    Dim rst As DAO.Recordset
    Dim strSql As String
    Dim db As Database
    
    Set db=CurrentDB
    
    strSql = "SELECT * FROM MachineSettingsT WHERE 1=1 "
    ''Set rst = db.OpenRecordset(strSql)
    
    If not IsNull(Me.Microwave) Then
       strWhere =  " AND Microwave = '" & Me.Microwave & "'" 
    End if
    If not IsNull(Me.WashingMachine) Then
       strWhere = strWhere & " AND WashingMachine ='" & Me.WashingMachine & "'"
    End if
    If not IsNull(Me.Element1) Then
       strWhere = strWhere & " AND Element1 ='" & Me.Element1 & "'" 
    End if
    If not IsNull(Me.Element3) Then
       strWhere = strWhere & " AND Element3 ='" & Me.Element3 & "'"  
    End if
    If not IsNull(Me.Dryer) Then
       strWhere = strWhere & " AND Dryer ='" & Me.Dryer & "'"
    End if
    
    Set rst = db.OpenRecordset(strSql & strWhere) 
    

    【讨论】:

    • +1 很好地使用了Where 1=1,以确保您无需担心基于值为空的值是使用Where 还是And
    • 非常感谢。奇迹般有效。请注意,需要在 if 语句中添加一个子句,以便仍然评估 Null 条件。例如If NOT IsNull(Me.Microwave) Then strWhere = strWhere & ... Else strWhere = " AND Microwave IS NULL" End If
    • 更多信息 Where 1=1 here
    【解决方案2】:

    当控件值为 Null 时,您的.FindFirst标准必须检查对应字段Is Null 是否等于控件的值。从一个更简单的示例开始,检查两个控件/字段对。

    Dim strCriteria As String
    If IsNull(Me.Microwave) Then
        strCriteria = " AND Microwave Is Null"
    Else
        strCriteria = " AND Microwave = '" & Me.Microwave & "'"
    End If
    If IsNull(Me.WashingMachine) Then
        strCriteria = strCriteria & " AND WashingMachine Is Null"
    Else
        strCriteria = strCriteria & " AND WashingMachine = '" & Me.WashingMachine & "'"
    End If
    If Len(strCriteria) > 0 Then
        ' discard leading " AND "
        strCriteria = Mid(strCriteria, 6)
        Debug.Print strCriteria 
        rst.FindFirst strCriteria
    End If
    

    【讨论】:

    • 这种方法也可以,但我使用@Remou 的方法来解决我的问题。谢谢你,我现在知道在使用 .FindFirst 时要小心 null 值以供将来参考
    猜你喜欢
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2022-12-11
    • 2019-11-17
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多