Results 1 to 12 of 12

Thread: [RESOLVED] For loop producing IndexOutOfRange error

  1. #1

    Thread Starter
    Member
    Join Date
    Sep 2013
    Posts
    44

    Resolved [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

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    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
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    Member
    Join Date
    Sep 2013
    Posts
    44

    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

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    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

  5. #5
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    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!

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    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

  7. #7

    Thread Starter
    Member
    Join Date
    Sep 2013
    Posts
    44

    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

  8. #8
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    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:
    1. Public Class Form1
    2.     Dim SourceTable As New DataTable
    3.     Dim CurrentPage As Integer
    4.  
    5.         'set up 104 row datatable for illustration purposes only
    6.     Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    7.  
    8.         SourceTable.Columns.Add("Index", GetType(Integer))
    9.         For i = 0 To 103
    10.             SourceTable.Rows.Add({i})
    11.         Next
    12.  
    13.         dgv.DataSource = GetDataPage(SourceTable, 25, CurrentPage)
    14.  
    15.     End Sub
    16.  
    17.     ' NB. PageIndex is zero based!
    18.     Private Function GetDataPage(dt As DataTable, PageSize As Integer, PageIndex As Integer) As DataTable
    19.  
    20.         ' crucial test - is your datatable empty?
    21.         If dt.Rows.Count > 0 Then
    22.  
    23.             Dim dtReturn As DataTable = dt.Clone
    24.  
    25.             ' are there enough records to make a page?
    26.             If (PageSize * PageIndex) <= dt.Rows.Count Then
    27.  
    28.                 ' is it a full page?
    29.                 If (PageSize * PageIndex) + PageSize -  1 <= dt.Rows.Count - 1 Then
    30.                     For i = 0 To PageSize - 1
    31.                         dtReturn.ImportRow(dt.Rows((PageSize * PageIndex) + i))
    32.                     Next
    33.                     Return dtReturn
    34.                 Else
    35.                     For i = PageSize * PageIndex To dt.Rows.Count - 1
    36.                         dtReturn.ImportRow(dt.Rows(i))
    37.                     Next
    38.                     Return dtReturn
    39.                 End If
    40.             Else
    41.                 MsgBox("No more records")
    42.                 Return Nothing
    43.             End If
    44.         Else
    45.             MsgBox("Datatable contains no records")
    46.             Return Nothing
    47.         End If
    48.     End Function
    49.  
    50. ' a next button just to show that it does actually work
    51.     Private Sub NextRecord_Click(sender As System.Object, e As System.EventArgs) Handles NextRecord.Click
    52.         CurrentPage += 1
    53.         dgv.DataSource = GetDataPage(SourceTable, 25, CurrentPage)
    54.     End Sub
    55.  
    56. 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!

  9. #9

    Thread Starter
    Member
    Join Date
    Sep 2013
    Posts
    44

    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

  10. #10
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    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!

  11. #11

    Thread Starter
    Member
    Join Date
    Sep 2013
    Posts
    44

    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

  12. #12
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    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
  •  



Click Here to Expand Forum to Full Width