关闭按钮不起作用卸载我

时间:2019-02-11 17:22:51

标签: excel vba userform

我在UserForm1中有一个for循环,该循环打开UserForm2的次数不定,以从用户那里获取适当数量的数据。参见下面在UserForm1中运行的代码

Private Sub Start_Click()
    Constants
    InitBoard
    While Not ValidTest
        IncParts
    Wend
End Sub

Public Sub InitBoard()
    Dim row As Integer
    Dim col As Integer
    For Mirror = 1 To NumBlocks(2, 1)
        LockType = 1
        UserForm2.Show
    Next Mirror
    For Prism = 1 To NumBlocks(2, 2)
        LockType = 2
        UserForm2.Show
    Next Prism
    For Wormhole = 1 To NumBlocks(2, 3)
        LockType = 3
        UserForm2.Show
    Next Wormhole
    For Blocker = 1 To NumBlocks(2, 4)
        LockType = 4
        UserForm2.Show
    Next Blocker
    For Splitter = 1 To NumBlocks(2, 5)
        LockType = 5
        UserForm2.Show
    Next Splitter
End Sub

现在,如果我运行代码,则可以在UserForm2中适当地获取数据。当我用红色的“ X”按钮手动关闭UserForm2时,一切正常。再次弹出UserForm2,并显示从上次循环运行中接受的数据。在每个循环运行了适当的次数之后,UserForm2停止打开,并且代码在UserForm1中继续到Start_Click()子项的While循环。但是,如果我在UserForm2内的子程序末尾使用“卸载我”以在收到正确的输入后自动将其关闭,则会收到“运行时错误'91':对象变量或未设置块变量”。当我按Debug时,以上代码中的InitBoard()的第5行被突出显示(UserForm2.Show)。下面是我在UserForm2内部使用的复选框单击功能。注释掉第3行即可解决该问题,但我必须手动关闭该表单。

Private Sub Bstate00_Click()
    BoardState(0, 0) = LockType + 5
    Unload Me
End Sub

在显示之前,我已经尝试过尝试加载UserForm2的所有组合,确保每次UserForm2关闭之前都不要结束循环,甚至添加无济于事的延迟。 Me.Hide确实解决了该问题,但没有运行更新在上一个循环中输入的信息所需的UserForm2_Initialize()子项。

请根据以下有关402错误的对话在注释中查看重新创建错误的最小代码:

在UserForm1中:

Private Sub Start_Click()
    For Mirror = 1 To 3
        LockType = 1
        With New UserForm2
            .Show
        End With
    Next Mirror
End Sub

在UserForm2中:

Private Sub Bstate00_Click()
    BoardState(0, 0) = LockType + 5
    Me.Hide
End Sub

Private Sub UserForm_Initialize()
    If BoardState(0, 0) = -1 Then
        Me.Controls("BState" & 0 & 0).Value = False
        Me.Controls("BState" & 0 & 0).Enabled = False
    ElseIf BoardState(0, 0) = 0 Then
        Me.Controls("BState" & 0 & 0).Value = False
        Me.Controls("BState" & 0 & 0).Enabled = True
    Else
        Me.Controls("BState" & 0 & 0).Value = True
        Me.Controls("BState" & 0 & 0).Enabled = False
    End If
End Sub

在Module1中:

Public BoardState(0 To 5, 0 To 5) As Integer
Public LockType As Integer

1 个答案:

答案 0 :(得分:2)

tldr; 按钮很重要。一切都不像UserForm土地上的样子。


FWIW,我无法在Excel 2013 x64中重现402运行时错误,但确实发现了一些有趣的行为。给出以下代码:

'UserForm1.cls
Private Sub UserForm_Initialize()
    Debug.Print "UserForm1_Initialize"
End Sub

Private Sub UserForm_Click()
    Dim i As Long
    For i = 1 To 3
        With New UserForm2
            .Show vbModal
        End With
    Next
    Debug.Print "Done"
End Sub

'UserForm2.cls
Private Sub UserForm_Initialize()
    Debug.Print "UserForm2_Initialize"
End Sub

Private Sub UserForm_Click()
    Me.Hide
End Sub

Private Sub UserForm_Terminate()
    Debug.Print "UserForm2_Terminate"
End Sub

执行以上操作(将UserForm1显示为模态)时,单击以将其显示为以下输出:

UserForm1_Initialize
UserForm2_Initialize
UserForm2_Initialize
UserForm2_Initialize
Done

请注意,With块退出时,不会终止事件。在点击处理程序中调用Unload Me的行为正常。这是完全出乎意料的,因此我仔细研究了UserForm类的文档,并从Paul Lomax 1 找到了这句话:

  

Microsoft建议仅在Click中卸载表格   CommandButton或菜单控件的事件。调用卸载语句   在其他情况下,处理程序可能会产生不良的副作用并导致   常规保护故障(GPF)。

这让我很好奇,如果将Me.Hide语句移到CommandButton处理程序中会发生什么:

Private Sub UserForm_Initialize()
    Debug.Print "UserForm2_Initialize"
End Sub

Private Sub CommandButton1_Click()
    Me.Hide
End Sub

Private Sub UserForm_Terminate()
    Debug.Print "UserForm2_Terminate"
End Sub

执行此代码将得到以下输出...

UserForm1_Initialize
UserForm2_Initialize
UserForm2_Terminate
UserForm2_Initialize
UserForm2_Terminate
UserForm2_Initialize
UserForm2_Terminate
Done

...完全符合预期。似乎在VBA处理UserForm周围存在一些未记录的怪异之处。但是它变得 更奇怪 。如果我将CommandButton留在表单上并恢复为原始代码(将表单单击处理程序隐藏在表单中,而代码中根本没有UserForm_Click()处理程序,则 it still 触发Terminate事件。表单上仅存在CommandButton会改变卸载行为,也就是说,您可以尝试在表单上放置一个隐藏的CommandButton并查看是否可以解决该问题。如果不能解决,则始终可以从调用站点中显式Unload来表单:

Private Sub UserForm_Click()
    Dim i As Long
    Dim subForm As UserForm2
    For i = 1 To 3
        Set subForm = New UserForm2
        subForm.Show vbModal
        Unload subForm
    Next
    Debug.Print "Done"
End Sub

1 Lomax,保罗。 VB和VBA简而言之:语言。加利福尼亚塞巴斯托波尔:OReilly,1999年,第567页