-1

I have a DataGridView with 8 Rows. In the following Sub i have an If statement to only do something when i is less than the RowCount, this is purposely so when i use (i + 1) on the last row it will still be in range, yet it is not? I can't figure out why. Would appreciate any help.

This is the sub

    Public Sub Durations(dgv As DataGridView)
    For i As Integer = 0 To dgv.RowCount

        Dim intTotalMinutesOfRows As Integer
        Dim IntHoursForRows As Integer
        Dim intMinutesForRows As Integer

        If i < dgv.RowCount Then

            If dgv.Rows(i).Cells("EmployeeID").Value = dgv.Rows(i + 1).Cells("EmployeeID").Value _
            And dgv.Rows(i).Cells("Date").Value = dgv.Rows(i + 1).Cells("Date").Value Then

                intTotalMinutesOfRows = intTotalMinutesOfRows + dgv.Rows(i).Cells("TotalDurationOfRow").Value

            Else

                intTotalMinutesOfRows = intTotalMinutesOfRows + dgv.Rows(i).Cells("TotalDurationOfRow").Value
                IntHoursForRows = Math.Floor(intTotalMinutesOfRows / 60)
                intMinutesForRows = intTotalMinutesOfRows Mod 60
                dgv.Rows(i).Cells("TotalDurationForDay").Value = "" & IntHoursForRows & " Hrs     " & intMinutesForRows & " Mins"
                intTotalMinutesOfRows = 0
            End If

        End If

    Next
Pete
  • 469
  • 7
  • 18
  • 0 counts as a row...so you need to loop from 0 to RowCount-1 – sous2817 Mar 15 '17 at 19:32
  • That's how i had it before but it was giving the same error although i will do it again now. – Pete Mar 15 '17 at 19:33
  • you may have to tweak your if statement as well as references like this "dgv.Rows(i + 1)". that i+1 will give you issues on your last iteration... – sous2817 Mar 15 '17 at 19:35
  • Thank you both they do remove the error so it loads fine, just the last row Is missing it's total duration, i thought that was because the last row was being missed but now i see it's just not being handled. – Pete Mar 15 '17 at 19:37
  • 1
    DataGrid**View**. You should be doing all your operations on an underlying non-ui datasource. – djv Mar 15 '17 at 21:17

2 Answers2

3

Iterate to RowCount - 1 only:

For i As Integer = 0 To dgv.RowCount - 1
                                     ^^^

Note that despite you've got If i < dgv.RowCount Then, later in this conditional operator you're trying to access Rows(i + 1), which causes the exception for i = dgv.RowCount - 1. So you have to change your condition to If i < dgv.RowCount - 1 Then as well.

Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
3

Indexes are zero-based (they start at 0), so index 7 is the 8th row.

Row   :  1  2  3  4  5  6  7  8
Index :  0  1  2  3  4  5  6  7

Infact even your loop's end is wrong, because i will go to whatever RowCount is. Thus if RowCount is 8 then i will be 8 as well in the end (which doesn't work, as seen in the indexes above).

In order to loop to the last index you must loop to RowCount - 1:

For i As Integer = 0 To dgv.RowCount - 1
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • The `RowCount -1` has solved the error, i see now that the last `Row` will fail the `If` statement and that's why there is no Total Duration displayed. I just need to do that now. What i didn't understand is if there is `8 Rows` then why on the 7th `Row` is the next one out of range? EDIT : Sat here thinking about it and i think the penny has dropped finally! Because `i` is the `index` not the `Row` So when `i` is 7 then that IS the last `Row` Got it – Pete Mar 15 '17 at 19:45
  • @DIMPeteAsUsername : Hehe, all the stuff to remember about arrays and indexes can be tricky ;). Good that you now understand the problem! Good luck! – Visual Vincent Mar 15 '17 at 19:50
  • Good illustration of the row and index. Never thought to explain it like that before. – Bugs Mar 15 '17 at 21:34