Userform - 多个文本框的事件更改

时间:2016-07-20 06:08:13

标签: excel-vba vba excel

我尝试为每个文本框更改更新一些标签值。 我在网站上搜索并找到this linkthis link,但我仍然无法在我的代码中采用它。因为我不知道“阶级”是如何运作的。

名为“QuoTxtBoxEvt”的类中的代码:

Option Explicit

Private WithEvents TxtBoxGroup As MSForms.textbox

Public Sub TxtBoxGroup_Change()
    With frmQuo
        .TextBox28.value = Val(.TextBox8.value) * Val(.TextBox9.value)
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox11.value) * Val(.TextBox12.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox14.value) * Val(.TextBox15.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox17.value) * Val(.TextBox18.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox20.value) * Val(.TextBox21.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox23.value) * Val(.TextBox23.value))
        If .CheckBox1 = True Then .TextBox28.value = Val(.TextBox28.value) * (100 - Val(.TextBox26.value)) / 100
        If .CheckBox2 = True Then .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox28.value) * Val(.TextBox27.value) / 100)
    End With
End Sub

用户形式中的代码:

Private Sub UserForm_Initialize()
'Variables for textbox change event handler
Dim TxtBoxGroupEventHandler() As New QuoTxtBoxEvt
Dim vfrmControl As Control
Dim i As Integer

'Event handler for textbox change to update total cost
i = 1
For Each vfrmControl In Me.Controls
    If TypeName(vfrmControl) = "TextBox" Then
        ReDim Preserve TxtBoxGroupEventHandler(1 To i)
        Set TxtBoxGroupEventHandler(i).TxtBoxGroup = vfrmControl
        i = 1 + i
    End If
Next vfrmControl
End Sub

到目前为止这些我的代码,它返回一个错误。我在代码中想念的是什么?有人能简单地教我如何编写“课堂”吗?

非常感谢Orz

编辑: 我有另一种方法来实现这一点,创建一个更新我的值并在每个文本框更改事件中调用该子的子。但这是最好的方式(正确的方法吗?)吗?或者使用类方法更好?

1 个答案:

答案 0 :(得分:0)

在对事件进行分组时,我们使用类来保存对控件的引用。接下来,我们为每个控件创建一个新的类实例,并将其添加到集合或数组变量中。需要在模块级别声明集合或数组变量。通过这种方式,在初始化子例程完成执行后,对控件的引用在代码中保持活动状态。

.TextBox8.value.TextBox9.value的值发生变化时,您似乎只需要触发事件。出于这个原因,我不会经历额外的设置。

Private Sub TextBox8_Change()
    RecalcTextBoxes
End Sub

Private Sub TextBox9_Change()
    RecalcTextBoxes
End Sub

Sub RecalcTextBoxes()
    With frmQuo
        TextBox28.Value = Val(TextBox8.Value) * Val(TextBox9.Value)
        TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox11.Value) * Val(TextBox12.Value))
        TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox14.Value) * Val(TextBox15.Value))
        TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox17.Value) * Val(TextBox18.Value))
        TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox20.Value) * Val(TextBox21.Value))
        TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox23.Value) * Val(TextBox23.Value))
        If CheckBox1 = True Then TextBox28.Value = Val(TextBox28.Value) * (100 - Val(TextBox26.Value)) / 100
        If CheckBox2 = True Then TextBox28.Value = Val(TextBox28.Value) + (Val(TextBox28.Value) * Val(TextBox27.Value) / 100)
    End With
End Sub

您应该在QuoTxtBoxEvt类中添加一个标记,以阻止TxtBoxGroup_Change事件重新触发自身。它现在的方式,你正在改变TextBox28 8次的值。这意味着您正在调用TxtBoxGroup_Change事件8次,这会触发8 * 8次呼叫,依此类推等等。

Option Explicit

Private WithEvents TxtBoxGroup As MSForms.TextBox
Private EditMode As Boolean

Public Sub TxtBoxGroup_Change()

    If EditMode Then 
       Exit Sub
    Else
       EditMode = True
    End If

    With frmQuo
        .TextBox28.value = Val(.TextBox8.value) * Val(.TextBox9.value)
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox11.value) * Val(.TextBox12.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox14.value) * Val(.TextBox15.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox17.value) * Val(.TextBox18.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox20.value) * Val(.TextBox21.value))
        .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox23.value) * Val(.TextBox23.value))
        If .CheckBox1 = True Then .TextBox28.value = Val(.TextBox28.value) * (100 - Val(.TextBox26.value)) / 100
        If .CheckBox2 = True Then .TextBox28.value = Val(.TextBox28.value) + (Val(.TextBox28.value) * Val(.TextBox27.value) / 100)
    End With

    EditMode = False

End Sub