我应该在哪里加载和卸载frm1(Userform名称为frm1),我应该在哪里放置Me.Show和Me.Hide? p>
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。这项工作。
调试器说错误在cmdb1_Click()中。我尝试添加一个名为UserForm_QueryClose()的子,但错误仍然存在。如果我不得不猜测,我会说错误是由我处理加载和卸载的方式引起的,因此是cmdb1_Click()。
修改
我的问题解决了。 ShowUserform和cmdbClose_Click包含CallumDA建议的代码。我的命令按钮现在有:
Private Sub cmdb1_Click()
Load frm1
Call ShowUserform
End Sub
答案 0 :(得分:17)
我建议您创建用户表单的实例:
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建议的那样在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)
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
(我知道以上并不是严格说明属性的正确方法,但这样可以正常工作。如果愿意,可以按常规方式将其设为只读。)
答案 1 :(得分:5)
将其放入标准模块并将其链接到用于显示用户表单的按钮
Sub ShowUserform
frm1.Show
End Sub
然后在userform
中Private Sub cmdbClose_Click()
Unload Me
End Sub
答案 2 :(得分:3)
我在Excel中使用表单多年来一直在努力。我永远无法理解一个对象(一个表单)是如何被销毁但仍然运行它的代码。
我现在在每个具有[确定]和[取消]按钮的表单上使用此代码,因为它允许您在主代码中控制用户单击的[确定],[取消]和[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的优秀文章,该文章详细介绍了上面给出的代码。