Solved

Progress bar does not run until end of program

Posted on 2006-07-22
4
155 Views
Last Modified: 2010-04-30
I have a progress bar on my form that I want to run between two statements in a sub.  The call looks something like this:

statement1
Call progress bar
statement2

When I call the progress bar, I want it to start the progress bar working, and when it finishes, I want statement2 to launch.  For some reason, the progress bar launches after all the code is finished executing.  Can someone tell me what I'm doing wrong? I will paste the progress bar sub and the timer.

Thanks for the help!
BPL

Private Sub showProgress()
    intpercent = 1
    Timer1.interval = 100
    Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
   
    If intpercent <= 100 Then
        ProgBar Picture1, CLng(intpercent), vbWhite, vbBlue, vbBlack, True, 0
    Else
        Timer1.Enabled = False
    End If
   
    intpercent = intpercent + 1
End Sub
0
Comment
Question by:bpl5000
  • 3
4 Comments
 
LVL 4

Accepted Solution

by:
JRCSystems earned 500 total points
ID: 17163034
What you've got there are 3 sub routines, not 1 routine called "ShowProgressBar" or something similar.
From what I see, you've tied the 3 routines together through a timer, which waits 100 ms (1/10 sec) before firing.
a) ShowProgress turns on the Timer.
b) The Timer when it fires, calls ProgBar.
c) ProgBar draws out your progress bar.

Unless you're running on an old Pentium 233, computers now a days (and maybe even back then) would be fast enough to Execute "Statement2" before the 1st timer goes off.

I am not sure what exactly you are trying to accomplish.
Progress bars typically update based on a real process; i.e. you've read record X out of Y, etc.
What you've got is a timer that will fire 10 times in 1 second, and will take 10 seconds to reach 100%

If that is what is desired ( wait 10 seconds before executing statement 2 ), why not try this, which uses a time delay.

=== put this is your common-code library ===
Public Sub TimeDelay(byval xfWait as Single)
Dim pfTimeEnd as Single

      pfTimeEnd = Timer + xfWait
      Do While Timer < pfTimeEnd
           DoEvents
      Loop
End Sub

=== Then put this in your current code loop, replacing timer logic ===
...
Dim plPercent As Long
...
       'statement1'
       For piPercent = 1 to 100
               TimeDelay 0.1
                ProgBar Picture1, plPercent, vbWhite, vbBlue, vbBlack, True, 0
      Next piPercent
      'statement2'
...

I suppose another option you have, if your set on using a Timer, would be something like this.

Private Sub Timer1_Timer()
    Timer1.Enabled = False
   
    If intpercent <= 100 Then
        ProgBar Picture1, CLng(intpercent), vbWhite, vbBlue, vbBlack, True, 0
        intpercent = intpercent + 1
        Timer1.Enabled = False
    Else
'       reset for next time thru ...
        intpercent = 0
        'Statement2'
    End If
   
End Sub

Basically, when the Timer knows IT is done, IT can call Statement2.
I also reset it values it case you need to call it again.
You might want to make a note of the minor changes I made to the timer.
The timer, when it fires, the first thing it should do is turn itself off.
If IT (the timer,your code) determines when its done that it needs to go back on, then turn it on.
Say, for example, that your ProgBar routine took more than 1/10 of sec to complete...
IF it did, you'd have a stack-buildup because the 1st routine never exited before the 2nd/3rd/4th/etc completed.

That should do it.






0
 
LVL 5

Author Comment

by:bpl5000
ID: 17163140
Okay, I think I understand.  I was trying to launch a statement, sleep for 10 seconds and then launch another statement.  The only problem was that I wanted the user to know something was going on so I put in the progress bar.  Apparently, when the sleep statement runs, no code continues to execute... even the progress bar.  I thought the progress bar would run because it was called before the sleep statement.  I'm guessing the code that you pasted will do what I need.  I will give it a try later today.

Thanks!
BPL
0
 
