Ограничить то, что кто-то печатает в текстовом поле - PullRequest
0 голосов
/ 04 августа 2011

Вот что я хочу сделать, и у меня есть проблема. Я хочу ограничить то, что пользователь вводит в определенные текстовые поля. Я хочу оставить ему набирать только цифры, но после 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

Есть идеи?

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

Ответы [ 4 ]

4 голосов
/ 11 августа 2011

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

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
2 голосов
/ 11 августа 2011

Попробуйте Dataannotations / metadata

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

1 голос
/ 11 августа 2011

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

Погуглил, и большинство ответов попадают в одно и то же решение, однако большинство из них также содержат комментарий «Я не мог заставить его работать», в том числе здесь, в 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
1 голос
/ 05 августа 2011

AFAIK, и если я хорошо понял, нет способа обработать это до ввода пользователя.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...