- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
史前
我已经阅读了创建表单的最佳实践,其中涉及这样一个事实:人们应该始终引用表单的对象而不是表单本身。因此,我决定为自己构建一个样板表单。
问题
一切都很顺利,直到我决定用右上角的红色X
关闭表单。关闭就OK了但是,当我尝试再次打开表单时,我收到此运行时错误:
错误出现在 objPresenter.Show
上(请参阅下面的代码)。显然,它没有进入上面的if
中。但问题是 X
的关闭不能正常工作。当我通过 End
按钮关闭表单时,一切正常。甚至,如果我将关闭代码从 btnEnd 复制到 UserForm_QueryClose ,它仍然无法正常工作。
表格
因此,我有一个 modMain
、frmMain
和 clsSummaryPresenter
,它们都负责处理表单。我从 modMain
我的表单如下所示:
它有btnRun
、btnExit
、lblInfo
。类的名称是frmMain
。
代码
在frmMain
中:
Option Explicit
Public Event OnRunReport()
Public Event OnExit()
Public Property Get InformationText() As String
InformationText = lblInfo.Caption
End Property
Public Property Let InformationText(ByVal value As String)
lblInfo.Caption = value
End Property
Public Property Get InformationCaption() As String
InformationCaption = Caption
End Property
Public Property Let InformationCaption(ByVal value As String)
Caption = value
End Property
Private Sub btnRun_Click()
RaiseEvent OnRunReport
End Sub
Private Sub btnExit_Click()
RaiseEvent OnExit
End Sub
Private Sub UserForm_QueryClose(CloseMode As Integer, Cancel As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
Hide
'Even if I change the two lines above with this the error happens:
'RaiseEvent OnExit
'However, if I simply write END in stead of those two lines
'anything works quite ok...
'but that is a bit brutal.
End If
End Sub
在clsSummaryPresenter
Option Explicit
Private WithEvents objSummaryForm As frmMain
Private Sub Class_Initialize()
Set objSummaryForm = New frmMain
End Sub
Private Sub Class_Terminate()
Set objSummaryForm = Nothing
End Sub
Public Sub Show()
If Not objSummaryForm.Visible Then
objSummaryForm.Show vbModeless
Call ChangeLabelAndCaption("Press Run to Start", "Starting")
End If
With objSummaryForm
.Top = CLng((Application.Height / 2 + Application.Top) - .Height / 2)
.Left = CLng((Application.Width / 2 + Application.Left) - .Width / 2)
End With
End Sub
Public Sub Hide()
If objSummaryForm.Visible Then objSummaryForm.Hide
End Sub
Public Sub ChangeLabelAndCaption(strLabelInfo As String, strCaption As String)
objSummaryForm.InformationText = strLabelInfo
objSummaryForm.InformationCaption = strCaption
objSummaryForm.Repaint
End Sub
Private Sub objSummaryForm_OnRunReport()
MainGenerateReport
Refresh
End Sub
Private Sub objSummaryForm_OnExit()
Hide
End Sub
Public Sub Refresh()
With objSummaryForm
.lblInfo = "Ready"
.Caption = "Task performed"
End With
End Sub
在modMain
Option Explicit
Private objPresenter As clsSummaryPresenter
Public Sub MainGenerateReport()
objPresenter.ChangeLabelAndCaption "Starting and running...", "Running..."
GenerateNumbers
End Sub
Public Sub GenerateNumbers()
Dim lngLong As Long
Dim lngLong2 As Long
tblMain.Cells.Clear
For lngLong = 1 To 4
For lngLong2 = 1 To 1
tblMain.Cells(lngLong, lngLong2) = lngLong * lngLong2
Next lngLong2
Next lngLong
End Sub
Public Sub ShowMainForm()
If (objPresenter Is Nothing) Then
Set objPresenter = New clsSummaryPresenter
End If
objPresenter.Show
End Sub
问题
再说一遍,为什么我无法用红色X
关闭表单?我可以用 End
替换 UserForm_QueryClose
中的代码,但这有点残酷。有什么想法吗?
最佳答案
将表单的模式从 vbModeless
更改为 vbModal
可以让您更早地获得更丰富的失败信息:
问题似乎是因为 QueryClose
处理程序中的 Cancel = True
赋值由于某种原因不起作用。
QueryClose
处理程序的签名如下:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
你的是:
Private Sub UserForm_QueryClose(CloseMode As Integer, Cancel As Integer)
您不应该自己手动键入这些处理程序签名 - 相反,请使用代码 Pane 右上角的下拉菜单,并让 VBE 为您生成处理程序 stub :
这样,您的处理程序签名将始终与其所属的接口(interface)相匹配。
VBA 并不真正关心处理程序中的参数名称:运行时匹配处理程序签名的方式是根据预期的参数索引及其类型进行匹配。由于两个 QueryClose
参数都是 Integer
值,因此反转它们可以很好地编译 - 除非您设置 Cancel = True
,运行时看到的是您已分配 CloseMode = -1
并保留 Cancel 参数。
这意味着您的表单不会取消其关闭,因此该对象每次都会被销毁。
反转 QueryClose
处理程序中的参数,一切都工作得很好并且完全符合预期。
关于vba - 如果从右上角关闭 Excel-VBA 表单的实例,则打开时会出现错误 红色 `X`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42255695/
我创建了一个分支来开发新功能。由于这个新功能完全是作为一个新项目开发的,唯一可能的冲突来源是解决方案文件。 随着功能的开发,主分支更新了几次。当我完成开发和测试时,我做了: git checkout
我是一名优秀的程序员,十分优秀!