Here is my take on the progress bar. In my view it's the simplest progress bar possible, and provides the greatest control to the developer. You can choose to base your progress bar on a text box, label, rectangle or line. You get to choose the colors, size and other attributes of the progress bar object. No Active/X object or class definition necessary.
To use the progress bar just add one (textbox or label) or two (rectangle or line) objects to your form. Decide on the position, dimensions and colors as you like. I prefer to make them invisible until used. Then call the wsProgressBar subroutine, providing the control(s) to be used and the variables necessary to compute progress percentage.
The sample attached to this article has 1 form showing 9 variations on the progress bar; 10 if you consider the two slanted lines together as representing one progress bar object. It was a kind of neat surprise to see that.
Here's the code. In the sample it's within the code-behind of the form; normally it would be in some public module so it would be callable from any form. I've included the kitchen sink; you might want to strip out some options.
To use the progress bar just add one (textbox or label) or two (rectangle or line) objects to your form. Decide on the position, dimensions and colors as you like. I prefer to make them invisible until used. Then call the wsProgressBar subroutine, providing the control(s) to be used and the variables necessary to compute progress percentage.
The sample attached to this article has 1 form showing 9 variations on the progress bar; 10 if you consider the two slanted lines together as representing one progress bar object. It was a kind of neat surprise to see that.
Here's the code. In the sample it's within the code-behind of the form; normally it would be in some public module so it would be callable from any form. I've included the kitchen sink; you might want to strip out some options.
Code:
' Procedure : ProgressBar
' Author : Jim Wolf, Wolf Software, LLC
' Date : 5/30/2014
' Purpose : Simple progress bar made up of on-screen controls (label, textbox, line or rectangle)
' 1 Rectangle/line will have a length or height that represents progress so far
' 2nd rectangle/line's max length or height gives something to measure progress against
' progress - how many units have been completed
' goal - # of units that is 100% complete
' bDoEvents - yes/no flag to indicate whether this routine should DoEvents before returning
' pbPctCtl - control to show the percent complete on. Use NULL if no % display wanted
' pbCTL1 = the control that represents 100%
' pbCTL2 = the control that grows to show percent complete
'
'---------------------------------------------------------------------------------------
'
Public Sub wsProgressBar(progress As Long, goal As Long, bDoEvents As Boolean, pbPctCtl, pbCTL1 As Control, Optional pbCTL2 As Control)
On Error GoTo ProgressBar_Error
Dim dblPCT As Double
Dim pbOrientation As Byte ' = 1 for making the control wider as progress increases
' not 1 for making the control taller as progress increases
Dim pbCTL As Control ' The control that will vary based on progress
If goal = 0 Then Exit Sub
If goal > 0 And progress < 0 Then Exit Sub ' if either is negative both must be
If goal < 0 And progress > 0 Then Exit Sub
If pbCTL1.Height >= pbCTL1.Width Then
pbOrientation = 0 ' vertical progress bar
Else
pbOrientation = 1 ' progress bar will be horizontal
End If
If pbCTL2 Is Nothing Then
Set pbCTL = pbCTL1 ' if only one control is provided there will be no goal shown
Else
Set pbCTL = pbCTL2
End If
pbCTL1.Visible = True ' show the goal
If progress = 0 Then
pbCTL.Visible = False
Else
pbCTL.Visible = True ' show the progress control
End If
dblPCT = Abs(progress) / Abs(goal) ' percentage complete
If dblPCT > 1 Then dblPCT = 1
pbCTL.Left = pbCTL1.Left
Select Case pbCTL1.ControlType
Case acRectangle
pbCTL.Top = pbCTL1.Top
If pbOrientation = 1 Then ' horizontal?
pbCTL.Width = pbCTL1.Width * dblPCT ' more progress =wider control
Else
pbCTL.Height = pbCTL1.Height * dblPCT ' more progess=taller control
pbCTL.Top = pbCTL1.Top + (pbCTL1.Height - pbCTL.Height) ' but start at bottom of the goal
End If
Case acLine
If pbCTL.Name = pbCTL1.Name Then
Else
If pbCTL1.Height = 0 Then ' is this a horizontal line
pbCTL.Top = pbCTL1.Top
pbCTL.Width = pbCTL1.Width * dblPCT ' more progress =wider control
ElseIf pbCTL1.Width = 0 Then ' is this a vertical line
pbCTL.Left = pbCTL1.Left
pbCTL.Height = pbCTL1.Height * dblPCT ' more progess=taller control
pbCTL.Top = pbCTL1.Top + (pbCTL1.Height - pbCTL.Height) ' but start at bottom of the goal
Else ' it must be a slanted line
pbCTL.Height = pbCTL1.Height * dblPCT ' more progess=taller control
pbCTL.Top = pbCTL1.Top
End If
End If
Case acTextBox, acLabel
If pbCTL.Vertical Then ' is this textbox showing text vertically?
pbCTL.TopMargin = (1 - dblPCT) * pbCTL.Height ' make margin as big as the part not yet done
Else
pbCTL.RightMargin = (1 - dblPCT) * pbCTL.Width ' make margin as big as the part not yet done
End If
End Select
If IsNull(pbPctCtl) Then
Else
Select Case pbPctCtl.ControlType ' can only show % on textboxes, labels and buttons
Case acTextBox
pbPctCtl.Value = Format(dblPCT, "#.#%") ' display the percentage complete
Case acLabel, acCommandButton
pbPctCtl.Caption = Format(dblPCT, "#.#%")
End Select
End If
Set pbCTL = Nothing
If bDoEvents Then DoEvents
On Error GoTo 0
Exit Sub
ProgressBar_Error:
MsgBox "Error " & Err.Number & " " & Err.Description
Resume Next
End Sub
Comment