Хобрук: Ваш путь к мастерству в программировании

Ограничить ввод текста в текстовое поле

Вот что я хочу сделать, и у меня есть проблема. Я хочу ограничить то, что пользователь вводит в определенные текстовые поля. Я хочу, чтобы он печатал только цифры, но после 3 цифр добавлял ";". (например, 007;123;003;005;).

Проблема в том, что мои элементы управления текстовым полем генерируются с помощью кода. Поэтому я не могу или не знаю, как установить действие для этих элементов управления.

Код, который я использую для создания элементов управления:

Set cControl = form.Controls("io" & masina).Add(
    "Forms.Label.1", "lreper" & l & pagina, True) 

With cControl 
    .Caption = "Reper" 
    .Width = 35 
    .Height = 9 
    .Top = 25 + k 
    .Left = 5 
End With

Любые идеи?

Большое спасибо!

04.08.2011

  • Не могли бы вы быть немного более конкретным обо всем? 04.08.2011
  • да. У меня есть форма с 3 текстовыми полями. Кто-то должен ввести в эти текстовые поля серийные номера некоторых продуктов. Проблема в том, что они иногда добавляют текст или используют только 2 цифры вместо 3 для серийного номера (например, 03 вместо 003) и так далее. Поэтому я хочу ограничить то, что они вводят в эти текстовые поля... если они не добавят 3 числа, появится всплывающее окно, чтобы сообщить им, как выглядит правильный SN. Также я хочу после каждых 3 чисел добавить ;. Вот и все. Это достаточно конкретно? Спасибо! 05.08.2011

Ответы:


1

Вы можете использовать событие нажатия клавиши, чтобы ограничить только цифры и «;». Вместе с условиями проверки.

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

    Select Case KeyAscii
        '// Numbers 0-9
        Case 48 To 57
            If Len(TextBox1.Text) = 3 And Right(TextBox1.Text, 3) Like "###" Then
                KeyAscii = 0
                GoTo DisplayFormatError
            End If
        '//  Key ;
        Case 59
            If Len(TextBox1.Text) < 3 Or Not Right(TextBox1.Text, 3) Like "###" Then
                KeyAscii = 0
                GoTo DisplayFormatError
            End If
        Case Else
            KeyAscii = 0
            GoTo DisplayFormatError
    End Select

    Exit Sub

DisplayFormatError:
    MsgBox "Please enter serial number in the format '000;000;000'", vbInformation, "Alert!"
End Sub

Лучше использовать регулярное выражение вместо аналогичного метода.

Если вам нужна помощь в добавлении событий для ваших элементов управления во время выполнения, посмотрите:

Добавить элементы управления и события для формирования во время выполнения

РЕДАКТИРОВАНИЕ (ЗАПРОС ОТ TIAGO)

Динамическое создание пользовательской формы и текстового поля с событием нажатия клавиши. Использует модифицированный пример приведенной выше ссылки. Кредит оригинальному автору.

Добавить ссылку. В разделе «Доступные ссылки» нажмите «Microsoft Visual Basic для расширяемости приложений» и нажмите «ОК».

Option Explicit
Sub MakeForm()
    Dim TempForm As Object ' VBComponent
    Dim FormName As String
    Dim NewTextBox As MSForms.TextBox
    Dim TextLocation As Integer
    Dim TextBoxName As String

    '** Additional variable
    Dim X As Integer

    'Locks Excel spreadsheet and speeds up form processing
    Application.VBE.MainWindow.Visible = False
    Application.ScreenUpdating = False

    'Create the UserForm
    Set TempForm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)

    'Set Properties for TempForm
    With TempForm
        .Properties("Caption") = "Temporary Form"
        .Properties("Width") = 200
        .Properties("Height") = 100
    End With

    FormName = TempForm.Name

    TextBoxName = "MyTextBox"

    'Add a CommandButton
    Set NewTextBox = TempForm.Designer.Controls _
      .Add("Forms.TextBox.1")

    With NewTextBox
        .Name = TextBoxName
        .Left = 60
        .Top = 40
    End With

    'Add an event-hander sub for the CommandButton
    With TempForm.CodeModule

    '** Add/change next 5 lines
    'This code adds the commands/event handlers to the form
        X = .CountOfLines
        .InsertLines X + 1, "Private Sub " & TextBoxName & "_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)"
        .InsertLines X + 2, "KeyAscii = KeyPress(" & TextBoxName & ".Text, KeyAscii)"
        .InsertLines X + 3, "End Sub"
    End With

    'Show the form
    VBA.UserForms.Add(FormName).Show

    'Delete the form
    ThisWorkbook.VBProject.VBComponents.Remove VBComponent:=TempForm
