Excel 用户窗体内的Progressbar

Excel 用户窗体内的Progressbar,excel,vba,ms-word,Excel,Vba,Ms Word,我试图在一个用户表单中创建一个进度条,而不是一个单独的进度条,因为无论是在上面还是在后台,这似乎都是不可靠的。因此progressbar工作正常,但是它会为progressbar执行的每次更新重新绘制整个用户表单。是否可以只刷新progressbar而不是整个用户表单 我当前的代码如下所示: Public Sub progress(pctCompl As Single) Me.Text.caption = Format(pctCompl, "##") & "% Completed

我试图在一个用户表单中创建一个进度条,而不是一个单独的进度条,因为无论是在上面还是在后台,这似乎都是不可靠的。因此progressbar工作正常,但是它会为progressbar执行的每次更新重新绘制整个用户表单。是否可以只刷新progressbar而不是整个用户表单

我当前的代码如下所示:

Public Sub progress(pctCompl As Single)
    Me.Text.caption = Format(pctCompl, "##") & "% Completed"
    Me.Bar.width = Round(pctCompl * 10, 5)
    If Me.Bar.width Mod 20 = 0# Then
        Me.Repaint
    End If
    DoEvents
End Sub

在对象浏览器中搜索
MSForm
库中的
Repaint
时,将找到
UserForm
,但也会找到
Frame
。因此,如果您想直接使用用户表单上的进度,那么您可以尝试将
包装到
MSForms.Frame
中,当需要重新绘制时,只需为此帧调用它即可。在这种情况下,剩余的用户窗体及其控件不应受到此影响,只应重新绘制框架

Me.Frame1.Repaint ' Me is the main user form

而不是有一个单独的进度条,因为这似乎是 如果在顶部或后台,则在这方面不可靠

这可以通过单独的模态形式轻松解决,该模态形式将显示进度。此表单将具有取消按钮,并在显示时引发事件
Start
,以便调用表单可以开始执行长时间运行的作业,并在用户过早单击取消按钮取消进程时引发事件
cancel
。例如,HTH

UserFormProgress

UserFormMain

选项显式
Private WithEvents progress作为UserFormProgress
私有cancelProgresForm为布尔值
Private Sub CommandButtonDoomethingLongRunning_Click()
Set progress=New UserFormProgress
'设置进度表
'progress.Caption=。。。
'progress.MaxValue=123456789
进度。显示vbModal
端接头
专用子进程_Start()
'从进度窗体回调,此处运行运行进程
'计算一些完整的状态值
Dim complete值为Long
completeValue=0
cancelProgresForm=False
做
completeValue=completeValue+1
更新完成值
多芬特
在cancelProgresForm=False且completeValue
什么类型的控件是
Bar
?尝试使用
DoEvents
而不是
Me。重新绘制
可能会稍微慢一点,但用户表单不应闪烁。为什么进度条不合适?
Option Explicit

Public Event Start()
Public Event Cancel(ByRef ignore As Boolean)

Private Sub CommandButtonCancel_Click()
    Dim ignoreCance As Boolean
    ignoreCance = False
    RaiseEvent Cancel(ignoreCance)
    If ignoreCance Then
        Exit Sub
    Else
        Unload Me
    End If
End Sub

Private Sub UserForm_Activate()
    Static isActivated As Boolean
    Me.Repaint
    If Not isActivated Then
        ' ensure only once activation
        isActivated = True
        RaiseEvent Start
        Unload Me
    End If
End Sub

Public Sub Update(ByVal newValue As Long)
    ' update progrress bar here
    ' Pseudo code: Me.Progress.Value = newValue etc.
    Me.Repaint
End Sub
Option Explicit

Private WithEvents progress As UserFormProgress
Private cancelProgresForm As Boolean

Private Sub CommandButtonDoSomethingLongRunning_Click()
    Set progress = New UserFormProgress
    ' Set progress form
    ' progress.Caption = ...
    ' progress.MaxValue = 123456789
    progress.Show vbModal
End Sub

Private Sub progress_Start()
    ' Callback from progress form, here runs the lung running process
    ' calculate some complete status value
    Dim completeValue As Long
    completeValue = 0
    cancelProgresForm = False
    Do
        completeValue = completeValue + 1
        progress.Update completeValue
        DoEvents
    Loop While cancelProgresForm = False And completeValue < progres.MaxValue 
End Sub

Private Sub progress_Cancel(ignore As Boolean)
    If MsgBox("Do you want to cancel?", vbQuestion Or vbYesNo) = vbNo Then
        ignore = True
    Else
        ignore = False
        cancelProgresForm = True
    End If
End Sub