Excel 如何加载和卸载用户表单

Excel 如何加载和卸载用户表单,excel,vba,Excel,Vba,我应该把加载和卸载frm1(用户名是frm1)放在哪里?我应该把Me.Show和Me.Hide放在哪里 UserForm中的(x)按钮不起作用 我的加载和卸载在活页1上的Active-X命令按钮代码中: Private Sub cmdb1_Click() Load frm1 Unload frm1 End Sub 这样我的UserForm就被初始化了,我就可以运行代码了 Private Sub Userform_Initialize() 'Some other

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

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

我的加载和卸载在活页1上的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中有一个命令按钮,其中包含代码

Private Sub cmdbClose_Click()
    Me.Hide
End Sub
我使用它来隐藏子对象,在子对象上执行cmdb1_Click()中的最后一行并卸载UserForm。这很有效

但是,当我在UserForm中按下(x)按钮时,会出现以下错误

调试器说错误在cmdb1_Click()中。我尝试添加名为UserForm_QueryClose()的子项,但错误仍然存在。如果必须猜测的话,我会说错误是由我处理加载和卸载的方式引起的,因此是由cmdb1_Click()引起的

编辑:

我的问题解决了。ShowUserform和cmdbClose\u单击包含您建议的代码。“我的命令”按钮现在有:

Private Sub cmdb1_Click()
    Load frm1
    Call ShowUserform
End Sub

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

Sub ShowUserform
    frm1.Show
End Sub
Private Sub cmdbClose_Click()
    Unload Me
End Sub 
然后在userform中

Sub ShowUserform
    frm1.Show
End Sub
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
我还建议不要从表单的初始化事件调用Show方法。将您的userform看作Excel中的另一个对象,并从主代码体管理它

此外,我不会像CallumDA建议的那样在cmdbClose_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)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = True
        Me.Hide
    End If
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
然后是上面提到的类似例子


这一切都基于一篇优秀的文章,文章详细介绍了上述代码。

您缺少卸载部分<代码>卸载我的对话框