excel 防止模态窗体在退出时关闭所有打开的非模态窗体

ibps3vxo  于 2023-01-14  发布在  其他
关注(0)|答案(3)|浏览(205)

在Excel中使用VBA窗体时,我遇到了一些奇怪的行为。我有一个调用无模式窗体的模块,该模块充当调用其他窗体的中心。其他窗体以模式调用。问题是,一旦子窗体隐藏或卸载,父无模式窗体也会关闭。
我试图找到一个答案,但即使有问题存在沿着这些路线,他们都没有提供一个答案,工程。
经过一段时间的测试,我确定任何数量的打开的无模式表单都会以相同的方式关闭。此外,我无法在新的工作簿中使用最小模型重现这个问题。之后,我继续逐块添加原始工作簿的所有组件(有几个模块,10-20个类和几个表单),以查看问题何时出现。
当我发现这个问题没有再次出现,甚至在我导入了所有的东西之后,我同时感到宽慰和烦恼。我的结论是,这是一种侥幸,不会再困扰我了。但是,不久之后,当我添加另一个这样的子窗体,使用相同的调用代码时,同样的情况又开始在新窗体上发生,而不是在旧窗体上。
然后,我继续导出这个不正常的表单,从工作簿中删除它,然后导入它。瞧,它又工作了。
以前有没有人遇到过这样的行为?我做错了什么吗?或者我应该把这当作一个烦人但可规避的bug?
下面请查找问题的最小模型,排除所有内容:
调用主窗体的模块:

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企业版6.1.7601(服务包1内部版本7601)
Excel版本:办公软件Excel 2016(16.0.6729.1014),64位
VBA版本:7.1

pcrecxhr

pcrecxhr1#

我以前遇到过这个问题。不确定这个问题是否已经解决,但对于希望修复这个问题的未来用户:
唯一的方法,我已经发现修复这个恼人的和间歇性的问题是显示用户窗体模态,然后隐藏和重新显示用户窗体模态。

Unload MyChildUserform
MyParentUserform.Show vbModal
MyParentUserform.Hide
MyParentUserform.Show vbModeless

这是笨重和恼人的,但它似乎工作,是一致的,至少。

    • 编辑:**

IMHO一个更好的解决方案是自己控制表单的模态。
声明:

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
laik7k3q

laik7k3q2#

我今天被这个问题困扰着,我发现了一个工作,它可以在模态形式的关闭事件上停止非模态形式的关闭。
只需将UserForm属性“ShowModal“设置为True
UserForm ShowModal Property to True
然后,当显示表单时,只需使用UserForm.Show(即 * 不指定 * vbModalvbModeless)。在我的工作区中,我将此.Show调用包含在相应模态UserForm的UserForm_Initialize事件中。现在,当您关闭此模态表单时,它不会取出所有父非模态表单。
这个问题对我来说是至关重要的,因为我的模态用户窗体必须是模态的,因为它包含一个RefEdit控件。经过一些进一步的调查和故障排除,我不能得出确切的是什么原因导致这个问题的模态窗体。我希望有人在VBA更好的知识来看看,但我担心他们可能都转移到绿色牧场...

quhf5bfb

quhf5bfb3#

我知道这是一个 * 真的 * 老线索,但我发现它寻找这个问题的答案,所以我想我会分享我的解决方案,希望它能帮助别人。
我发现的另一个选项是不将模态表单创建为新表单;相反,如果你只是显示一个模态表单而不是初始化一个新的表单,它将正确隐藏而不隐藏父表单。当然,如果你需要同时拥有这个特定表单的多个示例,这是行不通的,但是对于我的目的(它会打开一个搜索用户表单来选择一个值,然后传递回父表单),隐藏之后对我来说是有效的。

相关问题