2013-02-06 84 views
2

查看下面的代碼行。使用.FindFirst VBA MS Access函數的意外行爲:.NoMatch始終返回true

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表達值都空然後rst.NoMatch即使當存在與該領域的一個匹配空值的記錄被評估總是返回true。這是行爲預期還是可能存在另一個潛在問題。我檢查了msdn頁面,但沒有提供有關這種行爲的信息。

回答

2

考慮一種不同的方法。請注意,這是針對一組文本數據類型字段。

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

+1很好的使用'Where 1 = 1'來確保你不需要擔心是否使用基於null的'Where'或'And'。 –

+0

非常感謝。奇蹟般有效。請注意,雖然需要在if語句中添加子句,以便仍然評估Null條件。例如如果不是IsNull(Me.Microwave)那麼strWhere = strWhere&... Else strWhere =「AND Microwave IS NULL」End If – jaromey

+0

更多關於Where 1 = 1 [這裏](http://stackoverflow.com/questions/ 242822/why-would-someone-use-where-1-1-and-conditions-in-a-sql-clause) – jaromey

1

當控制值是零,你.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 
+0

這種方法也可以,但我用@ Remou的方法來解決我的問題。謝謝,我現在知道將來的參考,使用.FindFirst時要小心空值 – jaromey