我在TextBox
上有一个Form
。我使用.SelStart
中的TextBox
属性获取光标位置。当我在TextBox
中单击时,它可以按需要运行。然后我使用该位置通过按下打印其标题的同一表格上的按钮在光标位置上插入某些符号。
但是,如果我在TextBox
中用键盘键入一些字符,则Selstart
返回0.即使我键入了几个字符并且光标明显位于文本的末尾,SelStart
仍为0.现在,如果我在其他表单上打印按钮,则新字符总是在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
首先是关于访问表单上数据输入的一些事实。这些需要单独理解,以正确解释问题中描述的行为,特别是如果一个人试图改变控件的默认行为。
TextBox.SelStart
,SelLength
和SelText
仅在控件具有焦点时才可用且有效。当TextBox控件再次获得焦点时,默认选择所有文本,以便SelStart
= 0和SelLength
= Text
属性的长度。当使用鼠标并在特定字符位置单击TextBox时,将绕过默认行为,并按预期将光标放在鼠标光标处。Text
属性和Value
属性。 Text
属性表示在控件中显示的文本字符串。显示的文本可以与控件表示的基础值不同,尤其是如果Value
是非文本数据类型(例如,整数存储为数字,但表示为单独的文本数字)。 Value
属性返回VBA变体,该变体本身保存特定数据类型的基础值。
对于绑定控件(即填充了ControlSource
属性),Value
数据类型将与绑定源列相同。
对于未绑定的控制(即ControlSource
为空白),Value
数据类型由TextBox.Format
属性决定。如果Format
为空,则数据类型为文本,并且将有效地匹配Text
属性。
Text
和Value
并不总是同步,当控件具有焦点并且正在编辑时尤其如此。当表单用户编辑文本时(即不是代码),Value
不会更新,直到控件失去焦点或Shift + Enter保存表单(除非Enter键行为已被更改)。大多数将更新控件的事件还将涉及单击或以其他方式将焦点移动到控件之外,例如保存记录,将焦点更改为另一个控件等。
当控件的Value
更新时,显示的文本 - 可通过Text
属性访问 - 被解释和/或转换为适当的数据类型,然后保存到Value
属性。 (有时通过将'Value'重新格式化为Format
属性中指定的表示来继续同步。例如,如果Format = Long Date
则:文本输入为“4-12-19” - >更新值:#4/12/19 00:00#→更新文字:“2019年4月12日星期五”。在我谈到这一点之前的一个重要的最后事实:
TextBox.Value
属性时 - 即使它也是String数据类型 - 也会刷新Text
属性并重置光标位置和文本选择,以便选择整个文本。换句话说,SelStart
设置为0,SelLength
设置为Text
的长度,就像TextBox新接收焦点时观察到的行为(如上面第一点所述)。最后到了所有这些细节的关键:
LostFocus
事件处理程序中,SelStart
== 0。通过在各种事件中放置一些“日志记录”语句来跟踪代码是值得的,这样您就可以观察它们何时发生以及顺序。
Option Explicit
Option Compare Database
Dim LastSelStart As Integer
Dim LastSelLength As Integer
Dim UpdateSelStart As Integer
Dim UpdateSelLength As Integer
Private Sub button1_Click()
Insert
End Sub
Private Sub button2_Click()
Insert
End Sub
Private Sub Form_Load()
LastSelStart = -1
LastSelLength = 0
ResetUpdateSelValues
End Sub
Private Sub ResetUpdateSelValues()
UpdateSelStart = -1
UpdateSelLength = 0
End Sub
Private Sub t_AfterUpdate()
On Error Resume Next
UpdateSelStart = Me.t.SelStart
UpdateSelLength = Me.t.SelLength
If Err.Number <> 0 Then
UpdateSelStart = -1
End If
End Sub
Private Sub t_GotFocus()
On Error Resume Next
If LastSelStart >= 0 Then
Me.t.SelStart = LastSelStart
Me.t.SelLength = LastSelLength
End If
End Sub
Private Sub t_LostFocus()
LastSelStart = Me.t.SelStart
LastSelLength = Me.t.SelLength
If LastSelStart = 0 And UpdateSelStart > 0 Then
LastSelStart = UpdateSelStart
LastSelLength = UpdateSelLength
End If
ResetUpdateSelValues
End Sub
Private Sub Insert()
Dim caption As String
caption = Me.ActiveControl.caption
If IsNull(Me.t.Value) Then
Me.t.Value = caption
LastSelStart = Len(caption)
LastSelLength = 0
Else
Dim Text As String
Text = Me.t.Value
If LastSelStart = 0 Then
'* Don't add extra space at beginning
Text = caption & Mid(Text, LastSelLength + 1)
'Text = caption & Text
LastSelStart = Len(caption)
LastSelLength = 0
ElseIf LastSelStart > 0 Then
Text = Left(Text, LastSelStart) & " " & caption & Mid(Text, LastSelStart + LastSelLength + 1)
'Text = Left(Text, LastSelStart) & " " & caption & Mid(Text, LastSelStart + 0 + 1)
LastSelStart = LastSelStart + 1 + Len(caption)
LastSelLength = 0
Else
'If last cursor position is invalid, append characters
Text = Text & " " & caption
LastSelStart = Len(Text)
LastSelLength = 0
End If
t.Value = Text
End If
Me.t.SetFocus
End Sub