Сначала несколько фактов о вводе данных в форму доступа.Это необходимо понимать отдельно, чтобы правильно объяснить поведение, описанное в вопросе, и особенно, если кто-то пытается изменить поведение элемента управления по умолчанию.
-
TextBox.SelStart
, SelLength
и SelText
доступны и действительны только тогда, когда элемент управления имеет фокус.Когда элемент управления TextBox снова получает фокус, по умолчанию выбирается весь текст, поэтому SelStart
= 0 и SelLength
= длина свойства Text
.При использовании мыши и щелчке на TextBox в определенной позиции символа поведение по умолчанию игнорируется, и курсор помещается на курсор мыши, как и ожидалось. - Элементы управления TextBox имеют как свойство
Text
, так иValue
собственность.Свойство Text
представляет текстовую строку, отображаемую в элементе управления.Отображаемый текст может отличаться от базового значения, которое представляет элемент управления, особенно если Value
является нетекстовым типом данных (например, целое число хранится как число, но представляется как отдельные текстовые цифры).Свойство Value
возвращает вариант VBA, который сам содержит базовое значение определенного типа данных . - Для привязанного элемента управления (т. Е. Заполнено свойство
ControlSource
) тип данных Value
будет таким же, как столбец связанного источника. - Для несвязанного элемента управления (т.е.
ControlSource
- пусто), тип данных Value
определяется свойством TextBox.Format
.Если Format
пусто, то тип данных является текстовым и будет эффективно соответствовать свойству Text
. Text
и Value
не всегда синхронизируются, и это особенно верно, когда элемент управления имеет фокуси редактируется.Когда текст редактируется пользователем формы (т.е. не из кода), Value
не обновляется до тех пор, пока элемент управления не потеряет фокус, или Shift + Enter не сохранит форму (кроме случаев, когда поведение клавиши Enter имеетбыли изменены).Большинство событий, которые обновят элемент управления, также включают щелчок или иное перемещение фокуса вне элемента управления , например сохранение записи, изменение фокуса на другой элемент управления и т. Д. - Когда элемент управления
Value
обновляется, отображаемый текст - доступный через свойство Text
- интерпретируется и / или преобразуется в соответствующий тип данных, который затем сохраняется в свойстве Value
.(Иногда синхронизация продолжается, переформатируя «Значение» обратно в представление, указанное в свойстве Format
. Например, если Format = Long Date
, то: текст вводится как «4-12-19» -> обновленное значение: # 4/ 12/19 00: 00 # → обновленный текст: «Пятница, 12 апреля 2019 года».
Один важный последний факт, прежде чем я доберусь доточка:
- Когда свойство
TextBox.Value
обновляется - даже если это также тип данных String - свойство Text
также обновляется и положение курсора и выбор текста сбрасываются , так что весь текст выделяется. Другими словами, SelStart
устанавливается на 0, а SelLength
устанавливается на длину Text
, так же, как поведение, наблюдаемое приTextBox вновь получает фокус (как упомянуто в первом пункте выше).
Наконец, суть всей этой детали :
- Когдаклавиатура используется для изменения текста, это в конечном итоге вызовет обновление, но обычно не доКонтроль теряет фокус.Но когда происходит такое обновление, оно происходит за до события LostFocus и выбор текста сбрасывается, как описано выше, так что в обработчике
LostFocus
, SelStart
== 0. - Theпроблема на самом деле не между клавиатурой и мышью, а между изменяемым или неизменяемым текстом элемента управления. Если в текстовом поле используются только клавиши со стрелками, то положение курсора и выбор текста сохраняются в событии LostFocus, поскольку элемент управленияобновление не произошло.Наоборот, если мышь используется для изменения текста (например, нажатие правой кнопкой мыши на Вставить), это также вызывает обновление, которое сбрасывает выделение.Фактически, если кто-либо изменяет текст каким-либо образом, а затем использует клавиши со стрелками или щелчки мыши, все равно будет происходить обновление и сбрасывается положение курсора и выбор текста.
- Если фокус перемещается за пределы текстового поля, а затем снова с помощью мыши, возможно, произошло обновление, но мышь впоследствии установит позицию курсора.Я упоминаю об этом только для того, чтобы знать о случайных щелчках, которые могут не знать об обновлении и создавать иллюзию уникального поведения мыши.
- Для ударов нажмите Shift+ Введите для принудительного обновления, но сохраните фокус на элементе управления и обратите внимание, что весь текст выбирается автоматически.
Стоит отследить код, поместив некоторые операторы «logging» вразличные события, так что вы можете наблюдать, когда они происходят и порядок.
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