Access 在单一表格中搜索所有记录
Access Search All Records in a Single Form
我在单一表单视图中有一个装订表单。
我想模仿记录导航按钮中搜索框的行为,但也有更多的控制权。我面临的问题是,当我的用户搜索记录时,有时他们会在找到记录时不小心开始键入记录(比如在输入 3 或 4 个字母后他们仍在键入搜索词)并且原始数据丢失.由于这些字段有时需要输入数据,因此此时锁定它们并不是一个真正的选择。
我的想法是关闭导航按钮并通过 VBA 或通过宏来模拟此功能,并在找到要搜索的值时将焦点设置在另一个锁定的字段上(也可以选择查找下一个或提醒已找到或未找到的东西)。
我已经尝试使用宏和 VBA,但无法正常工作。
我有这段代码(并且稍微使用了一些参数),但它只会搜索当前记录(而不是所有记录)并且要么移动到下一条记录,要么根本没有记录,如果我发表评论FindNext
行。
Private Sub cmdFind_Click()
Dim sText As String
sText = Me.txtSearch 'a text box where user enters search term
DoCmd.FindRecord sText, acAnywhere, False, acDown, True, acCurrent
DoCmd.FindNext
End Sub
显然,我遗漏了一些东西。有人可以提供一些见解或替代方法。
我认为 HansUp 已经 post 找到了解决方案...但是由于我想出了一种不同的搜索方式(通过 RecordsetClone
和 FindFirst
),我会post 反正就是这样,说不定有用。 :)
Private Sub cmdFind_Click()
Static RS As Recordset
Static sText As String
Dim curText As String
Dim newSearch As Boolean
Dim sCrit As String
curText = Nz(Me.txtSearch)
If curText = "" Then Exit Sub
' If text hasn't changed, use FindNext
If curText = sText Then
newSearch = False
Else
sText = curText
newSearch = True
End If
' First call?
If RS Is Nothing Then
Set RS = Me.RecordsetClone
newSearch = True
End If
' The field you are searching in
sCrit = "[Text1] LIKE '*" & sText & "*'"
If newSearch Then
RS.FindFirst sCrit
Else
RS.FindNext sCrit
End If
If Not RS.NoMatch Then
' If found, navigate to the record
Me.Bookmark = RS.Bookmark
Else
MsgBox "No (more) matches)", vbInformation
End If
End Sub
您似乎想要查找 任何 字段与搜索文本匹配的第一条记录。
在那种情况下,使用 acAll
而不是 acCurrent
作为第六个参数 (OnlyCurrentField) 到 DoCmd.FindRecord
.
FindRecord
将检查表单的控件,其中包括 txtSearch
。所以在调用 FindRecord
之前立即清除该文本框的值。否则,表单的 Record Source 中的每一行都将被解释为匹配项。发生这种情况是因为无法将 FindRecord
告诉 "look for a match in every control except txtSearch
."
如果您使用 Continuous Form 视图中的表单测试您的原始代码(暂时),该解释应该会更清楚。使用该代码,FindRecord
始终将您放在第一条记录中。然后DoCmd.FindNext
把你放在第二条记录上。
无论如何,这是在 Access 2010 中测试的代码,它可以满足您的需求。我使用了文本框的 After Update 事件而不是命令按钮。
Private Sub txtSearch_AfterUpdate()
Dim strSearch As String
If Not IsNull(Me!txtSearch.Value) Then
strSearch = Me!txtSearch.Value 'a text box where user enters search term
' txtSearch contains the search text ...
' so remove it to avoid matching the first (and every) record
Me!txtSearch.Value = Null
DoCmd.FindRecord FindWhat:=strSearch, _
Match:=acAnywhere, _
MatchCase:=False, _
Search:=acDown, _
SearchAsFormatted:=True, _
OnlyCurrentField:=acAll ' instead of acCurrent
' restore search text to text box
Me!txtSearch.Value = strSearch
End If
End Sub
我在单一表单视图中有一个装订表单。
我想模仿记录导航按钮中搜索框的行为,但也有更多的控制权。我面临的问题是,当我的用户搜索记录时,有时他们会在找到记录时不小心开始键入记录(比如在输入 3 或 4 个字母后他们仍在键入搜索词)并且原始数据丢失.由于这些字段有时需要输入数据,因此此时锁定它们并不是一个真正的选择。
我的想法是关闭导航按钮并通过 VBA 或通过宏来模拟此功能,并在找到要搜索的值时将焦点设置在另一个锁定的字段上(也可以选择查找下一个或提醒已找到或未找到的东西)。
我已经尝试使用宏和 VBA,但无法正常工作。
我有这段代码(并且稍微使用了一些参数),但它只会搜索当前记录(而不是所有记录)并且要么移动到下一条记录,要么根本没有记录,如果我发表评论FindNext
行。
Private Sub cmdFind_Click()
Dim sText As String
sText = Me.txtSearch 'a text box where user enters search term
DoCmd.FindRecord sText, acAnywhere, False, acDown, True, acCurrent
DoCmd.FindNext
End Sub
显然,我遗漏了一些东西。有人可以提供一些见解或替代方法。
我认为 HansUp 已经 post 找到了解决方案...但是由于我想出了一种不同的搜索方式(通过 RecordsetClone
和 FindFirst
),我会post 反正就是这样,说不定有用。 :)
Private Sub cmdFind_Click()
Static RS As Recordset
Static sText As String
Dim curText As String
Dim newSearch As Boolean
Dim sCrit As String
curText = Nz(Me.txtSearch)
If curText = "" Then Exit Sub
' If text hasn't changed, use FindNext
If curText = sText Then
newSearch = False
Else
sText = curText
newSearch = True
End If
' First call?
If RS Is Nothing Then
Set RS = Me.RecordsetClone
newSearch = True
End If
' The field you are searching in
sCrit = "[Text1] LIKE '*" & sText & "*'"
If newSearch Then
RS.FindFirst sCrit
Else
RS.FindNext sCrit
End If
If Not RS.NoMatch Then
' If found, navigate to the record
Me.Bookmark = RS.Bookmark
Else
MsgBox "No (more) matches)", vbInformation
End If
End Sub
您似乎想要查找 任何 字段与搜索文本匹配的第一条记录。
在那种情况下,使用 acAll
而不是 acCurrent
作为第六个参数 (OnlyCurrentField) 到 DoCmd.FindRecord
.
FindRecord
将检查表单的控件,其中包括 txtSearch
。所以在调用 FindRecord
之前立即清除该文本框的值。否则,表单的 Record Source 中的每一行都将被解释为匹配项。发生这种情况是因为无法将 FindRecord
告诉 "look for a match in every control except txtSearch
."
如果您使用 Continuous Form 视图中的表单测试您的原始代码(暂时),该解释应该会更清楚。使用该代码,FindRecord
始终将您放在第一条记录中。然后DoCmd.FindNext
把你放在第二条记录上。
无论如何,这是在 Access 2010 中测试的代码,它可以满足您的需求。我使用了文本框的 After Update 事件而不是命令按钮。
Private Sub txtSearch_AfterUpdate()
Dim strSearch As String
If Not IsNull(Me!txtSearch.Value) Then
strSearch = Me!txtSearch.Value 'a text box where user enters search term
' txtSearch contains the search text ...
' so remove it to avoid matching the first (and every) record
Me!txtSearch.Value = Null
DoCmd.FindRecord FindWhat:=strSearch, _
Match:=acAnywhere, _
MatchCase:=False, _
Search:=acDown, _
SearchAsFormatted:=True, _
OnlyCurrentField:=acAll ' instead of acCurrent
' restore search text to text box
Me!txtSearch.Value = strSearch
End If
End Sub