防止在退出时关闭所有无模式打开表单的模态表单 [英] Prevent a Modal form closing all Modeless open forms upon exit
问题描述
在Excel中使用VBA表单时,我遇到了一些特殊行为.我有一个模块,该模块调用无模式表单,该表单用作调用其他表单的集线器.其他形式称为模态.问题是,一旦子窗体被隐藏或卸载,父无模式窗体也将关闭.
I ran into some peculiar behavior while using VBA Forms in Excel. I have a module which invokes a Modeless form, which serves as a hub to call other forms. The other forms are invoked as Modal. The problem is, as soon as the the child form is hidden or unloaded, the parent Modeless form gets closed as well.
我试图找到答案,但是即使存在这些问题,也没有一个提供有效的答案.
I tried to find an answer to this, but even though there are questions that exist along these lines, none of them provided an answer that works.
经过一些测试,我确定将以相同的方式关闭任意数量的打开的无模式表单.此外,我无法在新工作簿中使用最小模型来重现该问题.之后,我继续逐个添加原始工作簿的所有组件(有几个模块,10-20个类和几种形式),以查看问题何时出现.
After a bit of testing, I determined any number of open Modeless forms would be closed in the same way. Furthermore, I wasn't able to reproduce the issue using a minimal model in a new Workbook. After that, I went on to add piece-by-piece all the components (there are a few modules, 10-20 classes, and a few forms) of the original Workbook to see when the problem comes up.
当我发现即使完全导入所有内容后问题仍然没有出现时,我却同时感到宽慰和恼火.我的结论是,这是一种fl幸,不会再打扰我了.但是,不久之后,当我添加另一个具有相同调用代码的子窗体时,新窗体又开始发生相同的情况,而旧窗体又没有发生.
I was simultaneously relieved and annoyed when I found that the problem didn't reappear even after I imported absolutely everything back. My conclusion was that this was some kind of a fluke that won't bother me again. But, soon after, when I added another such child form, with identical calling code, the same started happening again with the new one, but not with the old one.
然后我继续导出行为异常的表单,将其从工作簿中删除,然后导入.瞧,它又奏效了.
I then proceeded to export the misbehaving form, delete it from the workbook, and then import it. And voila, it worked again.
有没有人以前遇到过这种行为?难道我做错了什么?还是应该将其视为烦人但可以规避的错误?
Is there anyone who encountered such behavior before? Am I doing something wrong? Or should I treat this as an annoying but circumventable bug?
请在下面的最小问题模型中查找,但不包括所有内容:
Please find below the minimum model of the problem, excluding all the content:
模块调用主要形式:
Sub testA()
Dim main1 As MainForm1
Set main1 = New MainForm1
main1.Show (vbModeless)
End Sub
主要形式:
Option Explicit
Dim formobject As frmPickInjection
Private Sub CommandButton1_Click()
Set formobject = New frmPickInjection
With formobject
.Show (vbModal)
Label1.Caption = CStr(.SelectedInjection)
End With
End Sub
子表格:
Option Explicit
Public passvar As Boolean
Private Sub CheckBox1_Click()
passvar = CheckBox1.Value
End Sub
系统:Microsoft Windows 7 Enterprise 6.1.7601(Service Pack 1内部版本7601)
System: Microsoft Windows 7 Enterprise 6.1.7601 (Service Pack 1 Build 7601)
Excel版本:Office365 Excel 2016(16.0.6729.1014),64位
Excel version: Office365 Excel 2016 (16.0.6729.1014), 64 bit
VBA版本:7.1
VBA version: 7.1
推荐答案
我以前遇到过此问题. 不确定是否已解决此问题,但对于希望解决此问题的未来用户:
I've encountered this problem before. Unsure whether this has already been resolved or not, but for future users looking to fix this:
我发现解决此烦人且间歇性问题的唯一方法是以模态显示用户表单,然后以隐藏方式隐藏并重新显示用户表单.
The only way I have found of fixing this annoying and intermittent issue is to show the userform Modally then Hide and re-show the userform Modelessly.
Unload MyChildUserform
MyParentUserform.Show vbModal
MyParentUserform.Hide
MyParentUserform.Show vbModeless
笨拙而烦人,但它似乎有效并且至少是一致的.
It's clunky and annoying, but it seems to work and is consistent at the least.
恕我直言,更好的解决方案是自己控制表单的形式.
IMHO A much better solution is to control the modality of the form yourself.
声明:
Public Declare Function EnableWindow lib "user32.dll" (ByVal hWnd as Long, ByVal fEnable as Long) as Long
Public Declare Function FindWindow lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName as String, ByVal lpWindowName as String) as Long
Public Enum MakeAsModal
Modal = 0
Modeless = 1
End Enum
Public ghWndParent as Long
公共替换:
Public Sub ChangeModality(ByRef hWnd as Long, ByVal isModal as MakeAsModal)
On Error Resume Next
Dim RetVal as Long
RetVal = EnableWindow(hWnd,isModal)
End Sub
父母表格:
Private Sub Userform_Initialize()
'Parent Form
ghWndParent = FindWindow(vbNullString, Me.Caption)
End Sub
Private Sub CallChild()
'Parent Form
ChildUserform.Show vbModeless
ChangeModality ghWndParent, Modal
End Sub
子表格:
Private Sub Userform_QueryClose(Cancel As Integer, CloseMode as Integer)
'Child Form
ChangeModality ghWndParent, Modeless
End Sub
这篇关于防止在退出时关闭所有无模式打开表单的模态表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!