弹出表格作为Access中的进度栏,要添加退出按钮
伙计们,所以我正在尝试为MS Access中的另一种表格制作进度条。进度条本质上是一个很小的弹出窗体,带有与非常耗时的子例程的进度相关联的控件,这里没有任何问题。但是,我试图在进度栏上放置一个“取消”按钮,但是当子例程在后台运行时,我无法在进度栏窗体中单击任何内容。我基本上得到了沙漏图标,我试图用vba代码禁用沙漏图标,但是没有运气。
本质上,我想知道是否有一种方法可以让我在执行子例程时单击其他表单上的按钮。我认为添加我的代码不会帮助您,但如果您希望看到它,请发表评论。谢谢!
答案 0 :(得分:0)
是的,有可能。使用DoEvents
告诉VBA继续泵送/处理Windows消息;结果可能不像真正的异步代码那样响应迅速,但是应该足以允许单击[取消]按钮并取消进程。
this article(免责声明:我写过)中的代码最初是为Excel编写的,并且使用了UserForm
(当主机为Access时,它隐藏在VBE中,但是Access VBA项目可以绝对包含和使用UserForm
个模块)。
您将要删除Excel特定的位,例如QualifyMacroName
:
Private Function QualifyMacroName(ByVal book As Workbook, ByVal procedure As String) As String
QualifyMacroName = "'" & book.FullName & "'!" & procedure
End Function
然后修改Create
工厂方法以 require instance
参数,如下所示:
Public Function Create(ByVal procedure As String, ByVal instance As Object, Optional ByVal initialLabelValue As String, Optional ByVal initialCaptionValue As String, Optional ByVal completedSleepMilliseconds As Long = 1000, Optional canCancel As Boolean = False) As ProgressIndicator
Dim result As ProgressIndicator
Set result = New ProgressIndicator
result.Cancellable = canCancel
result.SleepMilliseconds = completedSleepMilliseconds
If Not instance Is Nothing Then
Set result.OwnerInstance = instance
Else
Err.Raise 5, TypeName(Me), "Invalid argument: 'instance' must be a valid object reference."
End If
result.ProcedureName = procedure
If initialLabelValue <> vbNullString Then result.ProgressView.ProgressLabel = initialLabelValue
If initialCaptionValue <> vbNullString Then result.ProgressView.Caption = initialCaptionValue
Set Create = result
End Function
一旦编译,您可以通过注册执行实际工作的worker方法来使用ProgressIndicator
,例如:
With ProgressIndicator.Create("Run", New MyLongRunningMacro, canCancel:=True)
.Execute
End With
其中MyLongRunningMacro
是带有Run
方法的类模块,可能看起来像这样:
Public Sub Run(ByVal progress As ProgressIndicator)
Dim thingsDone As Long
For Each thing In ThingsToDo
Application.Run thing
thingsDone = thingsDone + 1
progress.UpdatePercent thingsDone / ThingsToDo.Count
If ShouldCancel(progress) Then
' user confirmed they want to cancel the whole thing.
' perform any clean-up or rollback here
Exit Sub
End If
Next
End Sub
Private Function ShouldCancel(ByVal progress As ProgressIndicator) As Boolean
If progress.IsCancelRequested Then
If MsgBox("Cancel this operation?", vbYesNo) = vbYes Then
ShouldCancel = True
Else
progress.AbortCancellation
End If
End If
End Function
例如,ThingsToDo
可能是要执行的宏的集合。通过循环报告进度百分比比较容易,但是虽然它也可以处理一系列操作,但是干净地处理取消会比较困难:
Public Sub Run(ByVal progress As ProgressIndicator)
Dim thingsDone As Long
DoThingOne
If Not UpdateAndContinue(progress, 0.33) Then Exit Sub
DoThingTwo
If Not UpdateAndContinue(progress, 0.66) Then Exit Sub
DoThingThree
If Not UpdateAndContinue(progress, 1) Then Exit Sub
End Sub
Private Function UpdateAndContinue(ByVal progress As ProgressIndicator, ByVal percentCompleted As Double) As Boolean
progress.UpdatePercent percentCompleted
If ShouldCancel(progress) Then
' user confirmed they want to cancel the whole thing.
' perform any clean-up or rollback here
Exit Function
Else
UpdateAndContinue = True
End If
End Function