[RESOLVED] [2005] - Progress Bar and DatagridView
Hi All,
I'm writing an application which takes the values out of a selected datagridview's column, places each value into a string and using a for loop, scrapes each values data from the website and places it into a second datagridview.
As there can be heaps of data to be scraped, I would like to inform the user of the progress and without locking up the user interface while the data is being scraped.
I'm following this article Using the BackgroundWorker Component but getting stuck at
Code:
worker.ReportProgress(i, i & " iterations complete")
Re: [2005] - Progress Bar and DatagridView
Please show more of your code. You may get stuck at that line, but we need to see how you are using it in the rest of your code to identify the problem.
Re: [2005] - Progress Bar and DatagridView
Could you also explain the "getting stuck" bit? Is it erroring out?
Re: [2005] - Progress Bar and DatagridView
As requested the code. It is a bit long and I have commented as much as possible to explain each step :D
The getting stuck is when
Code:
worker.ReportProgress(i, i & " iterations complete")
is added. The program will not build. Remove the line of code, the program will build but will lockup after scraping each value's data from the website.
Code:
Private Sub BackGroundWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
Try
Dim sDate As String = Format(Today, "yyyyMMdd")
For Each row As DataGridViewRow In DataGridView1.Rows
'worker.ReportProgress(row, row & " completed") <----- Cannot Build if this line is included.... If ommitted, the program will build, but will lockup after scraping all the data. I have tried converting to Integer which will build, but upon running an error is generated stating that string cannot be converted to Integer
Dim MorningStarCode As String = CStr(row.Cells(0).FormattedValue)
Dim MCode As String = CStr(row.Cells(1).FormattedValue)
' Start The Scraping Process
Dim APIUrl As String = "http://www.morningstar.com.au/MSToolsMain/FundResults.asp?cboCountryId=AUS&hdnToolId=qq&hdnView=5&hdncobrand=MS&hdnclientCode=MS&txtApirFundNameTicker=" + MorningStarCode + "&image.x=10&image.y=7"
Dim objRequest As HttpWebRequest = CType(WebRequest.Create(APIUrl), HttpWebRequest)
objRequest.Proxy = WebRequest.DefaultWebProxy
objRequest.Proxy.Credentials = CredentialCache.DefaultCredentials
Dim str As StreamReader
str = New StreamReader(objRequest.GetResponse().GetResponseStream())
' Read The Response Into A String
Dim strHTML As String = str.ReadToEnd
Dim strStartCut As String
Dim strEndCut As String
Dim strStartTag As String
Dim strEndTag As String
Dim strDesired As String
' Cut Out Only What We Need
'strStartTag = "bgcolor=""#f5f5f5"">"
'strEndTag = "</tr>"
strStartTag = "<td class=""Normal"" align=""right"">"
strEndTag = "</td>"
strStartCut = (InStr(1, strHTML, strStartTag, vbTextCompare) + Len(strStartTag))
strEndCut = (InStr(strStartCut, strHTML, strEndTag, vbTextCompare))
strDesired = Mid(strHTML, strStartCut, (strEndCut - strStartCut))
' Strip HTML Tags from the scraped data
Dim Pattern As String = "<[^>]*>"
Dim R As New Regex(Pattern)
strDesired = R.Replace(strDesired, "")
Dim Pattern2 As String = "[<]"
Dim S As New Regex(Pattern2)
strDesired = S.Replace(strDesired, "<")
Dim Pattern3 As String = "[>]"
Dim T As New Regex(Pattern3)
strDesired = T.Replace(strDesired, ">")
'Pad 0's to Scraped Result To Confirm To Standards
Dim PaddedResult As String = "000000" + strDesired + "00"
' Place into A New String with the other data
Dim FinalRow As String = "2B" & vbNewLine & MCode & vbNewLine & sDate & vbNewLine & "0000000.000000" & vbNewLine & PaddedResult
'Split The Data
Dim Lines() As String = Split(FinalRow.ToString, vbCrLf)
'Insert the data into the second datagridview
Me.DataGridView2.Rows.Add(Lines)
Next row
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Code:
Me.BackgroundWorker1.RunWorkerAsync()
is handled by a button click, BackgroundWorker1_ProgressChanged and BackgroundWorker1_RunWorkerCompleted are the same as in the posted article.
Re: [2005] - Progress Bar and DatagridView
Re: [2005] - Progress Bar and DatagridView
I see that you copied the code and using it without understanding what's going on in the copied code. The original code had this
Code:
worker.ReportProgress(i, i & " iterations complete")
Where the variable i is a loop counter and declared as an Integer. You changed it to
Code:
worker.ReportProgress(row, row & " completed")
Where row is of type DataGridViewRow... And obviously it's not going to work.
You need to modify your code to use a For loop with a loop counter instead of using For Each loop as you're doing now.
Re: [2005] - Progress Bar and DatagridView
I have re-written the for loop using
Code:
For I As Integer = 0 To DataGridView1.Rows.Count - 1
The code is working as expected but 2 problems are occurring.
Problem 1:
The second datagridview is locking up if more that 5 records are dynamically added. I if modify the for loop expression, the following message is returned.
Index was out of range. Must be non-negative and less than the size of the collection
Parameter name:index
Problem 2:
My label is incrementing by 1 every time a row is added to the second datagridview until it gets to "operation complete" but my progress bar increments once.
Re: [2005] - Progress Bar and DatagridView
Hi All,
All my problems have been solved...:D
Problem 1:
When adding rows exceeding the set size of the datagridview, generating both scroll bars would lockup the datagridview. Not sure why this caused but it only happens when using a background worker. Fixed by disabling horizontal scroll bar
Problem 2:
Forgot to set the minimum / maximum value of the progress bar :D