TextBox.SelStart为鼠标和键盘提供不同的值

时间:2019-04-11 00:42:32

标签: vba ms-access access-vba

我在TextBox上有一个Form。我在该.SelStart中使用TextBox属性获取光标位置。当我在TextBox单击时,它会按要求工作。然后,我使用该位置,通过按打印它们的字幕的相同形式的按钮光标位置上插入某些符号。

但是,如果我在TextBox中用键盘键入某些字符,则Selstart会返回0。即使我键入了多个字符并 cursor 明显位于文本末尾,SelStart仍为0。现在,如果我在其他 form 上打印 button ,则新字符始终在TextBox这不是我想要的。我希望即使在使用键盘键入内容时,也总是在光标位置打印字幕

这种行为非常令人困惑。有人可以帮忙吗?

Private LastPosition as Long  'declared in form module


Private sub t_LostFocus()     'to obtain last position in `TextBox`
    LastPosition = Me!t.SelStart
End Sub


Private Sub Insert()

Dim Text As String

   If LastPosition = 0 AND IsNull(Me!t.value) Then
      Me!t.Value = " " + Me.ActiveControl.Caption
      LastPosition = LastPosition + Len(Me.ActiveControl.Caption) + 1

   ElseIf LastPosition >=0 AND Not IsNull(Me!t.Value) Then
      Text = Me!t.Value
      Me!t.Value = Left(Text, LastPosition) & " " & Me.ActiveControl.Caption & Mid (Text, LastPosition + 1)
      LastPosition = LastPosition + Len(Me.ActiveControl.Caption)+1

   Else
      Me!t.Value = Me!t.Value + " " + Me.ActiveControl.Caption

   End If

End Sub

Private Sub button1_Click()
   Call Insert
End Sub

1 个答案:

答案 0 :(得分:1)

首先,有关在访问表单上输入数据的一些事实。需要分别理解这些内容,以正确解释问题中描述的行为,尤其是在尝试更改控件的默认行为时。

  • TextBox.SelStartSelLengthSelText仅在控件具有焦点时才有效。当TextBox控件再次获得焦点时,默认值为所有文本都被选中,因此SelStart = 0且SelLength = Text属性的长度。使用鼠标并在特定字符位置单击TextBox时,将绕过默认行为,并按预期将光标置于鼠标光标上。
  • TextBox控件同时具有Text属性和Value属性。 Text属性代表在控件中显示的文本字符串。显示的文本可以不同于控件表示的基础值,尤其是在Value是非文本数据类型的情况下(例如,整数存储为数字,但表示为单个文本数字)。 Value属性返回一个VBA变体,该变体本身保存 specific 数据类型的基础值。
    • 对于绑定控件(即,填充了ControlSource属性),Value数据类型将与绑定源列相同。
    • 对于未绑定控件(即ControlSource为空),Value数据类型由TextBox.Format属性决定。如果Format为空,则数据类型为text,并将有效匹配Text属性。
    • TextValue并不总是同步的,当控件具有焦点并正在编辑时尤其如此。当文本由表单用户编辑(即不是通过代码)时,Value不会更新,直到控件失去焦点或 Shift + Enter 保存表单为止(除非Enter关键行为已更改)。大多数将更新控件的事件还将涉及单击或以其他方式将焦点移到控件外部,例如保存记录,将焦点更改为另一个控件等。
      • 更新控件的Value时,将解释显示的文本(可通过Text属性访问)和/或将其转换为适当的数据类型,然后将其保存到{{1 }}属性。 (有时,通过将“值”重新格式化为Value属性中指定的表示形式,继续进行同步。例如,如果Format则:输入为“ 4-12-19”的文本->已更新价值:#4/12/19 00:00#→更新文本:“ 2019年4月12日,星期五”。

我要讲的最后一个重要事实:

  • 更新Format = Long Date属性(即使它也是String数据类型)也会刷新TextBox.Value属性,并且光标位置和重置文本选择,以便选择整个文本。换句话说,Text设置为0且SelStart设置为SelLength的长度,就像TextBox新获得焦点时所观察到的行为(如上文第一点所述) )。

最后是所有这些细节的症结所在

  • 使用键盘更改文本时,这最终将触发更新,但通常直到控件失去焦点时才会触发更新。但是,当发生这样的更新时,它发生在 LostFocus事件之前,并且如上所述重置了文本选择,因此在Text事件处理程序中,LostFocus == 0 。
  • 问题实际上不在于键盘和鼠标之间,而在于更改或未更改的控制文本之间。如果在文本框中仅使用箭头键,则光标位置和文本选择为保留在LostFocus事件中,因为尚未发生控件更新。相反,如果使用鼠标更改文本(例如,右键单击“粘贴”),这也会触发更新,该更新将重置选择。实际上,如果人们以任何方式更改文本,然后使用箭头键或鼠标单击,仍然会发生更新,并重置光标位置和文本选择。
    • 如果将焦点移到文本框之外,然后使用鼠标又将其移回,则可能发生了更新,但是鼠标随后将设置光标位置。我只提到这一点是为了意识到可能在不知情的情况下造成的误点击,从而导致更新,并且仍然给人一种鼠标具有独特行为的错觉。
  • 要获得踢动,请按 Shift + Enter 强制进行更新,但要保持对控件的关注,并观察到所有文本均被自动选中。

通过在各种事件中放置一些“记录”语句来跟踪代码是值得的,以便您可以观察它们的发生时间和顺序。


SelStart