如何加载和卸载Userform

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何加载和卸载Userform相关的知识,希望对你有一定的参考价值。

我应该在哪里加载和卸载frm1(Userform名称是frm1),我应该把Me.Show和Me.Hide放在哪里?

UserForm中的(x)按钮不起作用。

我的加载和卸载在Sheet1上的Active-X命令按钮代码中:

 Private Sub cmdb1_Click()
     Load frm1
     Unload frm1
 End Sub

这样我的UserForm被初始化,我可以运行代码

Private Sub Userform_Initialize()
    'Some other code that Works...  
    frm1.Show
End Sub

这显示了我的Userform。现在,我的Userform中有一个包含代码的命令按钮

Private Sub cmdbClose_Click()
    Me.Hide
End Sub

我用来隐藏sub,在cmdb1_Click()中执行最后一行并卸载UserForm。这个作品。

但是当我按下UserForm中的(x)按钮时,会出现以下错误:Run-time error '91'

调试器说错误位于cmdb1_Click()内。我尝试添加一个名为UserForm_QueryClose()的子,但错误仍然存​​在。如果我不得不猜测,我会说错误是由我处理加载和卸载的方式引起的,因此通过cmdb1_Click()。

编辑:

我的问题解决了。 ShowUserform和cmdbClos​​e_Click包含CallumDA建议的代码。我的命令按钮现在有:

Private Sub cmdb1_Click()
    Load frm1
    Call ShowUserform
End Sub
答案

将其放在标准模块中,并将其链接到用于显示用户窗体的按钮

Sub ShowUserform
    frm1.Show
End Sub

然后在userform中

Private Sub cmdbClose_Click()
    Unload Me
End Sub 
另一答案

我建议您创建userform的实例:

Dim MyDialog As frm1

Set MyDialog = New frm1    'This fires Userform_Initialize

然后,您可以在尝试卸载表单之前轻松检查表单是否已加载:

If Not MyDialog Is Nothing Then
    Unload MyDialog
End If

我还建议您不要从表单的Initialize事件中调用Show方法。将您的userform视为Excel中的另一个对象,并从主代码体管理它。

此外,我不会按照CallumDA的建议在cmdbClos​​e_Click事件中卸载它(尽管这可以解决当前问题)。通常,您需要能够从主代码体中引用表单上的值,如果卸载它们,它们将无法使用。相反,保持它就像你在第一时间拥有它:

Private Sub cmdbClose_Click()
    Me.Hide
End Sub

所以你的主代码体(在你的activeX按钮中)看起来像这样:

Dim MyDialog as frm1

Set MyDialog = New frm1      'This fires Userform_Initialize
'Place any code you want to execute between the Initialize and Activate events of the form here
MyDialog.Show           'This fires Userform_Activate
'When the close button is clicked, execution will resume on the next line:
SomeVariable = MyDialog.SomeControl.Value
'etc.

If Not MyDialog Is Nothing Then
    Unload MyDialog
End If

您还可以捕获用户单击表单上的“X”时触发的事件,并阻止表单被卸载:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    Me.Hide
End Sub

最后,通常您需要在表单上使用“取消”按钮。我处理这个的方法是在窗体的代码隐藏中创建一个“已取消”属性:

Public Cancelled as Boolean
'(Note You can create additional properties to store other values from the form.)

在取消按钮单击事件中:

Private Sub cmdbCancel_Click()
    Me.Cancelled = True
    Me.Hide
End Sub

并在主代码体中:

Dim MyDialog as frm1

Set MyDialog = New frm1
MyDialog.Show

If Not MyDialog.Cancelled Then
    SomeVariable = MyDialog.SomeControl.Value
    SomeOtherVariable = MyDialog.SomeOtherProperty
    'etc.
End If

If Not MyDialog Is Nothing Then
    Unload MyDialog
End If

(我知道上面并不是严格说明属性的正确方法,但这样可以正常工作。如果你愿意的话,你可以按常规方式将它设为只读。)

另一答案

我在Excel中使用表单多年来一直在努力。我永远无法理解一个对象(一个表单)是如何被销毁但仍然运行它的代码。

我现在在每个具有[OK]和[Cancel]按钮的表单上使用此代码,因为它允许您在主代码中控制用户单击的[OK],[Cancel]和[X]:

Option Explicit
Private cancelled As Boolean

Public Property Get IsCancelled() As Boolean
    IsCancelled = cancelled
End Property

Private Sub OkButton_Click()
    Hide
End Sub

Private Sub CancelButton_Click()
    OnCancel
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        OnCancel
    End If
End Sub

Private Sub OnCancel()
    cancelled = True
    Hide
End Sub

然后,您可以将表单用作实例,如下所示:

With New frm1    
    .Show
    If Not .IsCancelled Then
        ' do your stuff ...
    End If
End With

或者您可以将它用作上述对象(变量?),例如:

Dim MyDialog As frm1

Set MyDialog = New frm1    'This fires Userform_Initialize

然后是上面提到的类似实例

这完全基于RubberDuck的一篇优秀文章,该文章详细介绍了上面给出的代码。

以上是关于如何加载和卸载Userform的主要内容,如果未能解决你的问题,请参考以下文章

如何从程序集中加载及卸载插件

如何动态加载和卸载(重新加载).dll 程序集

如何加载和卸载级别

vb.net编程,如何使用 appdomain 实现某进程DLL动态加载和卸载?

C#.Net 如何动态加载与卸载程序集(.dll或者.exe)

如何卸载已加载的程序集