【问题标题】:VBA Userform works when run directly but not when run through subVBA Userform 在直接运行时有效,但在通过 sub 运行时无效
【发布时间】:2019-07-19 05:19:47
【问题描述】:

我有一个用户窗体,它提示用户选择一个文件(Application.FileDialog(.soFileDialogOpen))并单击几个选项(各种复选框 )。这两个都是必需的,所以我希望只有在选择了文件并且至少单击了一个复选框时才启用“确定”按钮。我有一个子 (CheckAndEnable),它在选择文件后和单击任何复选框后都运行(我正在使用一个类来处理这个问题)。

这是用户表单代码的一个非常简化的版本。用户窗体有一个名为 buttonOK 的按钮,一个选择文件 buttonSelectFile 的按钮,以及可变数量的复选框。

Option Explicit
Dim colChkboxes As Collection
Dim intchoice As Integer, AtLeastOneChecked As Boolean, strPath As String

Private Sub buttonOK_Click()
    Hide
End Sub

Private Sub buttonSelectFile_Click()
    Dim intchoice As Integer

    Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
    intchoice = Application.FileDialog(msoFileDialogOpen).Show

    If intchoice <> 0 Then
        strPath = Application.FileDialog(msoFileDialogOpen).SelectedItems(1)
        labelPath.Caption = strPath
    End If

    CheckAndEnable
End Sub

Public Sub CheckAndEnable()
    Dim ctrl As Control
    ' checks all checkboxes to determine if at least one is checked    
    AtLeastOneChecked = False
    For Each ctrl In Me.Controls
        If TypeName(ctrl) = "CheckBox" Then
            If ctrl.Value = True Then
                AtLeastOneChecked = True
                Exit For
            End If
        End If
    Next ctrl

    ' enable the OK button if file selected and at least one checkbox clicked
    If (AtLeastOneChecked = True) And (Not IsEmpty(strPath)) And (strPath <> "") Then
        buttonOK.Enabled = True
    Else
        buttonOK.Enabled = False
    End If
End Sub

Private Sub UserForm_Initialize()
    buttonOK.Enabled = False
    ' declare vars
    Dim ctrl As Control
    Dim obj As clsCheckBox

    Set colChkboxes = New Collection
    ' set each checkbox to CheckBox Class that handles if checkbox is 
clicked.
    For Each ctrl In Me.Controls
        If TypeName(ctrl) = "CheckBox" Then
            Set obj = New clsCheckBox
            obj.AssignClicks ctrl
            colChkboxes.Add obj
        End If
    Next ctrl
End Sub

我还有一个类模块clsCheckBox,代码如下,每当单击复选框时都会调用 CheckAndEnable。

Private WithEvents chkbox As MSForms.CheckBox

Public Sub AssignClicks(ctrl As Control)
    Set chkbox = ctrl
End Sub

Private Sub chkbox_Change()
    Call MyUserform.CheckAndEnable
End Sub

当我直接运行用户窗体时,一切正常。问题是,当我在模块中调用用户表单时(此用户表单是较大脚本中一系列用户表单的一部分),CheckAndEnable 脚本在单击复选框时运行,但未按预期启用 OK 按钮。我对此进行了广泛的研究,但找不到任何东西。任何帮助将不胜感激!

【问题讨论】:

  • 您是以MyUserform.Show 启动用户表单还是创建它的实例然后启动它?例如Dim frm as new MyUserform 然后frm.Show?
  • 如果我使用MyUserform.Show 启动用户表单,它可以正常工作。问题是这个用户表单有时只显示(取决于早期的表单),所以我一直在使用Set frm = VBA.UserForms.Add("MyUserform"),然后是frm.Show,因为这样我可以根据需要灵活地循环调用用户表单和其他人。跨度>
  • 请参阅UserForm1.Show -- 如果您要在任何地方使用任何代码,则不能让 anything 引用表单的 默认实例处理非默认实例。具体来说,MyUserForm.CheckAndEnable 看起来像 clsCheckBox 需要引用它需要使用的表单实例,而不是假设默认实例可以。
  • 啊哈!就是这样。我用Call chkbox.Parent.CheckAndEnable 替换了Call MyUserform.CheckAndEnable,现在它可以正常工作了。谢谢你们!
  • 是的 Call MyUserform.CheckAndEnable 如果您按照我的第一条评论中所述执行后者,则会产生问题。

标签: excel vba userform


【解决方案1】:

当您在 clsCheckBox 的子 chkbox_Change() 中调用 MyUserform.CheckAndEnable 时,它会为 UserForm 的 default 实例运行 CheckAndEnable 脚本。由于显示用户表单的模块正在创建表单的非默认实例,因此 CheckAndEnable 脚本失败了,因为它不知道在非默认版本中更改了哪些复选框/变量/等。

感谢 Mathieu Guindon 的解决方案。详情请见UserForm1.Show。

【讨论】:

    猜你喜欢
    • 2015-10-09
    • 2013-10-07
    • 2014-04-24
    • 2016-08-06
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    相关资源
    最近更新 更多