You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

源查询无结果时,如何访问Form.Textbox.Text属性?

Access连续表单搜索无结果时焦点丢失报错问题

我正在制作一个连续表单用于搜索,用户在多个搜索框中输入内容时,表单会自动更新。
在用户输入对应无匹配记录的参数前,代码运行正常。

当查询无结果时,我会收到以下错误提示:

"Can't use the property or method when the control doesn't have the focus"

我无法确定是表单中的哪个元素导致的问题,为文本框控件添加.SetFocus方法也没有效果。

请问有什么办法可以:

  1. 重新为文本框设置焦点并防止焦点丢失;或者
  2. 找出窃取焦点的元素并禁用它?

以下是在textbox_Change子过程中调用的RefreshTB子过程,我已添加了一个临时解决方法:

Private Sub RefreshTB(textbox As Control)
    'This is to prevent Acces from removing trailing spaces
    'If the textbox isn't empty and there is a space at the end, don't requery. This preserves trailing spaces as Access trims them on Me.requery
    If Len(textbox.Text) <> 0 And InStr(Len(textbox.Text), textbox.Text, " ", vbTextCompare) Then
        Exit Sub
    End If
    'If the last character isn't a space, requery on change to show new results of the query
    Me.Requery
    'The workaround: If the query returns no results, detect that, warn the user and clear search box. Requery to show some results again.
    If DCount("*", "DatasetsFilterQ") = 0 Then
        If MsgBox("No results found. The last TextBox you searched in will be cleared.", vbOKOnly, "No Records") = vbOK Then
            textbox = ""
            Me.Requery
        End If
        Exit Sub
    End If
    textbox.SetFocus
    textbox.SelStart = Len(Nz(textbox.Text))
End Sub

我尝试过使用过滤器,但在将.Text值传递给函数时遇到了相同的错误。


解决方案一:修正焦点设置逻辑

问题核心是Me.Requery执行后,无记录的连续表单会自动将焦点转移到导航按钮、空记录行控件等元素,导致原文本框失去焦点,后续.SetFocus因控件状态失效。调整代码如下:

Private Sub RefreshTB(textbox As Control)
    Dim txtName As String
    txtName = textbox.Name ' 提前记录文本框名称,避免控件对象失效
    
    ' 保留原尾空格判断逻辑
    If Len(textbox.Text) <> 0 And InStr(Len(textbox.Text), textbox.Text, " ", vbTextCompare) Then
        Exit Sub
    End If
    
    Me.Requery
    
    If DCount("*", "DatasetsFilterQ") = 0 Then
        If MsgBox("No results found. The last TextBox you searched in will be cleared.", vbOKOnly, "No Records") = vbOK Then
            Me(txtName) = ""
            Me.Requery
            DoEvents ' 等待表单状态更新完成
            ' 用控件名称重新设置焦点
            Me(txtName).SetFocus
            Me(txtName).SelStart = Len(Nz(Me(txtName).Text))
        End If
        Exit Sub
    End If
    
    DoEvents
    Me(txtName).SetFocus
    Me(txtName).SelStart = Len(Nz(Me(txtName).Text))
End Sub

解决方案二:定位并禁用抢焦点元素

通过日志记录焦点变化,找到窃取焦点的控件:

  1. 在表单模块添加全局变量:
Private lastFocusedControl As String
  1. 为表单添加焦点日志事件:
Private Sub Form_GotFocus()
    lastFocusedControl = Me.ActiveControl.Name
    Debug.Print "焦点转移到:" & lastFocusedControl ' 按Ctrl+G打开立即窗口查看日志
End Sub

触发无结果查询后,查看立即窗口记录的控件名称,针对性处理:

  • 若为导航按钮:在表单属性中设置NavigationButtons = No
  • 若为空记录行控件:设置控件TabStop = No,或无记录时隐藏
  • 若为其他控件:无结果时设Enabled = False,有结果时恢复

额外建议:用Filter替代Requery减少焦点异常

频繁Requery会导致表单频繁刷新,改用Filter可避免重新加载表单,更易保持焦点:

Private Sub RefreshTB(textbox As Control)
    Dim txtName As String
    txtName = textbox.Name
    Dim filterStr As String
    
    ' 根据你的查询逻辑构建过滤条件
    filterStr = "[目标字段名] Like '*" & Replace(textbox.Text, "'", "''") & "*'"
    
    ' 保留尾空格判断
    If Len(textbox.Text) <> 0 And InStr(Len(textbox.Text), textbox.Text, " ", vbTextCompare) Then
        Me.Filter = filterStr
        Me.FilterOn = True
        Exit Sub
    End If
    
    Me.Filter = filterStr
    Me.FilterOn = True
    
    If Me.Recordset.RecordCount = 0 Then
        If MsgBox("No results found. The last TextBox you searched in will be cleared.", vbOKOnly, "No Records") = vbOK Then
            Me(txtName) = ""
            Me.Filter = ""
            Me.FilterOn = False
            DoEvents
            Me(txtName).SetFocus
        End If
        Exit Sub
    End If
    
    DoEvents
    Me(txtName).SetFocus
    Me(txtName).SelStart = Len(Nz(Me(txtName).Text))
End Sub

内容的提问来源于stack exchange,提问作者T00Fast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 10:33:59