访问以单一形式搜索所有记录

Posted

技术标签:

【中文标题】访问以单一形式搜索所有记录【英文标题】:Access Search All Records in a Single Form 【发布时间】:2016-02-24 15:34:16 【问题描述】:

我在单一表单视图中有一个绑定表单。

我想模仿记录导航按钮中搜索框的行为,但也有更多的控制权。我面临的问题是,当我的用户搜索记录时,有时他们会在找到记录时不小心开始输入记录(例如在输入 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

显然,我错过了一些东西。有人可以提供一些见解或替代方法。

【问题讨论】:

您在什么情况下运行此代码?如果它在txtSearch_Change() 中,您将需要Me.txtSearch.Text 而不是Me.txtSearch(即Me.txtSearch.Value),因为在您离开控件之前不会设置.Value。 -- 尽管在使用空搜索文本调用 DoCmd.FindRecord 时出现运行时错误。 -- 编辑:要找出这是否是问题所在,请在分配后添加Debug.Print sText 如果可以只显示包含搜索文本匹配的行,请使用表单的Filter 属性。 @Andre - 谢谢。我更新了我的答案。我通过单击按钮调用它。 sText 不为空。 @HansUp。谢谢,但表格不在数据表视图中。它是具有自定义布局的 SingleForm。 如果你在DoCmd.FindRecord 之前执行Me!txtSome_field.SetFocus,那么如果有匹配项,那应该将你放在txtSome_field 匹配txtSearch 的第一条记录中。如果有多个匹配项,DoCmd.FindNext 将带您到第二个匹配记录。那是你要的吗? (对不起,我迷路了。) 【参考方案1】:

我认为 HansUp 已经发布了解决方案……但由于我想出了一种不同的搜索方式(通过 RecordsetCloneFindFirst),我还是会发布它,也许它有用。 :)

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

【讨论】:

谢谢安德烈。这肯定让我快到了。我需要搜索多个字段,但我可以将此代码重构为 :)【参考方案2】:

您似乎想找到 any 字段与搜索文本匹配的第一条记录。

在这种情况下,使用acAll 而不是acCurrent 作为DoCmd.FindRecord 的第六个参数(OnlyCurrentField)。

FindRecord 将检查表单的控件,其中包括txtSearch。因此,在调用FindRecord 之前立即清除该文本框的值。否则,表单的记录源中的每一行都将被解释为匹配项。发生这种情况是因为没有办法告诉FindRecord “在除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

【讨论】:

感谢 HansUp。是的,我遇到了让它总是找到txtSearch 框的问题。我很欣赏我原来的方法的清理版本。是的,我确实想要 acAll 并且最初拥有它(打算改回来)。

以上是关于访问以单一形式搜索所有记录的主要内容,如果未能解决你的问题,请参考以下文章

我如何以表格形式查看 ms 访问表单中的所有插入数据

从子窗体访问去记录

通过连续形式访问循环

搜索后未找到访问表单记录源

访问查询以包含所有记录,即使一个字段缺少数据(为 Null)

访问连续表单:记录状态