End Sub

Public Function KeyPress(ByVal strText As String, ByVal KeyAscii As Integer) As Integer

    Select Case KeyAscii
        '// Numbers 0-9
        Case 48 To 57
            If Len(strText) = 3 And Right(strText, 3) Like "###" Then
                GoTo DisplayFormatError
            End If
        '//  Key ;
        Case 59
            If Len(strText) < 3 Or Not Right(strText, 3) Like "###" Then
                GoTo DisplayFormatError
            End If
        Case Else
            GoTo DisplayFormatError
    End Select

    KeyPress = KeyAscii

    Exit Function

DisplayFormatError:
    KeyPress = 0
    MsgBox "Please enter serial number in the format '000;000;000'", vbInformation, "Alert!"
End Function

ДРУГОЙ МЕТОД (с использованием класса обработчика событий)

Код в пользовательской форме:

Private colEventHandlers As Collection
Private Sub UserForm_Initialize()   

    '// New collection of events
    Set colEventHandlers = New Collection

    '// Add dynamic textbox
    Set tbxNewTextbox = Me.Controls.Add("Forms.TextBox.1", "MyNewTextbox", True)

    With tbxNewTextbox
        .Top = 25
        .Left = 5
    End With

    '//  Add the event handler
    Dim objEventHandler As TextboxEventHandler
    Set objEventHandler = New TextboxEventHandler

    Set objEventHandler.TextBox = tbxNewTextbox

    colEventHandlers.Add objEventHandler  


End Sub

И добавьте модуль класса и тоже переименуйте его в «TextBoxEventHandler», затем добавьте следующий код:

Private WithEvents tbxWithEvent As MSForms.TextBox
Public Property Set TextBox(ByVal oTextBox As MSForms.TextBox)
    Set tbxWithEvent = oTextBox
End Property

Private Sub tbxWithEvent_Change()

End Sub

Private Sub tbxWithEvent_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

    Select Case KeyAscii
        '// Numbers 0-9
        Case 48 To 57
            If Len(tbxWithEvent.Text) = 3 And Right(tbxWithEvent.Text, 3) Like "###" Then
                GoTo DisplayFormatError
            End If
        '//  Key ;
        Case 59
            If Len(tbxWithEvent.Text) < 3 Or Not Right(tbxWithEvent.Text, 3) Like "###" Then
                GoTo DisplayFormatError
            End If
        Case Else
            GoTo DisplayFormatError
    End Select

    Exit Sub

DisplayFormatError:
   KeyAscii = 0
    MsgBox "Please enter serial number in the format '000;000;000'", vbInformation, "Alert!"
