Reputation: 39
I've programmed a "Please wait" form in which I inserted a progress bar. I looked around how to program a progress bar and this is what I did. First of all I programmed the button - Button3_Click - I press to start. Then I programmed the timer - Timer1_Tick -and so I wrote:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
*[calculus code]*
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
End Sub
I can't understand why the progress bar gets stuck at 100% and neither form18 gets hidden, nor hrrspkexcel becomes visible. Where am I doing wrong? Thanks for any support. Best regards.
Edit: I tried to edit my code as comments say:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
[calculus code]
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If Form18.ProgressBar1.Value = 100 Then
Timer1.Stop()
Timer1.Enabled = False
End If
End Sub
In this case, progress bar gets stuck at 10%.
Edit II: Following suggestions in comment, I removed the timer and based my progress bar on the entity of the calculus code (Form18.ProgressBar1.Maximum). Anyway, what is reported under [calculus code] is an heavy Excel export so the progress bar freezes to 0% until exportation has ended and then start running (I set loading cursor to understand when exportation has ended), so maybe I'd need of a BackgroundWorker to make my bar progressing while exporting? (I'm a beginner programmer and I read somewhere something about this, but I don't know if this solution is suitable for me, so I'm asking).
At last, this is how I corrected my code:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
Form18.ProgressBar1.Maximum = [if loop criteria based on my code]
Form18.ProgressBar1.Increment(1)
Form18.Show()
[calculus code - excel export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
With this edit, my ProgressBar freezes at 0% even if exportation has already ended, so I'm obviously doing wrong somewhere. Thanks for all the support you're giving to me.
Edit III: I managed in making progressbar working using a for loop to increment its value, as you suggested me, with a proportional equation to percentage and to overcome the problem about the maximum value of the bar, that's always set on 100. So thanks all of you for your support. The last thing I want to ask you - if I'm not offtopic - is how to make my loading form - with the progressbar - on foreground and to "lock" interaction with all other forms.
Edit III BIS: I've tried to use Backgroundworker in order to overcome the loading-form freezing. This is the first time I'm using this command and I don't know if it's the right way to make it comunicating to a ShowDialog Form. This is what I wrote:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Form18.ShowDialog()
[excel calculus export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrnativexcel.Visible = True
End If
End Sub
I'm always getting the same trouble: when Form18 appears, remains on 0% loading.
Edit IV: I'm having an issue about progressbar increment for the following situation: I have two for loops for exporting values in excel and the upper bound of this loops are different. So I've created a third for loop, whose upper bound is the sum of the upper bounds of the two abovementioned for loops, in order to increment the progressbar progress. When it reaches 100%, it starts again going in loop. How could I solve this issue? Here is the code I'm using:
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
For k = 0 To CInt(CInt(Form6.ListBox1.Items.Count) + CInt(Form10.ListBox1.Items.Count))
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(i + 1, 2).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * k / (CInt(Form6.Label9.Text) + CInt(Form10.ListBox1.Items.Count)))
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
Next
Thanks in advance.
Edit V: I've updated my code following comments in order to solve the issue described in Edit IV. This is what I wrote:
Dim pbloop As Integer
pbloop = CInt(Form10.ListBox1.Items.Count) * CInt(Form6.ListBox1.Items.Count)
For p = 1 To pbloop
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
hrrspkexcel.Cells(i + 1, 4).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(i + 1, 3).value = Form6.ListBox2.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox1.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(j + 1, 2).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * p / pbloop)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
I'm getting stuck always at 0% and progress bar that doesn't increase.
Upvotes: 0
Views: 1056
Reputation: 1963
You current code reads as if you want the Progress Bar to update on a button click a maximum of 10 times before hiding the form. Is that your intention? I would have expected that you want the "Please wait ..." form to stay visible with the progress bar updating every, say, second, then disappear?
Using a timer for the latter is fine but for the former, you can simply update the progress bar directly - as you are doing - without a timer.
Also, you don't need to multiply your progress bar value by 10; you can simply set the progress bar Maximum
value to 10.
Also, since you change the ForeColor
value on the first click, you can probably dispense with the Case Select {even|odd}
test because the code is otherwise identical.
So without the timer or the color change and with Progress Bar Maximum = 10
, all you need to do is:
Form18.ProgressBar1.Value = iProgressBarValue
Form18.Label3.Text = $"{iProgressBarValue} %")
No need for the Case Select
.
Another option for the PB is to use the PerformStep()
method to increment it. Just set the Step
property to 1 for this approach.
Upvotes: 1
Reputation: 39122
Try something more like this out:
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button3.Enabled = False
hrrspkexcel.Visible = False ' changed this to a Label next to the button just for demonstration
Dim f18 As New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave the maximum at 100!
f18.Show(Me)
Dim pct As Integer
Dim maximum As Integer = 319 ' <-- figure out the max value based on your "calculus code"
Await Task.Run(Sub()
' [calculus code - excel export]
For i As Integer = 0 To maximum
System.Threading.Thread.Sleep(50) ' <- some kind of processing going on
' calculate the percentage based on your loop value "i" and the "maximum":
pct = CDbl(i) / CDbl(maximum) * 100 ' <-- scale your loop value to 100
Try
f18.ProgressBar1.Invoke(Sub()
f18.ProgressBar1.Value = pct
End Sub)
Catch ex As Exception
' User closed the progressform, create another one
Me.Invoke(Sub()
f18 = New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave it at 100
f18.Show(Me)
' make progressbar immediately jump to the right spot
f18.ProgressBar1.Value = f18.ProgressBar1.Maximum
f18.ProgressBar1.Value = pct
End Sub)
End Try
Next
End Sub)
' when we hit here, the "calculus code" above completed
f18.Close()
hrrspkexcel.Visible = True ' changed this to a Label next to the button just for demonstration
Button3.Enabled = True
End Sub
Here's what it looks like in action:
Upvotes: 1
Reputation: 655
This is not the true answer of the problem but a sample to show you how to use a progress bar.
This code is not beautiful, I know, it's for the example. Please be careful when you use a textbox text as a number without check what is written.
Imports System.Threading
Public Class Form1
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
' Initialisation of the progressbar
myProgressbar.Value = 0
myProgressbar.Maximum = tbxTo.Text
lbxInfos.Items.Clear() ' Clear the content in the listbox1 if it's not the first run
' This simulate your [calculus code], I just add an information in the listbox
For i As Integer = tbxFrom.Text To tbxTo.Text
myProgressbar.Value = i ' Set the progressbar avancement
lbxInfos.Items.Add("This is the loop n° " & i & " !")
lbxInfos.Refresh() ' Just because the listbox will not be refresh until the end of the sub
Thread.Sleep(200) ' The code is too fast, I add this to see the progress (= wait 200 ms)
Next
MsgBox("This is the end ! Now the form will be closed")
Me.Close()
End Sub
End Class
Upvotes: 1