我编写了下面的代码,以便它在关闭表单之前检查流程是否已完成。该用户表单用作记分表,在卸载表单之前,作为子项目的最后一步,绿色表示range("A6")通过,红色表示失败。range("B6")
从我目前在网上查到的情况来看,它应该有效。调试时,宏一直到达显示 Cancel = True 的位置,读取该行,但窗体仍会关闭。
为什么即使在读取线路时取消也没有注册?
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
Run Code Online (Sandbox Code Playgroud)
有几件事:
您没有关闭错误处理,因此Err.Number = 0检查无效;如果存在运行时错误,执行无论如何都会直接跳出该过程。
MSG应该是 a vbMsgBoxResult,而不是 a String。您的代码之所以有效,是因为从基础Integer值到String您强制转换的类型的隐式类型转换。
除非您没有发布整个代码,否则Exit Sub在两个分支中都是多余的。
可以使用更简单的代码重现该问题:
Private Sub Userform_queryclose(CloseMode As Integer, Cancel As Integer)
Cancel = True
End Sub
Run Code Online (Sandbox Code Playgroud)问题是你编造了这个签名,或者以某种方式凭记忆输入了它。这是处理程序的签名QueryClose:
Run Code Online (Sandbox Code Playgroud)Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
注意参数的顺序。
CloseMode通过将您的设置设置为True而不是... ,您将获得预期的行为,Cancel但更好的解决方法是将参数按正确的顺序放置。
事件处理程序并不真正关心参数名称:它关心的是类型和顺序。由于两个参数都是Integer,因此取决于顺序:第一个Integer参数被解释为Cancel参数,第二个参数是CloseMode- 表单/COM 不关心您如何调用它们,Cancel无论如何它都会从第一个参数读取值。
您可以通过从代码窗格顶部的下拉列表中选择事件来避免将来出现此问题:
确保左侧下拉列表显示“UserForm”,然后从右侧下拉列表中选择“QueryClose”:
如果没有对应的处理程序,VBE 将为您创建一个正确形成的处理程序。
| 归档时间: |
|
| 查看次数: |
4448 次 |
| 最近记录: |