设置UserForm元素以进行唯一验证

时间:2013-02-14 16:40:25

标签: excel vba excel-vba

这是关于Excel UseForm中文本框的特定验证的上一个问题的延续。获得此代码后,Sorceri对我帮助很大,但我现在需要进行一些微调。我需要在不同的文本框中进行不同的验证。我通过“工具箱”中的“控件”构建了文本框。他们按顺序命名; “info1”,“info2”,“info3”等等。

大多数文本框的验证可以在下面看到(“1-5”,“88”和“99”)。但是,其中两个文本框需要以不同方式进行验证(“1-3”和“88”)。除此之外,还需要为第三组文本框(“0-10”和“88”)设置第三个验证集。我对VBA和编程很新,但我学得很快。任何帮助将不胜感激。

为了补充说明,我在括号内的Sorceri旁边添加了自己的评论。再次感谢大家。

Private Sub cmdEnter_Click()
Dim ctl As Control
For Each ctl In Me.Controls
    'check to see if it is a textbox (I'm guessing I could specify which textboxes here, but I'm unsure)
    If TypeOf ctl Is MSForms.TextBox Then
        Dim tBox As MSForms.TextBox
        Set tBox = ctl
        'we have a textbox so validate the entry (Again, I'm hoping to make this into, "We found textbox variant A and so will validate its entry with validation A, etc)
        If validateTextBox(tBox) Then
            'did not validate so set focus on the control
            MsgBox "Invalid Entry!", vbCritical, "Invalid!"
            ctl.SetFocus
            'release the object
            Set tBox = Nothing
            Exit Sub
        End If
        Set tBox = Nothing
    End If
Next
End Sub




'validate a textbox's value and return true or false
Private Function validateTextBox(tb As MSForms.TextBox) As Boolean
    Dim sValue As String
    Dim bInvalid As Boolean
    bInvalid = True
    sValue = Trim(tb.Text)
    If sValue = "1" Or sValue = "2" Or sValue = "3" Or sValue = "4" Or sValue = "5" Or sValue = "99" Or sValue = "88" Then
        bInvalid = False
    End If
    'return the results
    validateTextBox = bInvalid
End Function

3 个答案:

答案 0 :(得分:1)

所以真正的问题是你的文本框元素是如何分组的。需要有一些方法来区分需要验证的三个不同组。最简单的方法可能是附加到每个文本框的名称当前名称的命名约定(除非您可以使用分组控件IE框架)。您可以使用A-B-C或任何其他命名方案。在这个例子中,我将使用A-B-C。

A组验证 (“1-5”,“88”和“99”)

B组验证 (“1-3”和“88”)

C组验证 (“0-10”和“88”)

现在在每个textBox的末尾,我附加了A,B或C来区分文本框所属的组。您声明您的文本框元素遵循以下命名方案:“info1”,“info2”,“info3”,

所以我们现在应该有“info1A”,“info2A”,“info3C”,“info4B”,“info5C”....“info30A”,

有了这个,我们现在为每个组添加一个枚举类型

Private Enum ValidationGroup
NONE
A 
B
C
End Enum

'我们将在获取组

的方法中添加switch语句
Private Sub cmdEnter_Click()
Dim ctl As Control
For Each ctl In Me.Controls
    'check to see if it is a textbox
    If TypeOf ctl Is MSForms.TextBox Then
        Dim tBox As MSForms.TextBox
        Dim tbGroup As ValidationGroup

        Set tBox = ctl
        'we have a textbox so check the group and validate the entry
        'get the group to validate against
        tbGroup = Switch(Right(tBox.Name, 1) = "A", ValidationGroup.A, _
        Right(tBox.Name, 1) = "B", ValidationGroup.B, _
        Right(tBox.Name, 1) = "C", ValidationGroup.C, _
        Right(tBox.Name, 1) <> "*", ValidationGroup.NONE) 'default value of none

        If validateTextBox(tBox, tbGroup ) Then
            'did not validate so set focus on the control
            MsgBox "Invalid Entry!", vbCritical, "Invalid!"
            ctl.SetFocus
            'release the object
            Set tBox = Nothing
            Exit Sub
        End If
        Set tBox = Nothing 
    End If
