限制某人在文本框中键入的内容

时间:2011-08-04 17:02:20

标签: forms excel excel-vba vba

这就是我想要做的事情,我遇到了问题。 我想限制用户在某些文本框中键入的内容。我想留下他只键入数字,但在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

有什么想法吗?

非常感谢!

5 个答案:

答案 0 :(得分:4)

您可以使用按键事件仅限制数字和“;”。随着检查条件。

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

更好的方法是使用正则表达式而不是类似的方法。

如果需要帮助,请在运行时为控件添加事件,请查看:

Add controls and events to form at runtime

编辑(TIAGO请求)

使用按键事件动态创建Userform和Textbox。使用上述链接的修改示例。感谢原作者。

添加引用 - 在“可用引用”下,单击“Microsoft Visual Basic for Applications Extensibility”,然后单击“确定”。

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

另一种方法(使用事件处理程序类)

Userform中的代码:

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

答案 1 :(得分:2)

尝试Dataannotations / metadata

更多信息:http://msdn.microsoft.com/en-us/library/ee256141.aspx

答案 2 :(得分:1)

AFAIK如果我理解的话,在用户输入之前无法处理此

然而,您可以使用TextBox_Exit事件进行格式化。您可以调整this sample of code

答案 3 :(得分:1)

虽然除非严格要求,否则我从不使用动态控制,但我对这个问题感到困惑......所以我认为这是一个挑战。 : - )

用Google搜索并且大多数答案都属于同一个解决方案,但是大多数答案都附带了“我无法让它发挥作用”的评论,包括SO Assign on-click VBA function to a dynamically created button on Excel Userform中的这个评论。

这是我构建的代码......显然不起作用,否则我会说可能是的解决方案。问题在于它应该是动态创建的按键方法。要测试它,只需将代码粘贴到名为“myForm”的VBA表单中。

我保留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

答案 4 :(得分:-1)

使用此代码:无需分类!

用户代码

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