在VBA中将ProgressBar用户窗体显示为模态还是非模态更好?
在VBA中将ProgressBar用户窗体显示为模态还是非模态更好?在VBA中制定进度指标的最佳实践是什么 无模式用户表单需要使用在VBA中将ProgressBar用户窗体显示为模态还是非模态更好?,vba,modal-dialog,userform,modeless,progress-indicator,Vba,Modal Dialog,Userform,Modeless,Progress Indicator,在VBA中将ProgressBar用户窗体显示为模态还是非模态更好?在VBA中制定进度指标的最佳实践是什么 无模式用户表单需要使用Application.Interactive=False,而模式用户表单本质上阻止与应用程序的任何交互,直到核心过程完成或取消 但是,如果使用了Application.Interactive=False,Esc键会中断代码执行,因此在用户窗体和调用过程中都需要使用Application.enableCanceKey=xlErrorHandler和错误处理(Err.N
Application.Interactive=False
,而模式用户表单本质上阻止与应用程序的任何交互,直到核心过程完成或取消
但是,如果使用了Application.Interactive=False
,Esc键会中断代码执行,因此在用户窗体和调用过程中都需要使用Application.enableCanceKey=xlErrorHandler
和错误处理(Err.Number=18
)
资源密集型调用过程还可能导致无模式用户窗体中的CommandButton\u Click
和UserForm\u Activate
事件发生错误
一般来说,使用模态用户表单的进度指示器似乎更简单,因为正在执行的代码完全包含在用户表单模块中,并且不需要传递变量
但是,将模态UserForms用于进度指示器的问题是,每个需要进度指示器的过程都需要一个单独的UserForm模块,因为调用过程必须位于UserForm\u Activate过程内部
因此,虽然在无模式用户表单中可以有一个可重用的进度指示器,但它的可靠性不如在多模式用户表单中执行代码
哪条路更好
谢谢 还有第三种方法,使用
应用程序.StatusBar
。
您甚至可以使用U+25A0和U+25A1字符序列来模拟一个真正的进度条。我将结束这一部分,并说Modal是赢家。我已经尝试了这两种方法,但您最终试图用无模式用户表单来填补太多的漏洞。模态更难,因为它更严格,但它鼓励您将代码分成更小的块,这从长远来看会更好。绝对是模态的。
如果你要考虑非模态,你应该在分离的进程线程上运行它,而不是在Excel。EXE主线程上。 < P>我认为最初的主题是值得回答的,因为问题很好地被谷歌最先发现。 第1节-理论 首先要说的是,在模块之间传递变量一点也不困难 您需要做的唯一一件事是创建一个单独的模块,并将所有全局变量放在那里。然后你就可以在任何地方阅读所有表格、表格、模块 第二件事是窗口应该是无模式的。为什么? 答案是保持代码的移动性,即
Sub UpdateProgressBar(PCTDone_in As Single)
With UserForm1
' Update the Caption property of the Frame control.
.FrameProgress.Caption = Format(PCTDone_in, "0%")
' Widen the Label control.
.LabelProgress.Width = PCTDone_in * _
(.FrameProgress.Width)
' Display the current file from global variable
.Label1.Caption = Declaration.CurrentFile
End With
End Sub
4) 在任何其他模块中,我们必须具有执行例行程序的功能或程序/子模块:
For i=1 to All_Files
Declaration.CurrentFile = myFiles (i)
FormFnc.UpdateProgressBar (i / .Range("C11").Value)
DoEvents
If Declaration.StopForce = 1 Then
GoTo 3
End If
Next i
事实上,您有以下属性,根据您的需要产生利弊:
Type | Impact on UI | Impact on caller execution
----------|--------------|-----------------------------
Modal | Blocked | Blocked until Form is closed
Modeless | Not blocked | Continues
如果要阻止UI并让调用方继续,则需要使用
应用程序以模式模式打开表单。OnTime
感谢GSerg的建议,但我过去曾尝试过使用该方法,但Excel 2007停止更新窗口并显示“无响应”在应用程序窗口的顶部。我对office 2007不是很有经验,但是如果在将值设置为状态栏后立即调用DoEvents会怎么样?嗯,这很有效。哇,这是个不错的选择,不是吗!谢谢你,格斯伯格!使用状态栏作为进度指示器的一个问题是无法提供取消按钮。这项技术不错,但它并不能真正回答关于模态/非模态的最佳实践问题,在ausing statusbar上有一个技术答案。请注意,无模式用户表单在Mac OSI上似乎根本不起作用。在试图通过应用程序打开表单时,会收到一条错误消息。OnTime
(我尝试了不同的变体)。你用什么语法来解释这个?
Type | Impact on UI | Impact on caller execution
----------|--------------|-----------------------------
Modal | Blocked | Blocked until Form is closed
Modeless | Not blocked | Continues