我有一组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
答案 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
事件,而不是当用户将焦点(和光标)移动到另一个控件时发生的事件。