End Sub
10.08.2011
  • +1! Код, который, как я сказал, не работал, был не динамическими формами, а средством форматирования в ###;###;###. Я смог добавить ####. В любом случае, спасибо за подробное объяснение динамических элементов управления! 12.08.2011
  • Спасибо, да, я понял, что вы говорили о форматере, но у меня он работает - я не могу добавить 4 нуля. Извините, я не уверен, почему это не работает для вас. В любом случае, надеюсь, это решит проблему OP с динамическим управлением. Ваше здоровье. 12.08.2011
  • Отличный выстрел! Спасибо за объяснение ›› заслуживает как минимум +1, кстати 12.08.2011

  • 2

    Попробуйте Dataannotations/метаданные

    Подробнее здесь: http://msdn.microsoft.com/en-us/library/ee256141.aspx

    11.08.2011

    3

    Насколько я понимаю, нет способа справиться с этим до ввода пользователем.

    Тем не менее, вы можете использовать событие TextBox_Exit для последующего форматирования. Вы можете адаптировать этот пример кода.

    05.08.2011
  • Вы хорошо поняли... Я хочу увидеть, что они печатают вживую... если они напечатают букву, появится MsgBox, сообщающий им, как правильно писать в этом текстовом поле. 05.08.2011
  • @Andrei Lion: Не могли бы вы использовать событие TextBox_Change для проверки букв при вводе пользователем? Я понимаю, что вы не можете сделать трехзначную проверку таким образом, но это, кажется, решает половину проблемы. 05.08.2011
  • @Excellll Я не могу использовать TextBox_Change, потому что текстовые поля добавляются не с помощью перетаскивания, а с помощью небольшого фрагмента кода. Установите cControl = form.Controls(io & masina).Add(Forms.Label.1, lreper & l & pagina, True) With cControl .Caption = Reper .Width = 35 .Height = 9 .Top = 25 + k .Left = 5 Конец с 06.08.2011
  • @ Андрей, добавьте эту информацию, которую вы прокомментировали выше, в свой вопрос. Ваш вопрос слишком расплывчатый, чтобы получить от нас больше помощи, чем та, которую вы уже получили. 11.08.2011
  • Кстати, приведенный выше код добавляет Label вместо TextBox. 11.08.2011

  • 4

    Хотя я бы никогда не использовал динамические элементы управления, если только это не требовалось строго, я был озадачен этим вопросом... так что я думаю об этом как о вызове. :-)

    Погуглил, и большинство ответов попадают в одно и то же решение, однако большинство из них также содержат комментарий «Я не мог заставить это работать», включая этот здесь, в SO Назначить функцию VBA по щелчку для динамически созданной кнопки в пользовательской форме Excel.

    Вот код, который я создал... который явно не работает, иначе я бы сказал, что он может быть решением. Проблема в том, что метод нажатия клавиш, который он создает динамически, не вызывается, когда должен быть. Чтобы проверить это, просто вставьте код в форму VBA с именем «myForm».

    Я оставил TextBox1_KeyPress только в целях тестирования, чтобы доказать удобство использования валидатора текстового поля (извините, @Readfidy, ваш код не сработал, как я ожидал. Я смог добавить более 3 чисел подряд) .

    Если кто-то еще заинтересован в том, чтобы этот код работал... Буду рад поблагодарить ;-)

    Option Explicit
    
    Private Sub UserForm_Activate()
    
        Dim sTextBoxName As String
        Dim cControl As MSForms.TextBox
        Dim sMetaFunction As String
        Dim CodeModule
    
        sTextBoxName = "lreper"
    
        Set cControl = myForm.Controls.Add("Forms.TextBox.1", sTextBoxName, True)
    
        With cControl
            .Top = 25
            .Left = 5
        End With
    
        sMetaFunction = "Private Sub " & sTextBoxName & "_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)" & vbCrLf & _
            vbCrLf & _
            vbTab & "Set KeyAscii = EvaluateText(myForm.Controls(" & sTextBoxName & "), KeyAscii)" & vbCrLf & _
            vbCrLf & _
            "End Sub"
    
        Set CodeModule = ActiveWorkbook.VBProject.VBComponents.VBE.ActiveCodePane.CodeModule
        CodeModule.InsertLines 60, sMetaFunction
    
    End Sub
    
    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    
        Set KeyAscii = EvaluateText(myForm.Controls("TextBox1"), KeyAscii)
    
    End Sub
    
    Private Function EvaluateText(ByRef oTextBox As MSForms.TextBox, ByVal KeyAscii As MSForms.ReturnInteger) As MSForms.ReturnInteger
    
        If ((Len(oTextBox.Text) + 1) / 4 = CInt((Len(oTextBox.Text) + 1) / 4)) Then
    
            If KeyAscii <> 59 Then KeyAscii = 0
    
        Else
    
            If KeyAscii < 48 Or KeyAscii > 57 Then KeyAscii = 0
    
        End If
    
        If KeyAscii = 0 Then
    
            MsgBox "Please enter serial number in the format '000;000;000'", vbInformation, "Alert!"
    
        End If
    
    End Function
    
    11.08.2011
  • Я не уверен, почему у вас возникли проблемы с моим кодом, но я снова протестировал его в Office 2010, и он работает нормально, попытка добавить 4 нуля подряд приводит к отображению окна msgbox. Пожалуйста, смотрите редактирование в моем исходном посте для примера использования динамических элементов управления. Динамические элементы управления, безусловно, работают, и я использовал их много раз в прошлом. В некоторых случаях динамические элементы управления могут быть очень полезны, но я также стараюсь их избегать. 12.08.2011

  • 5

    ИСПОЛЬЗУЙТЕ ЭТОТ КОД: КЛАСС НЕ ТРЕБУЕТСЯ!

    КОД ПОЛЬЗОВАТЕЛЬСКОЙ ФОРМЫ

    Private Function QNumber(ByRef oTextBox As MSForms.TextBox, ByVal KeyAscii As MSForms.ReturnInteger) As MSForms.ReturnInteger
    On Error Resume Next
    Select Case KeyAscii
    Case 45 '"-"
    If InStr(1, oTextBox.Text, "-") > 0 Or oTextBox.SelStart > 0 Then
    KeyAscii = 0
    End If
    Case 46 '"."
    If InStr(1, oTextBox.Text, ".") > 0 Then
    KeyAscii = 0
    End If
    Case 48 To 57 '0-9"
    Case Else
    KeyAscii = 0
    End Select
    End Function
    

    ТЕКСТОВЫЙ КОД

    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Set KeyAscii = QNumber(Me.Controls("TextBox1"), KeyAscii)
    End Sub
    
    20.07.2019
    Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..