Excel это не сложно
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
28.03.2024, 23:56:25

Войти
Интересные и полезные статьи по работе с Excel и VBA можно найти в разделе ХИТРОСТИ
33 233 Сообщений в 5 454 Тем от 6 750 Пользователей
Последний пользователь: Alex1210
*
Перейти на сайт Хитрости Надстройка MulTEx Обучающие тренинги Наша группа ВКонтакте
Правила форума Начало Помощь Поиск Календарь Войти Регистрация Выйти
+  Excel это не сложно
|-+  Основные форумы
| |-+  Вопросы по Excel и VBA
| | |-+  Вопрос по контролю ввода с помощью VBScript.RegExp
Страниц: [1]   Вниз
Печать
Автор Тема: Вопрос по контролю ввода с помощью VBScript.RegExp  (Прочитано 3457 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Muskin2029
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 28


Просмотр профиля
« : 01.07.2020, 14:17:19 »

Всем привет!
На форме имеется несколько полей TextBox для ввода чисел.
Конкретно - в поле t_OffsetY ввод контролируется так:
Код: (vb)
Private Sub t_OffsetX_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

       With CreateObject("VBScript.RegExp")
           .Pattern = "^[-]?[1-9]?[0-9]?$"
           If Not .Test(t_OffsetX.Value & Chr(KeyAscii)) Then KeyAscii = 0
       End With

End Sub
При отсутствии начального значения в t_OffsetX (пустое поле) всё отрабатывается нормально.
При заданном начальном значении поля t_OffsetX и при переходе на это поле по Tab поле выделяется и необходимо нажать Backspace, чтобы произвести ввод.
Что необходимо добавить именно в .Pattern, чтобы не использовать Backspace, т.е. выделение затиралось бы при вводе (-) и/или чисел?
Записан

Win10x64, MSO 2016
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 828



Просмотр профиля WWW
« Ответ #1 : 01.07.2020, 14:39:57 »

Если честно - ничего не понял. Почему нельзя использовать событие KeyDown для определения кода клавиши? И причем здесь вообще RegExp, если хотите что-то затирать клавишей?
Можете как-то иначе попробовать пояснить задачу?
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Muskin2029
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 28


Просмотр профиля
« Ответ #2 : 01.07.2020, 15:11:52 »

Попытаюсь попроще описать.
В поле t_OffsetX должно вводиться значение от 0 до 99, может быть со знаком -.
Это же поле t_OffsetX имеет начальное значение 20.
Если перейти на это поле по Tab, число 20 выделяется, ввод по шаблону "^[-]?[1-9]?[0-9]?$" невозможен, пока не затереть это выделение.
Почему RegExp? - да просто удобно и коротко.
Записан

Win10x64, MSO 2016
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 828



Просмотр профиля WWW
« Ответ #3 : 01.07.2020, 16:00:15 »

имеет начальное значение 20
А зачем оно нужно, если его надо затирать в итоге? Я не очень понимаю все равно манипуляции. Почему просто не запретить ввод ненужного и оставить только ввод по шаблону? Например, так:
Код: (vb)
Private Sub t_OffsetX_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Dim ore As Object
    Set ore = CreateObject("VBScript.RegExp")
    With CreateObject("VBScript.RegExp")
        .Pattern = "[-]?\d{0,2}"
        If .Replace(t_OffsetX.Value & Chr(KeyAscii), "") <> "" Then KeyAscii = 0
    End With
End Sub
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Muskin2029
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 28


Просмотр профиля
« Ответ #4 : 01.07.2020, 17:37:11 »

А зачем оно нужно, если его надо затирать в итоге? Я не очень понимаю все равно манипуляции.
В поле t_OffsetX указано начальное значение, например, 20.
С предыдущего поля по Tab перескакиваем на t_OffsetX, число 20 полностью выделяется.
Если по каким-то условиям его менять не нужно - жмём Tab и перескакиваем на следующее поле.
Но если 20 нужно изменить, выделение нужно затереть, чтобы ввести в соответствие с шаблоном новое число.
Так как избежать этого затирания (BackSpace)?
Если не использовать RegExp (обычный ввод без контроля), то при переходе на t_OffsetX при наборе первого же символа выделение затирается автоматически.
Записан

Win10x64, MSO 2016
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 828



Просмотр профиля WWW
« Ответ #5 : 01.07.2020, 18:48:07 »

Так как избежать этого затирания
Никак. И уж точно не при помощи RegExp. Какая разница используете Вы его или нет - если в событии Вы не предотвращаете нажатие клавиши BackSpace, то и действие её тоже нельзя предотвратить. Я изначально написал - для отслеживания нажатия клавиш используйте KeyDown. Ну вроде того:
Код: (vb)
Private Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = 8 Then
        KeyCode = 0
    End If
End Sub

а что в итоге надо я все равно не понял, уж извините. Вы можете забыть про RegExp и написать каким видите правильное поведение при переходе Tab-ом на текстбокс и вводе без BackSpace и с ним данных?

P.S. Вы мой-то код пробовали? Ему вообще фиолетово как Вы там вводите - затирая сначала или нет, все обрабатывается по шаблону правильно.
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Muskin2029
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 28


Просмотр профиля
« Ответ #6 : 01.07.2020, 19:24:28 »

P.S. Вы мой-то код пробовали?
Ну да, его и буду использовать.
Ему вообще фиолетово как Вы там вводите - затирая сначала или нет, все обрабатывается по шаблону правильно.
У меня почему-то не фиолетово - при выделенном поле шаблон не срабатывает, приходится всё-таки затирать.
Обнаружил ещё одну неприятность.
Допустим, перепрыгиваю на это поле, там стоит число 20, выделенное. Стрелкой влево иду в начало числа, чтобы поставить минус - шаблон не срабатывает, тут уже приходится использовать Delete и всё-равно очищать всё поле.
Придётся, наверно, действительно использовать _KeyDown, хотя If-ов и по прибавится.
Записан

Win10x64, MSO 2016
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 828



Просмотр профиля WWW
« Ответ #7 : 01.07.2020, 19:42:16 »

Стрелкой влево иду в начало числа, чтобы поставить минус - шаблон не срабатывает
логично. Вы же всегда ПОСЛЕ текста добавляете новый вводимый символ:
TextBox2.Value & Chr(KeyAscii)
Вам надо обрабатывать определение позиции вводимого символа и составлять корректную будущую строку для проверки шаблоном:
Код: (vb)
Private Sub t_OffsetX_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Dim ore As Object
    Dim s$, ls&, txt$
   
    Set ore = CreateObject("VBScript.RegExp")
    With CreateObject("VBScript.RegExp")
        .Pattern = "[-]?\d{0,2}"
        ls = t_OffsetX.SelStart
        txt = t_OffsetX.Value
        If ls = 0 Then
            s = Chr(KeyAscii) & txt
        Else
            s = Mid(txt, 1, ls) & Chr(KeyAscii) & Mid(txt, ls + 1, Len(txt) - 1)
        End If
        If .Replace(s, "") <> "" Then KeyAscii = 0
    End With
End Sub

Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Muskin2029
Новичок
*

Репутация: +0/-0
Офлайн Офлайн

Сообщений: 28


Просмотр профиля
« Ответ #8 : 05.07.2020, 11:47:20 »

Дмитрий, спасибо за пример, однако есть моменты, когда он не срабатывает.
При первом попадании на поле t_OffsetX Tab-ом вводятся только отрицательные числа, положительные - стопор.
После ухода с этого поля, а затем возврата на него c помощье Shift+Tab или выделения его мышкой ввод любых чисел не возможен.
После небольшой паузы, написал такой вот код:
Код: (vb)
Private Sub t_OffsetX_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
   
  With CreateObject("VBScript.RegExp")
       .Pattern = "^(0|-$|-?[1-9]\d{0,2})$"
       txt = t_OffsetX.Value
       char_k = Chr(KeyAscii)
       sel_Text = t_OffsetX.SelText
       If sel_Text <> Empty Then    ' полное или частичное выделение
          If Not .Test(Replace(txt, sel_Text, char_k)) Then KeyAscii = 0
        Else                        ' выделения нет
          ls = t_OffsetX.SelStart
          If Not .Test(Mid(txt, 1, ls) & char_k & Mid(txt, ls + 1, Len(txt))) Then KeyAscii = 0
       End If
  End With

End Sub
Заменил шаблон для исключения при вводе ненужных нолей (-0, -012, 007 и т.п.).
Записан

Win10x64, MSO 2016
Страниц: [1]   Вверх
Печать
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Яндекс.Метрика Рейтинг@Mail.ru