|
-
Jan 4th, 2014, 08:23 AM
#1
Thread Starter
Member
[RESOLVED] For loop producing IndexOutOfRange error
I keep getting the following error and unsure has to how fix it. As a fairly new user to VB.NET, I think it is saying that there are no rows at that position? To compensate for this, I included an If statement to check the row count, but it is still producing this error. In fact, the messagebox is not firing at all. The error seems to happen when I use the combobox to change the value of the pagesize. Can someone please advise as to how I can correct this error. Thanks
There is no row at position 1.
Code:
Private Sub loadpages()
Dim i As Integer
Dim startRec As Integer
Dim endRec As Integer
Dim dtTemp As DataTable
'Dim dr As DataRow
'Duplicate or clone the source table to create the temporary table.
dtTemp = dtSource.Clone
If currentPage = PageCount Then
endRec = maxRec
Else
endRec = pageSize * currentPage
End If
startRec = recNo
'Copy the rows from the source table to fill the temporary table.
If dtSource.Rows.Count <> 0 Then
For i = startRec To endRec - 1
dtTemp.ImportRow(dtSource.Rows(i)) <--- ERROR HERE
recNo = recNo + 1
Next
Else
MessageBox.Show(dtSource.Rows.Count.ToString())
End If
frmMain.DGV.DataSource = dtTemp
DisplayPageInfo()
'fillPostings()
End Sub
combobox sub to change pagesize
Code:
Sub cmbpage()
'Set the start and max records.
pageSize = CInt(frmMain.cmbPageSize.Text)
maxRec = dtSource.Rows.Count
PageCount = maxRec \ pageSize
MessageBox.Show(CStr(maxRec))
' Adjust the page number if the last page contains a partial page.
If (maxRec Mod pageSize) > 0 Then
PageCount = PageCount + 1
End If
'Initial seeings
currentPage = 1
recNo = 0
' Display the content of the current page.
UDGfillPostings()
loadpages()
End Sub
-
Jan 4th, 2014, 08:28 AM
#2
Re: For loop producing IndexOutOfRange error
Your page size is greater than the number of records in the result set. Use Math.Min to get the lesser of the two values and then use that as the upper limit for your loop
-
Jan 4th, 2014, 12:15 PM
#3
Thread Starter
Member
Re: For loop producing IndexOutOfRange error
@jmcilhinney Thanks for reply. However, as I am new to vb.net and still learning my way, would you be able to provide and example by way of code as I am not sure to what you are reffering. Thanks
-
Jan 4th, 2014, 05:02 PM
#4
Re: For loop producing IndexOutOfRange error
I would suggest that you put a breakpoint on this statement:
dtTemp.ImportRow(dtSource.Rows(i))
when execution stops on the breakpoint, take a look at these items:
1) i
2) dtSource.Rows.Count
3) startRec (which will actually be the same as i at this time)
4) endRec
5) maxRec
6) pageSize
7) currentPage
If you haven't used breakpoints and looked at the values of variables in running code, this is an excellent time to learn, as those are the most powerful tools available for diagnosing issues like this. You shouldn't be wonering why the messagebox isn't firing. Instead, you could put a breakpoint on the line where you check whether there are any rows, and see why the messagebox isn't firing. That may be of some interest, but you kind of already know the answer. After all, you say that the messagebox should be shown if the record count is zero. The messagebox is not being shown. Therefore, the record count is not zero.
By looking at the items that I suggested, you will find that the problem is occuring when the loop runs off the end of the datatable. You are right in assuming that there is no record at location i, your mistake was assuming that i = 0 when the error occured. The datatable isn't empty, the loop is going too far. With the breakpoint, and looking at those variables, you will probably see that i can take on a value that is greater than the number of records in the datatable. From the breakpoint, you can even step forwards line by line through the code (generally F10 or F11, but F8 on some layouts) and watch i count upwards with each loop until it gets beyond the number of records in the datatable...then crash.
I suspect that performing that excersize will show you more than any amount of code could do.
My usual boring signature: Nothing
 
-
Jan 4th, 2014, 05:08 PM
#5
Re: For loop producing IndexOutOfRange error
endRec = pageSize * currentPage
All that's needed is to recognise that if you have a page size to accommodate, say, 25 records and the actual number of records is not a multiple of 25 (which is very likely), you need to set the loop end to the number of records not to the page size as you are here. I'm not entirely sure what the pagesize does but it certainly shouldn't be part of any count termination calculation. If you don't have a fixed number of records at this point and cannot move this process to somewhere that you do, it might be better to use a For Each loop rather than an indexed loop.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Jan 4th, 2014, 06:42 PM
#6
Re: For loop producing IndexOutOfRange error
I don't think he can use a For Each, at least not easily. He's obtaining some contiguous subset of records from a datatable, so taking X records starting at some point, would be easiest to do with a For Next. He's just getting too many, as you noted.
My usual boring signature: Nothing
 
