【问题标题】:VBA UserForm: SpinButtons not working when TextBoxes are formatted using Class ModuleVBA 用户窗体:使用类模块格式化文本框时,旋转按钮不起作用
【发布时间】:2017-12-09 02:18:52
【问题描述】:

我有一堆控制文本框中值的微调按钮。我正在使用一个类来允许他们所有人使用相同的更改事件。它适用于未格式化的框。

但是,当我尝试让文本框显示 + 和 - 数字时,它无法正常工作。只有第一个旋转按钮有效。在下一个旋转按钮起作用之前,它的值需要设置为负数。除非按顺序将其正上方的文本框设置为负数,否则任何按钮(第一个除外)都无法正常工作。

我尝试过使用 .Text 代替 .Value,但没有任何区别。

类模块:

Public WithEvents SpinBtn As MSForms.SpinButton
Public WithEvents StatBox As MSForms.TextBox

Private Sub StatBox_Change()
Call UserForm1.ChangeSpin
End Sub

Private Sub SpinBtn_Change()
Call UserForm1.ChangeStat
End Sub

用户窗体模块:

Dim collSpin As New Collection
Dim collStat As New Collection

Public Sub ChangeStat()
    Dim i As Long

    For i = 1 To 4
         Me.Controls("StatBox" & i).Value = Me.Controls("SpinButton" & i).Value
    Next
End Sub

Public Sub ChangeSpin()
    Dim i As Long  

    For i = 1 To 4
        Me.Controls("SpinButton" & i).Value = Me.Controls("StatBox" & i).Value
        Me.Controls("StatBox" & i) = Format(Me.Controls("StatBox" & i), "+#;-#;+0")
        'This is the line that breaks things
    Next
End Sub

Private Sub UserForm_Initialize()
    Dim i As Long
    Dim ctl As MSForms.Control
    Dim obEvents As clsSpin

    Call ChangeSpin

    'Collect SpinButtons
    For Each ctl In Me.Controls
        If TypeOf ctl Is MSForms.SpinButton Then
            For i = 1 To 4
                If ctl.Name = "SpinButton" & i Then
                    Set obEvents = New clsSpin
                    Set obEvents.SpinBtn = ctl
                    collSpin.Add obEvents
                End If
            Next
        End If
    Next ctl

    'Collect StatBoxes
    For Each ctl In Me.Controls
        If TypeOf ctl Is MSForms.TextBox Then
            For i = 1 To 4
                If ctl.Name = "StatBox" & i Then
                    Set obEvents = New clsSpin
                    Set obEvents.StatBox = ctl
                    collStat.Add obEvents
                End If
            Next
        End If
    Next ctl
End Sub

编辑: 感谢 @YowE3K 向我展示了一种更简单、更清洁的方式!

类:

Public WithEvents SpinBtn As MSForms.SpinButton
Public WithEvents StatBox As MSForms.TextBox

Private Sub StatBox_Change()
    'prevents error when enter + or -
    If IsNumeric(Me.StatBox.Value) = False Then
    Else
        'defaults to max or min of spinbutton when out of range
        Select Case Me.StatBox.Value
            Case Is < SpinBtn.Min
                Me.SpinBtn.Value = Me.SpinBtn.Min
            Case Is > SpinBtn.Max
                Me.SpinBtn.Value = Me.SpinBtn.Max
            Case Else
                Me.SpinBtn.Value = Me.StatBox.Value
        End Select
    Me.StatBox.Value = Format(Me.StatBox.Value, "+#;-#;+0")
    End If
End Sub

Private Sub SpinBtn_Change()
    Me.StatBox.Value = Format(Me.SpinBtn.Value, "+#;-#;+0")
End Sub

Private Sub StatBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Select Case KeyAscii
        Case 43 '+
        Case 45 '-
        Case 48 To 57 '0-9
        Case Else
            KeyAscii = 0
    End Select
End Sub

用户表单:

Dim collSpinStat As New Collection

Private Sub UserForm_Initialize()
    Dim i As Long
    Dim obEvents As clsSpin

    For i = 1 To 4
        Set obEvents = New clsSpin
        Set obEvents.SpinBtn = Me.Controls("SpinButton" & i)
        Set obEvents.StatBox = Me.Controls("StatBox" & i)
        Me.Controls("StatBox" & i) = Format(Me.Controls("StatBox" & i), "+#;-#;+0")
        collSpinStat.Add obEvents
    Next
End Sub

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    您似乎正在尝试将“StatBox”控件与“SpinButton”控件链接起来。如果是这样,请尝试以下操作:

    类“clsSpin”:

    Public WithEvents SpinBtn As MSForms.SpinButton
    Public WithEvents StatBox As MSForms.TextBox
    
    Private Sub StatBox_Change()
        Me.SpinBtn.Value = Me.StatBox.Value
    End Sub
    
    Private Sub SpinBtn_Change()
        Me.StatBox.Value = Format(Me.SpinBtn.Value, "+#;-#;+0")
    End Sub
    

    用户窗体模块:

    Dim collSpinStat As New Collection
    
    Private Sub UserForm_Initialize()
        Dim i As Long
        Dim obEvents As clsSpin
    
        For i = 1 To 4
            Set obEvents = New clsSpin
            Set obEvents.SpinBtn = Me.Controls("SpinButton" & i)
            Set obEvents.StatBox = Me.Controls("StatBox" & i)
            collSpinStat.Add obEvents
        Next
    End Sub
    

    FWIW,我建议使用标签而不是文本框。使用 TextBoxes 意味着您需要将代码合并到 StatBox_Change 事件中,以测试用户在 TextBox 中输入的值是否实际有效。使用标签意味着用户必须使用 SpinButton 进行更改。

    【讨论】:

    • 完美!从来不知道您可以使用 Format 更改值。那真好;那真甜。我确实希望用户能够在文本框中输入值。我会在编辑中为发生此情况的其他人添加它。
    • @bigbucky - 你的 Me.Controls("StatBox" &amp; i) = Format(Me.Controls("StatBox" &amp; i), "+#;-#;+0") 和我的 Me.StatBox.Value = Format(Me.SpinBtn.Value, "+#;-#;+0") 做同样的事情 - 我只是明确地编码了 Value 属性,而不是让它默认为那个属性。
    • @bigbucky 哦!我刚刚重新查看了我的代码并意识到为什么需要Collection - 没有它,obEvents 引用的对象将不会被维护。使用集合,它们将持续存在,直到表单关闭。我编辑了not的答案,说Collection 并不是真正需要的。
    • 是的,在没有Collection 的情况下尝试了它,并意识到我仍然需要它。我在编辑中发布了我的完整代码。工作得很好,更干净。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    相关资源
    最近更新 更多