是否有一个无模式的用户表单,同时仍然暂停代码执行,如模式表单?
我希望显示userform,但仍允许与父程序进行交互。模态表单阻止与父程序的交互。一个无模式的形式可以工作,但我希望代码执行在表单启动时暂停。
我通过创建一个无限循环来检查表单是否可见,但这看起来有点hacky。
Public Sub GetFormInfoAndDoStuff
ufForm.show vbModeless
Do while ufForm.Visible
DoEvents
Loop
' Do other stuff dependent on form
End Sub
已编辑以澄清.show之后存在的代码,必须在用户表单完成后执行
答案 0 :(得分:4)
您应该能够将表单显示为vbModeless
,并且仅在特别请求时执行代码,即来自CommandButton
或其他控件。
然后,您可以通过“X”按钮或通过调用UserForm_Terminate
事件的其他控件将表单显示/显示,直到它被特别关闭为止。
为了实现这一点,您可能需要将一些可执行代码移动到另一个子例程和/或模块中,并从CommandButton_Click
事件中调用此子例程。
你已经有一个包含如下行的子程序:
Sub ShowTheForm()
UserForm1.Show vbModeless
End Sub
因此,表单正确显示以允许用户输入到父应用程序。
您实际上不需要在上面的模块中添加任何其他代码。我们将其他代码放在其他modules / subs中,然后从用户控件(如命令按钮)调用它。
示例:强>
获取所有可执行代码,并将其放入另一个子例程(如果它适合您的组织偏好,另一个模块),例如:
Sub MyMacro(msg$)
MsgBox msg
End Sub
在UserForm上,添加一个命令按钮并为其分配以下代码:
Sub CommandButton1_Click()
MyMacro "hello"
End Sub
现在,表单将一直显示,直到用户单击“X”按钮。代码仅在从命令按钮调用时运行。
编辑澄清
您无需使用此方法“暂停”执行。表单无模式显示后执行结束,表单仍然存在。该对象有一些事件可用于触发进一步执行代码。
答案 1 :(得分:0)
这就是我的所作所为。
此示例适用于我称为" Find Header"的表单。代码试图找到几个列标题,但其中一些列标题可能丢失(标题文本可能已被随机覆盖),所以我可能需要暂停并要求用户定位(单击)我的一些标题:
首先,将此声明放在标准模块:
中Public bDlgFindHeaderIsShowingModeless As Boolean
然后,将其放入任何取消无模式对话框的按钮或其他控件的事件过程中,例如表单的“单击事件”和“取消”按钮:
bDlgFindHeaderIsShowingModeless = False
然后,将其放在代码中的任何位置,以便在暂停用户交互时显示无模式窗体:
bDlgFindHeaderIsShowingModeless = True 'init
frmFindHeader.Show vbModeless
Do
If Not bDlgFindHeaderIsShowingModeless Then Exit Do
DoEvents
Loop
是的,它会搅动CPU,因此如果您使用的是单核处理器,并且运行着至关重要的后台进程,您可能不想这样做。但它有效;在无模式窗体显示时,用户可以轻松,顺畅地与Excel交互。用户并不觉得他们正在无休止地对抗。
答案 2 :(得分:0)
最佳方法是使用两个不同的子。我能够解决此问题,而无需按如下方式拆分子项目:
Public Mode as Boolean
Sub Stuff()
If Mode Then
Goto Continue
End If
'Code before Userform
Mode = True
Userform.Show vbModeless
Exit Sub
Continue:
Mode = False
'Rest of your code
End Sub
我将“模式”(Mode)设置为全局变量,因为我将此用户窗体用于多个子项。如果使用单个子,则可以在本地使用。通过在“ ThisWorkbook”选项卡下并添加以下代码,我在打开此工作簿时也将“模式”设置为false:
Private Sub Workbook_Open()
Mode = False
End Sub
仅当您将用户表单用于多个子菜单时,才需要再次使用。 按下“继续”按钮时,最后将此代码添加到您的用户表单代码下。
Private Sub Confirm_Click()
Userform.hide
if Mode Then
Call Stuff
End If
End Sub
如果您仅使用one子方法,请跳过if语句,仅调用该子方法。