-
Jan 5th, 2014, 07:12 AM
#7
Thread Starter
Member
Re: For loop producing IndexOutOfRange error
@Shaggy I am finding it difficult being new to vb.net to debug. Basically, I am not 100% sure what the error means so just beating my head against a wall. After taking your advice, I made a small change to the code but still producing error. What I find strange is that the try/catch dosen't seem to being fired in a messagebox. Where to go from here. BTW, This code is for a pagination so I can split many records into manageable chucnks and can be viewed from the link I posted in original question. Thanks
Code:
Try
'Copy the rows from the source table to fill the temporary table.
If dtSource.Rows.Count > i Then
For i = startRec To endRec - 1
dtTemp.ImportRow(dtSource.Rows(i))
recNo = recNo + 1
Next
Else
MessageBox.Show(CStr(i))
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
-
Jan 5th, 2014, 10:46 AM
#8
Re: For loop producing IndexOutOfRange error
I'm beginning to suspect that your problem all along has been that the source table never actually has any rows. I've written up a version of your paging here (as a function to make it portable). I'm not saying it's perfect by any means but it works. I suggest you try it with your own table so that we can identify exactly where the problem lies (and of course keep it if it suits).
vb.net Code:
Public Class Form1
Dim SourceTable As New DataTable
Dim CurrentPage As Integer
'set up 104 row datatable for illustration purposes only
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
SourceTable.Columns.Add("Index", GetType(Integer))
For i = 0 To 103
SourceTable.Rows.Add({i})
Next
dgv.DataSource = GetDataPage(SourceTable, 25, CurrentPage)
End Sub
' NB. PageIndex is zero based!
Private Function GetDataPage(dt As DataTable, PageSize As Integer, PageIndex As Integer) As DataTable
' crucial test - is your datatable empty?
If dt.Rows.Count > 0 Then
Dim dtReturn As DataTable = dt.Clone
' are there enough records to make a page?
If (PageSize * PageIndex) <= dt.Rows.Count Then
' is it a full page?
If (PageSize * PageIndex) + PageSize - 1 <= dt.Rows.Count - 1 Then
For i = 0 To PageSize - 1
dtReturn.ImportRow(dt.Rows((PageSize * PageIndex) + i))
Next
Return dtReturn
Else
For i = PageSize * PageIndex To dt.Rows.Count - 1
dtReturn.ImportRow(dt.Rows(i))
Next
Return dtReturn
End If
Else
MsgBox("No more records")
Return Nothing
End If
Else
MsgBox("Datatable contains no records")
Return Nothing
End If
End Function
' a next button just to show that it does actually work
Private Sub NextRecord_Click(sender As System.Object, e As System.EventArgs) Handles NextRecord.Click
CurrentPage += 1
dgv.DataSource = GetDataPage(SourceTable, 25, CurrentPage)
End Sub
End Class
Last edited by dunfiddlin; Jan 5th, 2014 at 10:50 AM.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Jan 5th, 2014, 02:58 PM
#9
Thread Starter
Member
Re: For loop producing IndexOutOfRange error
@dunfiddlin Thanks. I created a new form and your code worked fine inthat form with only your code. I use a call to access db to populate the grid, how do I adapt your code so I can try to narrow the error down. Thanks
BTW: Here is the link where I got the original code from: http://support.microsoft.com/kb/305271/en-us
-
Jan 5th, 2014, 05:47 PM
#10
Re: For loop producing IndexOutOfRange error
Simply replace my faux table with a real one. By whatever means you obtained dtSource in your original code, do that in the FormLoad event and then change the parameters in the dgv.Datasource = GetDataPage function call accordingly. The whole point of transferring this to a function is to make it possible to obtain the required result from any datatable created in any way at any time.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Jan 6th, 2014, 04:33 AM
#11
Thread Starter
Member
Re: For loop producing IndexOutOfRange error
@dunfiddlin Many thanks. I shall make the adjustments and proceed from there. If I could ask one last question. How would I do previous button. I have coded like attached, but when I reach last page, errors with 'no row at position -25'. Thanks
Code:
Private Sub PrvRecord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PrvRecord.Click
CurrentPage -= 1
DataGridView1.DataSource = GetDataPage(SourceTable, 25, CurrentPage)
End Sub
-
Jan 6th, 2014, 10:52 AM
#12
Re: [RESOLVED] For loop producing IndexOutOfRange error
There are various conditions you could use in an If clause to simply bypass the paging code. CurrentPage < 0 seems the most obvious.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|