如何从22个文本框中为20个文本框创建一个代码,而不是相同的20倍

时间:2017-12-31 18:33:19

标签: vba excel-vba textbox excel

我有一组22个文本框。前20个是1到10之间的数字,textbox21是textbox22,每个组的总数为10.我有一个textbox1,直到textbox20相同的代码,但我怎样才能使这更容易?

下面你会看到我对其中一个文本框的代码。

Private Sub TextBox1_Change()
    korps(1) = 0
    korps1
    If TextBox1.Value = "" Then
                            TextBox1.SetFocus
                            Exit Sub
    End If
            If Not IsNumeric(TextBox1.Value) Then
                MsgBox "Sorry, only numbers allowed"
                TextBox1.Value = ""
                Exit Sub
            End If
    If TextBox1.Value = 0 Then TextBox1.Value = 10
    korps(1) = TextBox1.Value
    korps1
End Sub

2 个答案:

答案 0 :(得分:3)

如果您按照我的评论中的链接,您可以创建一个名为txtBox的类和以下代码

Option Explicit

Private WithEvents mTextBox As MSForms.Textbox

Property Set Box(nBox As MSForms.Textbox)
    Set mTextBox = nBox
End Property

Private Sub mTextBox_Change()

    If mTextBox.Value = "" Then
        mTextBox.SetFocus
        Exit Sub
    End If
    If Not IsNumeric(mTextBox.Value) Then
        MsgBox "Sorry, only numbers allowed"
        mTextBox.Value = ""
        Exit Sub
    End If
    If mTextBox.Value = 0 Then mTextBox.Value = 10

End Sub

在表单中,您需要一个类似于以下代码的代码

Option Explicit

Dim colTxtBoxes As Collection

Private Sub UserForm_Initialize()

Dim m_txtBox As txtBox
Dim ctl As MSForms.Control

    Set colTxtBoxes = New Collection

    For Each ctl In Me.Controls

        If ctl.Name = "TextBox21" Or ctl.Name = "TextBox22" Then
        Else
            If TypeName(ctl) = "TextBox" Then
                Set m_txtBox = New txtBox
                Set m_txtBox.Box = ctl
                colTxtBoxes.Add m_txtBox
            End If
        End If

    Next ctl

End Sub

答案 1 :(得分:0)

这是一个只需要代码一次的解决方案。以下是您需要的程序。它们应该位于Userform的代码表中,您拥有所有文本框。

Option Explicit

    Dim Korps() As Long

Private Sub UserForm_Initialize()
    ' 01 Jan 2018
    ' presuming that all Tbxs are 0 upon initialisation.
    ' if they are not, transfer their initial values to Korps here.

    ReDim Korps(1 To 10, 1 To 2)
    SetTotals
End Sub

Private Function KeyPress(Tbx As MSForms.TextBox, _
                          ByVal Key As Integer) As Integer
    ' 01 Jan 2018
    ' Message is shown after each 3rd wrong entry,
    ' regardless of the Tbx in which it occurred.

    Static Count As Integer

    If Not IsNumeric(Chr(Key)) Then
        Key = 0
        Count = Count + 1
        If Count = 3 Then
            MsgBox "Only numbers may be entered", _
                    vbInformation, "Entry restrictions"
            Count = 0
        End If
    End If
    KeyPress = Key
End Function

Private Sub TbxUpdate(Tbx As MSForms.TextBox)
    ' 01 Jan 2018

    Dim Idx As Integer                      ' Tbx number
    Dim Grp As Integer                      ' 1 = 1 to 10, 2 = 11 to 20

    With Tbx
        Idx = Mid(.Name, Len("TextBox") + 1)
        Grp = Int((Idx - 1) / 10) + 1
        If Trim(.Text) = "" Then
            ' reject blank: restore previous value
            .Value = Korps(Idx, Grp)
            .SetFocus
        Else
            If .Value = 0 Then .Value = 10
            Korps(Idx, Grp) = .Value
            SetTotals Grp
        End If
    End With
End Sub

Private Sub SetTotals(Optional ByVal Grp As Integer)
    ' 01 Jan 2018
    ' if Grp isn't supplied, both groups are summed up

    Dim Ttl As Double
    Dim LoopStart As Integer, LoopEnd As Integer
    Dim i As Long

    If Grp Then
        LoopStart = Grp
        LoopEnd = Grp
    Else
        LoopStart = 1
        LoopEnd = 2
    End If

    For Grp = LoopStart To LoopEnd
        Ttl = 0
        For i = 1 To 10
            Ttl = Ttl + Korps(i, Grp)
        Next i
        Me.Controls("TextBox2" & Grp).Value = Ttl
    Next Grp
End Sub

如您所见,我猜测了您的变量korps和过程korps1做了什么。

对于20个文本框中的每个文本框,您将需要以下事件过程。除了声明中的TextBox编号外,它们都是相同的。这就是Storax'的优越性。建议改为创建一个类。如果您愿意创建我应该推荐的课程。

Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    ' 01 Jan 2018
    TbxUpdate ActiveControl
End Sub

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    ' 01 Jan 2018
    KeyAscii = KeyPress(ActiveControl, KeyAscii)
End Sub

观察我建议使用与您想到的事件不同的事件。我认为即使您选择创建课程,也应该重新考虑。 Change事件将在输入的每个字符上触发。这对于捕获非数字条目非常有用,除了KeyPress事件更适合它,因为它可以阻止字符出现在文本框中。

至于维持一个运行总计,Change事件是冒险的,因为它会在输入多位数时创建无意义的总计。我推荐Update事件,而不是当用户将焦点(和光标)移动到另一个控件时发生的事件。