Next
End Sub

更改validateTextBox以包含枚举

**作为旁注,这种方法可以进行大修,以提高效率

'validate a textbox's value and return true or false
Private Function validateTextBox(tb As MSForms.TextBox, vg As ValidationGroup) As Boolean
    Dim sValue As String
    Dim bInvalid As Boolean
    bInvalid = True
    sValue = Trim(tb.Text)t
    'check the validation group then check the values
    If vg = ValidationGroup.A Then
        If sValue = "1" Or sValue = "2" Or sValue = "3" Or sValue = "4" Or sValue = "5" Or sValue = "99" Or sValue = "88" Then
            bInvalid = False
        End If
    ElseIf vg = ValidationGroup.B Then
        If sValue = "1" Or sValue = "2" Or sValue = "3" Or sValue = "88" Then
            bInvalid = False
        End If
    ElseIf vg = ValidationGroup.C Then
        If sValue = "0" Or sValue = "1" Or sValue = "2" Or sValue = "3" Or sValue = "4" Or sValue = "5" Or _
        sValue = "6" Or sValue = "7" Or sValue = "8" Or sValue = "9" Or sValue = "10" Or sValue = "88" Then
            bInvalid = False
        End If
    End If
    'return the results
    validateTextBox = bInvalid
End Function

答案 1 :(得分:0)

尝试以下方法。

我根据文本框的名称在函数中放置了一些选择案例。

我假设,为简单起见,您将根据验证分组(重新)命名文本框。但是,您可以将每个单独的文本框名称放在Case Is =语句中,并删除Left语句中的Select Case函数。

我还将tb.Value更改为Integer以使If语句更易于编写/读取。

这并不是一个完整的答案,而是提供一个明确的结构来构建你的答案。

Function validateTextBox(tb As MSForms.TextBox) As Boolean

    Dim iValue As Integer, sName As String, bInvalid As Boolean

    bInvalid = True

    sName = tb.Name
    iValue = CInt(Trim(tb.Text))

    If iValue = 88 Then 'because this is common among all the groups check for it first

        bInvalid = False

    Else

        Select Case Left(sName, "4")

            Case Is = "grp1"

                If (iValue > 1 And iValue <= 5) Or iValue = 99 Then bInvalid = False

            Case Is = "grp2"

                If (iValue > 1 And iValue <= 3) Then bInvalid = False

            Case Is = "grp3"

                If (iValue > 1 And iValue <= 10) Then bInvalid = False

        End Select

    End If

    'return the results
    validateTextBox = bInvalid

End Function

答案 2 :(得分:0)

将验证值放在每个Textbox的Tag属性中,如“1-30,88,89”(尽管没有引号)可能也想稍微整理这些变量声明。

Function ValidateTextBox(tb As MSForms.TextBox) As Boolean
    Dim sTag, i, arr, arrVal, min, max, v, tbVal, ok As Boolean

    tbVal = Trim(tb.Value)

    If IsNumeric(tbVal) Then

        sTag = Replace(tb.Tag, " ", "") 'remove any spaces from tb Tag

        v = CInt(tbVal) 'convert the textbox value to integer

        If sTag <> "" Then
            arr = Split(sTag, ",")
            For i = LBound(arr) To UBound(arr)
                arrVal = Trim(arr(i))
                If InStr(arrVal, "-") > 0 Then
                    'check against a range
                    min = CInt(Split(arrVal, "-")(0))
                    max = CInt(Split(arrVal, "-")(1))
                    If v >= min And v <= max Then
                        ok = True
                        Exit For
                    End If
                Else
                   'just a single value to check against
                   If v = CInt(arr(i)) Then
                        ok = True
                        Exit For
                   End If
                End If
            Next i
        Else
            MsgBox "No rule for this textbox: " & tb.Name
        End If

    End If

    ValidateTextBox = ok

End Function