LVL 5

Author Comment

by:bpl5000
ID: 17164766
JRC, I tried your code and it works great.  Thanks for helping me out!  There was one problem... you have piPercent and plPercent.  For anyone looking for a progress bar, I will paste it all below.

Thanks again JRC!

'Code below starts the progress bar
    For piPercent = 1 To 100
        TimeDelay 0.1
        ProgBar Picture1, piPercent, vbWhite, vbBlue, vbBlack, True, 0
    Next piPercent

'*********************************
Public Sub TimeDelay(ByVal xfWait As Single)
Dim pfTimeEnd As Single

      pfTimeEnd = Timer + xfWait
      Do While Timer < pfTimeEnd
           DoEvents
      Loop
End Sub

'*********************************
Public Function ProgBar(PicX As PictureBox, _
    PercentIn As Long, _
    Optional BGcolor As Long = vbWhite, _
    Optional FGcolor As Long = vbBlue, _
    Optional TextColor = vbBlack, _
    Optional DisplayText As Boolean = True, _
    Optional Style As Integer = 0) As Boolean
   
    Dim OnePercent As Single
    Dim PBarWidth As Long
    Dim PBarHeight As Long
    Dim T As Long
    Dim i As Long
    Dim temp As Long
    Static J As Long
   
    On Error GoTo Err_Handler
   
    If J > PercentIn Then PicX.Cls
    If J > 0 And J = PercentIn Then Exit Function
   
    With PicX
        .AutoRedraw = True
        .ScaleMode = 3
        .BackColor = BGcolor
        .ForeColor = FGcolor
    End With
   
    ' Get the width and height of the bar...
    PBarWidth = PicX.Width / Screen.TwipsPerPixelX
    PBarHeight = PicX.Height / Screen.TwipsPerPixelY
    OnePercent = PBarWidth / 100
   
    Select Case Style
   
    Case 1 ' Vertical Progress bar
       
        OnePercent = PBarHeight / 100
       
        For T = PBarHeight - (OnePercent * PercentIn) To PBarHeight
            PicX.Line (0, T)-(PBarWidth, T)
        Next T
       
        If DisplayText = True Then
            ' Print percent done on bar (for vert style)
            PicX.CurrentX = PBarWidth / 2 - 10
            PicX.CurrentY = PBarHeight / 2 - 8
            PicX.ForeColor = TextColor
            PicX.Print "" & PercentIn & "%"
       
            ' Percent done on bar turnes the
            ' background color as the bar passes
            For T = PBarHeight - (OnePercent * PercentIn) To PBarHeight
                For i = 0 To PBarWidth
                    If GetPixel(PicX.hdc, i, T) = TextColor _
                        Then PicX.PSet (i, T), BGcolor
                Next i
                If T > OnePercent * 60 Then T = PBarHeight
            Next T
        End If
       
    Case 2 ' Chunks (Win95/98 look) - should use without %done text over it.
        ' Draw the Progress
        For T = 0 To OnePercent * (PercentIn - 1)
            PicX.Line (T, 0)-(T, PBarHeight)
        Next T
       
        ' Make some chunks...
        For T = 0 To OnePercent * (PercentIn - 1) Step (OnePercent * 7)
            PicX.ForeColor = BGcolor
            ' draw an inner box of background color...
            PicX.Line (0, 0)-(PBarWidth - 1, 0)
            PicX.Line (1, 1)-(1, PBarHeight - 1)
            PicX.Line (PBarWidth - 1, 0)-(PBarWidth - 1, PBarHeight - 1)
            PicX.Line (1, PBarHeight - 1)-(PBarWidth, PBarHeight - 1)
            PicX.Line (1, PBarHeight - 2)-(PBarWidth, PBarHeight - 2)
            PicX.Line (1, PBarHeight - 3)-(PBarWidth, PBarHeight - 3)
           
            ' Draw the latest vertical line
            PicX.Line (T - 1, 0)-(T - 1, PBarHeight)
            PicX.Line (T, 0)-(T, PBarHeight)
            PicX.ForeColor = FGcolor
        Next T
       
       
    Case 3 ' Progbar blends from one color to another.
       
        Dim iRed As Integer, iBlue As Integer, iGreen As Integer
        Dim nRed As Integer, nBlue As Integer, nGreen As Integer
        Dim BlueRange As Long, RedRange As Long, GreenRange As Long
        Dim RedPcnt As Single, GreenPcnt As Single, BluePcnt As Single
        Dim Red1 As Long, Green1 As Long, Blue1 As Long
        Dim rTemp As Long, bTemp As Long, gTemp As Long
       
        ' Get RGB values of fgcolor...
        Call ColorCodeToRGB(FGcolor, iRed, iGreen, iBlue)

        ' Why not swap red and blue, and set green _
        ' to half to get the starting color?
        nRed = iBlue: nBlue = iRed: nGreen = 128
       
        RedRange = nRed - iRed
        BlueRange = nBlue - iBlue
        GreenRange = nGreen - iGreen
       
        RedPcnt = RedRange / 100
        GreenPcnt = GreenRange / 100
        BluePcnt = BlueRange / 100
       
        ' Draw the Progress
        For T = 0 To OnePercent * (PercentIn - 1)
           
            Red1 = nRed - RedPcnt * (T / OnePercent + 1)
            If Red1 < 0 Then Red1 = 0
           
            Green1 = nGreen - GreenPcnt * (T / OnePercent + 1)
            If Green1 < 0 Then Green1 = 0
           
            Blue1 = nBlue - BluePcnt * (T / OnePercent + 1)
            If Blue1 < 0 Then Blue1 = 0

            PicX.ForeColor = RGB(Red1, Green1, Blue1)
            PicX.Line (T, 0)-(T, PBarHeight)
        Next T
       
    Case Else
        ' Draw the Progress
        For T = 0 To OnePercent * (PercentIn - 1)
            PicX.Line (T, 0)-(T, PBarHeight)
        Next T
    End Select
   
    If DisplayText = True Then
       
        If Style <> 1 Then
            ' Print percent done on bar...
            PicX.CurrentX = PBarWidth / 2 - 7
            PicX.CurrentY = PBarHeight / 2 - 8
            PicX.ForeColor = TextColor
            PicX.Print "" & PercentIn & "%"
       
            ' Percent done on bar turnes the background color as the bar passes
            If PercentIn > 40 Then
                For T = OnePercent * 40 To OnePercent * (PercentIn - 1)
                    For i = 0 To PBarHeight
                        If GetPixel(PicX.hdc, T, i) = TextColor Then
                            PicX.PSet (T, i), PicX.BackColor
                        End If
                    Next i
                    If T > OnePercent * 60 Then T = _
                        OnePercent * (PercentIn - 1)
                Next T
            End If
        End If
       
    End If
   
    ' Remember what percent we're at...
    J = PercentIn
   
    ' Tell us if it all went well
    ProgBar = True: Exit Function
   
Err_Handler:
   
    ' Tell us if it didn't
    ProgBar = False
   
End Function

'****************************************
Private Function ColorCodeToRGB(lColorCode As Long, _
    iRed As Integer, _
    iGreen As Integer, _
    iBlue As Integer) As Boolean
'
    Dim lColor As Long
    lColor = lColorCode      'work long
    iRed = lColor Mod &H100  'get red component
    lColor = lColor \ &H100  'divide
    iGreen = lColor Mod &H100 'get green component
    lColor = lColor \ &H100  'divide
    iBlue = lColor Mod &H100 'get blue component

    ColorCodeToRGB = True
End Function
0
 
LVL 5

Author Comment

by:bpl5000
ID: 17164775
I forgot to include the declartions:

Option Explicit
Dim intpercent As Integer
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now