Excel VBA Userform QueryClose:取消不起作用

我已经写了下面的代码,以便在closures表单之前检查一个进程是否已经完成。 这个用户表单被用作计分表,在卸载表单之前,将range("A6")绿色表示通过,或者将range("B6")红色表示失败作为子的最后一个步骤。

从我到目前为止在网上查过的,应该是有效的。 在debugging的时候,macros会一路走到它所说的Cancel = True的地方,然后读取该行,但表单仍然closures。

为什么不取消注册,甚至当它读取线路?

 Private Sub Userform_queryclose(CloseMode As Integer, Cancel As Integer) Dim wbScoreCard As Workbook Dim wsScoreCard As Worksheet Dim MSG As String Set wbScoreCard = Workbooks(NameBox.Value) Set wsScoreCard = wbScoreCard.Worksheets(Format(Date, "MM.dd.yy") & " " & CallType.Caption) If Err.Number = 0 Then If wsScoreCard.Range("A6").Interior.Color <> vbGreen Then If wsScoreCard.Range("B6").Interior.Color <> vbRed Then Beep MSG = MsgBox("This scorecard is not complete! If you close it now, this scorecard will not be saved. Continue?", vbYesNo, "Warning - Scorecard Incomplete") If MSG = vbYes Then wbScoreCard.Close savechanges:=False Exit Sub Else Cancel = True Exit Sub End If End If End If End If End Sub 

几件事:

  • 你没有closureserror handling,所以Err.Number = 0检查没有效果; 如果存在运行时错误,则执行直接跳出程序。

  • MSG应该是一个vbMsgBoxResult ,而不是一个String 。 你的代码只能工作,因为隐含的types转换,从底层的Integer值到你强制的Stringtypes。

  • 除非您没有发布完整的代码,否则Exit Sub在两个分支中都是多余的。

  • 这个问题可以用简单的代码复制:

     Private Sub Userform_queryclose(CloseMode As Integer, Cancel As Integer) Cancel = True End Sub 

问题在于你编造了这个签名或者以某种方式从内存中input了它。 这是QueryClose处理程序的签名:

 Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) 

注意参数的sorting

您将通过将您的CloseMode设置为True而不是Cancel来获得预期的行为,但更好的解决方法是将参数按正确的顺序排列。

事件处理程序并不关心参数名称,而是关于types和顺序。 由于这两个参数都是Integer ,所以它的顺序是:第一个Integer参数被解释为Cancel参数,第二个参数是CloseMode – 表单/ COM不关心你如何调用它,它将读取Cancel值无论如何,第一个参数。

您可以通过从代码窗格顶部的下拉列表中select事件来避免此问题:

首先从左侧下拉列表中选择UserForm接口/事件提供程序

确保左侧下拉菜单显示“UserForm”,然后从右侧下拉列表中select“QueryClose”:

然后在右侧下拉列表中选择QueryClose事件

如果没有处理程序,VBE将为您创build一个正确的