Frothingslosh
Premier Pale Stale Ale
- Local time
- Today, 05:07
- Joined
- Oct 17, 2012
- Messages
- 3,276
One of the most commonly asked questions I’ve seen on this and other MS Access sites has got to be ‘How do I show a progress bar?’ While Access has a built-in meter bar, upon which I will elaborate momentarily, I’ve also ended up having to create a couple other options that I’ll share.
EDIT: Please see addendum at the end of this post for issues regarding accde/mde files.
EDIT: Changes specific to the newest version are italicized.
First off, we have the built-in meter bar, accessed via the SysCmd object. Microsoft has an article on it HERE, but here is an overview:
OPTION 1 – BUILT-IN METER
Positives:
Step 1: Initialize the meter. You do so with the command
***
Sometimes, however, this meter isn’t what you need. It can be hard to see, and sometimes you want to make absolutely certain that your user can see your progress. Sometimes one meter won’t cut it, and you need a linked pair, with one showing task progress while another shows overall progress. For those, I wound up writing a couple custom classes, which I have attached to this post.
OPTION 2: clsMeter (Single Meter Bar)
Positives:
Step 1: Dim as a clsMeter, then create a new instance of the meter object; example:
Optional Step: You can alter the displayed text for the task as follows:
Positives:
Step 1: As with clsMeter, you must first Dim a variable as a clsDualMeter object, and then create it.
Step 7: Once the project is 100% complete, the code will pause if indicated back in step 1, and then the meter form will be closed.
An example where you might need to change the project description might be this:
***
I have updated an Access 2003 database with both class modules as well as a test form so you can see it work as well as have working examples of the various methods. If you have any concerns or suggestions, please post them; I do have a few updates I want to make to these when I have the time and desire.
As per this forum’s rules, if you have questions about this, please PM me directly, and I will reply as soon as I am able.
***
ADDENDUM July 11, 2014
As CJLondon pointed out to me, this code will not be able to generate new forms in an mde/accde file. If you use my code in those types of files, you will need to have the forms pre-generated. You can certainly do that by running the test form in Meter.mdb, but just to play it safe, I'm uploading a file containing the two forms in question as well as the module.
EDIT: Please see addendum at the end of this post for issues regarding accde/mde files.
EDIT: Changes specific to the newest version are italicized.
First off, we have the built-in meter bar, accessed via the SysCmd object. Microsoft has an article on it HERE, but here is an overview:
OPTION 1 – BUILT-IN METER
Positives:
- Built-in function, so normally fast to execute
- Uses no extra system resources
- Fairly straightforward
- Hard to see (no pop-up, only shows on bottom-left of screen)
- Hides the progress meter you normally see when action queries process.
- If you’re doing thousands of iterations, this can drastically slow down processing if you’re updating the meter literally every iteration.
Step 1: Initialize the meter. You do so with the command
Code:
SysCmd acSysCmdInitMeter, Arg1, Arg2
- Arg 1 is the text you want displayed on the status bar.
- Arg 2 is a long integer used to indicate the maximum progress. For example, if you are running 27 loops, you would include 27. If you wanted to track percent complete, you might set it to be 100.
- NOTE: The displayed value of the bar starts at 0, meaning the meter will show empty.
Code:
SysCmd acSysCmdUpdateMeter, Arg1
- Arg1 is a long integer indicating current progress. If the max progress (Arg 2 above) is 100 and you set Arg1 here to 27, the meter will show at 27% full.
- NOTE: Values of Arg1 set higher than Arg2 was in Step 1 will show 100% complete.
Code:
SysCmd acSysCmdRemoveMeter
***
Sometimes, however, this meter isn’t what you need. It can be hard to see, and sometimes you want to make absolutely certain that your user can see your progress. Sometimes one meter won’t cut it, and you need a linked pair, with one showing task progress while another shows overall progress. For those, I wound up writing a couple custom classes, which I have attached to this post.
OPTION 2: clsMeter (Single Meter Bar)
Positives:
- Uses a pop-up window, so much more visible to the user.
- Progress bar is slightly more flexible than the hash marks Option 1 uses.
- Includes a few options for a slightly more flexible display.
- Used similarly to Option 1.
- Uses a custom class, so uses system resources
- Technically runs slightly slower due to being a class rather than being inbuilt.
- Little overall difference from Option 1 other than visibility.
- As with Option 1, action query progress cannot be tracked with this meter.
Step 1: Dim as a clsMeter, then create a new instance of the meter object; example:
Code:
Dim Meter as clsMeter
Set Meter = New clsMeter
- NOTE: When this object is initialized, the code will look for ‘frmMeter’. If that form does not exist, it will create and save it.
- The remaining examples will assume that the object being referenced was named ‘Meter’.
Code:
Meter.Initialize ActionCount, DisplayText, PauseOnUpdate, PauseDuration, BarColor, FormColor
- ActionCount (Long Integer) is the number of actions covered by this meter, similar to Arg2 in acSysCmdInitMeter above.
- DisplayText (Text) is the text to be displayed above the progress bar. The text field that displays this is only 3 inches in length, so keep that in mind when setting this argument.
- PauseOnUpdate (Y/N) is an optional Boolean field that defaults to TRUE. It indicates whether or not the code should pause once progress has reached 100% (generally for the sake of visibility).
- PauseDuration (Single) is optional and only applies if PauseOnUpdate is TRUE. This is the length of time the system pauses once complete. This can range from 1 to 10 seconds, but the default is 1. Note that this argument will accept fractions of a second.
- BarColor is an optional Long Integer field used to set the color of the progress bar.
- Leaving it out uses the normal values in the form (normally green).
- This is a long variable representing the color from the color pallette.
- FormColor an optional Long Integer field used to set the background color of the form.
- Leaving it out uses the normal background color of the form (normally white).
- This is a long variable representing the color from the color pallette.
- NOTE: Current progress will start at 0% complete.
- NOTE: This is the step where frmMeter is displayed to the user. The form is both modal and a pop-up, so it will effectively lock the user out of doing anything else with the database until processing is completed.
Code:
Meter.Update ActionCount
- ActionCount is the current value of whatever counter you’re using – iteration number, task number completed, whatever you’re tracking.
- NOTE: The system only updates the visible meter whenever at least 1% progress has been made since the last display update. If you’re only running 8 loops, the display will update every time. If you’re running 10,000 loops, however, the display will be updated every 100. This is to cut down on unnecessary screen updates that slow the system down. The system still tracks the exact progress internally, however.
- NOTE: After a screen update, the system pauses 0.002 seconds. This ensures that the progress meter moves at a speed visible to the human eye. Any value lower than 0.002 seconds is treated by Access as 0 seconds, and if your iterations or tasks finish quickly enough, the meter can well reach 100% instantly if the pause is set below 0.002.
- NOTE: Once the meter reaches 100%, it will pause for the length of time indicated by Step 2, and then close the display form. As with any other object, the object variable itself will remain allocated until you destroy it or terminate code execution.
Optional Step: You can alter the displayed text for the task as follows:
Code:
Meter.ChangeDesc NewDescription
- NewDescription is a string that will replace the displayed description text.
Positives:
- High visibility due to pop-up meter display
- Uses dual meter bars, so can track tasks and overall progress simultaneously
- Notably more complicated than either option above, as it involves both tasks and the ‘project’ – the overall process you’re executing.
- As with clsMeter, slower and more resource-intensive than the built-in option.
- As with Options 1 and 2, this meter cannot track action query progress.
Step 1: As with clsMeter, you must first Dim a variable as a clsDualMeter object, and then create it.
Code:
Dim Meter as clsDualMeter
Set Meter = New clsDualMeter
- NOTE: When this object is initialized, the code will look for ‘frmDualMeter’. If that form does not exist, it will create and save it.
- The remaining examples will assume that the object being referenced was named ‘Meter’.
Code:
Meter.InitializeProject NumberOfTasks, ProjectDescription, PauseOnTaskComplete, TaskCompletePauseDuration, PauseOnProjectComplete, ProjectCompletePauseDuration, BarColor, FormColor
- NumberOfTasks (Long Integer) is the total number of tasks to be completed with this project. For example, you may be exporting ten spreadsheets.
- ProjectDescription (String) is the text description for the project itself. An example might be “Exporting Employee Status Reports”. This is displayed in a 3 inch text box, so try to keep it short.
- PauseOnTaskComplete (Boolean) is optional. Set to True if you want a pause after each task is completed.
- TaskCompletePauseDuration (Single) is optional and is the length of time you want the system to pause after each task is completed. Can range from 1 to 10 seconds, and fractions of a second are allowed. In the example case, this would pause for 1 second after each spreadsheet is exported.
- PauseOnProjectComplete and ProjectCompletePauseDuration are the same as the two arguments above, but apply to the project as a whole. In the example case, these would cause the meter to pause for one second after the project is 100% complete.
- BarColor is an optional Long Integer field used to set the color of the progress bars.
[*]Leaving it out uses the normal values in the form (normally green).
[*]This is a long variable representing the color from the color pallette.
- FormColor is an optional Long Integer field used to set the color of the meter display form.
[*]Leaving it out uses the normal values in the form (normally white).
[*]This is a long variable representing the color from the color pallette.
Code:
Meter.InitializeTask ActionCount, TaskDescription
- ActionCount (Long Integer) is the number of actions needed in this task. For the export example, assuming you were doing a line-by-line export rather than TransferSpreadsheet, this would be the number of lines being exported.
- TaskDescription (String) is self-explanatory. It suffers from the same 3 inch display limitation as the project description.
Code:
Meter.UpdateTask ActionCount
- ActionCount (Long Integer) is simply the numeric value indicating your progress. In the example, this would be the number of rows exported so far.
- NOTE: Once this step reaches 100% completion, processing will pause as indicated when the project was initialized (1 second by default).
- NOTE: After reaching 100% task completion, project progress will be incremented by 1. In the exporting ten spreadsheets example, every time an export is complete, the project (lower) progress (TaskCount) will increment, and the project meter bar will update by a 10% increment.
Code:
Meter.ChangeProjectDescription ProjectDesc
- ProjectDesc (String) is the new project description you want displayed on the project (lower) meter bar.
Step 7: Once the project is 100% complete, the code will pause if indicated back in step 1, and then the meter form will be closed.
An example where you might need to change the project description might be this:
- Import spreadsheet.
- Clean data in multiple fields
- Transfer cleaned data to a permanent table
- Output reports based on newly imported data
***
I have updated an Access 2003 database with both class modules as well as a test form so you can see it work as well as have working examples of the various methods. If you have any concerns or suggestions, please post them; I do have a few updates I want to make to these when I have the time and desire.
As per this forum’s rules, if you have questions about this, please PM me directly, and I will reply as soon as I am able.
***
ADDENDUM July 11, 2014
As CJLondon pointed out to me, this code will not be able to generate new forms in an mde/accde file. If you use my code in those types of files, you will need to have the forms pre-generated. You can certainly do that by running the test form in Meter.mdb, but just to play it safe, I'm uploading a file containing the two forms in question as well as the module.
Attachments
Last edited: