ArgumentOutOfRangeException未处理,索引超出范围

时间:2017-07-10 09:01:37

标签: vb.net visual-studio

我想问一下是否有人知道这个错误发生的原因?所以有两种形式。第一个计算形式没有错误,这是产生错误的第二个计算形式,在搜索到这里和那里masi尚未启示后,也许有人可以帮忙吗?

THIS SCREENSHOT OF ERROR

这个完整的源代码

Public Class FrmHitung2
    Private Sub FrmHitung2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim dt As DataTable = openDT("SELECT * FROM tb_rel_alternatif2 WHERE kode_crips NOT IN (SELECT kode_crips FROM tb_crips2)")
        If dt.Rows.Count > 0 Then
            msgError("Anda belum mengatur nilai untuk setiap alternatif, silahkan atur di menu Nilai Bobot")
            BtnCetak.Enabled = False
        Else
            Dgv1.AllowUserToAddRows = False
            Dgv1.AllowUserToDeleteRows = False
            Dgv1.ReadOnly = True
            Dgv1.AutoGenerateColumns = False
            awal()
        End If
    End Sub
    Sub awal()
        Dgv1.Columns.Clear()
        Dgv1.Rows.Clear()

        Dgv1.Columns.Add("nim", "Kode")
        Dgv1.Columns("nim").ReadOnly = True
        Dgv1.Columns.Add("nama_mahasiswa", "Nama")
        Dgv1.Columns("nama_mahasiswa").ReadOnly = True

            dr = openDR("SELECT * FROM tb_alternatif2 ORDER BY nim")
            While dr.Read()
                Dgv1.Rows.Add(dr(0), dr(1))
            End While

            dr = openDR("SELECT kode_kriteria, atribut FROM tb_kriteria2 ORDER BY kode_kriteria")
            While dr.Read()
                Dgv1.Columns.Add(dr(0), dr(0))
                Dgv1.Columns(dr(0).ToString()).ToolTipText = dr(1).ToString()
            End While

            For a = 0 To Dgv1.Rows.Count - 1
                dr = openDR("SELECT c.nama_crips FROM tb_rel_alternatif2 r " &
                            " LEFT JOIN tb_crips2 c ON c.kode_crips = r.kode_crips " &
                            " WHERE nim='" & Dgv1.Rows(a).Cells(0).Value & "' ORDER BY r.kode_kriteria")
                Dim b As Integer = 2
                While dr.Read
                    Dgv1.Rows(a).Cells(b).Value = dr(0)
                    b = b + 1
                End While
            Next
            Dgv1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
            BtnCetak.Enabled = False
    End Sub
    Function get_col_max(ByVal dgv As DataGridView, ByVal col_name As String) As Double
        Dim max As Double = 0
        If dgv.Rows.Count > 0 Then max = Val(dgv.Rows(0).Cells(col_name).Value)
        For Each row As DataGridViewRow In dgv.Rows
            If Val(row.Cells(col_name).Value) > max Then
                max = Val(row.Cells(col_name).Value)
            End If
        Next
        get_col_max = max
    End Function

    Function get_col_min(ByVal dgv As DataGridView, ByVal col_name As String) As Double
        Dim min As Double = 0
        If dgv.Rows.Count > 0 Then min = Val(dgv.Rows(0).Cells(col_name).Value)
        For Each row As DataGridViewRow In dgv.Rows
            If Val(row.Cells(col_name).Value) < min Then
                min = Val(row.Cells(col_name).Value)
            End If
        Next
        get_col_min = min
    End Function
    Private Sub BtnHitung_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnHitung.Click
        Dim a, b As Integer

        awal()

        Dgv1.copyTo(Dgv2)

        For a = 0 To Dgv2.Rows.Count - 1
            dr = openDR("SELECT c.nilai FROM tb_rel_alternatif2 r " &
                        " LEFT JOIN tb_crips2 c ON c.kode_crips = r.kode_crips " &
                        " WHERE nim='" & Dgv2.Rows(a).Cells(0).Value & "' ORDER BY r.kode_kriteria")
            b = 2
            While dr.Read
                Dgv2.Rows(a).Cells(b).Value = dr(0)
                b = b + 1
            End While
        Next
        Dgv2.copyTo(Dgv3)
        For Each row As DataGridViewRow In Dgv2.Rows
            For b = 2 To Dgv2.Columns.Count - 1
                Dim v = row.Cells(b).Value
                If Dgv2.Columns(b).ToolTipText = "benefit" Then
                    Dgv3.Rows(row.Index).Cells(b).Value = v / get_col_max(Dgv2, Dgv2.Columns(b).Name)
                Else
                    Dgv3.Rows(row.Index).Cells(b).Value = get_col_min(Dgv2, Dgv2.Columns(b).Name) / v
                End If
            Next
        Next

        dr = openDR("SELECT kode_kriteria, bobot FROM tb_kriteria2 ORDER BY kode_kriteria")
        While dr.Read()
            Dgv3.Columns(dr(0).ToString()).ToolTipText = dr(1).ToString()
        End While

        Dgv3.copyTo(Dgv4)
        For Each row As DataGridViewRow In Dgv3.Rows
            For b = 2 To Dgv3.Columns.Count - 1
                Dim v = row.Cells(b).Value
                Dgv4.Rows(row.Index).Cells(b).Value = v * Val(Dgv3.Columns(b).ToolTipText)
            Next
        Next
        Dgv4.Columns.Add("total", "Total")
        For Each row As DataGridViewRow In Dgv4.Rows
            For b = 2 To Dgv2.Columns.Count - 1
                row.Cells("total").Value = row.Cells("total").Value + row.Cells(b).Value
            Next
        Next

        Dgv4.copyTo(Dgv5)
        Dgv5.Sort(Dgv5.Columns("total"), System.ComponentModel.ListSortDirection.Descending)
        For Each row As DataGridViewRow In Dgv5.Rows
            execute("UPDATE tb_alternatif2 SET total=@0, rank=@1 WHERE nim=@2", row.Cells("total").Value, row.Index + 1, row.Cells("nim").Value)
        Next

        TabControl1.SelectedTab = TabRangking
        BtnCetak.Enabled = True
    End Sub

    Private Sub BtnCetak_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCetak.Click
        LapRangking.ShowAsChild(Me.MdiParent)
    End Sub

    Private Sub BtnKeluar_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnKeluar.Click
        Me.Close()
    End Sub
End Class

2 个答案:

答案 0 :(得分:0)

当您尝试访问具有不存在的索引的数组或其他集合时,会发生该错误。请注意,索引从0开始一直到Count - 1

从您的屏幕截图中我可以看到此行Dgv1.Rows(a).Cells(b).Value = dr(0)发生错误。 a 在For循环中以这种方式定义,For a = 0 To Dgv1.Rows.Count - 1因此不太可能是罪魁祸首。

您可能需要检查已启动的 b 的值为2.如果您尝试访问集合中的第二个项目,则必须更改那条线要读......

Dim b As Integer = 1 ' If you wanted to start from the 2nd cell.
    While dr.Read
    Dgv1.Rows(a).Cells(b).Value = dr(0)
    b = b + 1
End While

b 可能会超过您拥有的细胞数量并导致该问题。

注意: 我已将b的定义更改为从1开始

更新2

再次查看您的代码之后,我在查看导致错误的行时看到了一些我似乎错过的内容。您将b定义为Dim b As Integer = 2 ' I recommended changing that to 1并使用它来访问数据集/阅读器中的列。但是当我查看你的问题时,其他东西就会显露出来。 awal()方法中的第一个是

SELECT * FROM tb_alternatif2 ORDER BY nim

返回一个有序的集合,其中包含一些未知的(无论如何)行数和列数。然后循环将数据读取器的第1列和第2列添加到我假设为数据网格视图的行中。之后,您调用另一个查询

SELECT kode_kriteria, atribut FROM tb_kriteria2 ORDER BY kode_kriteria

返回一个带有2列的有序集,您将其作为列添加到数据网格视图中。接下来,您有查询

SELECT c.nama_crips FROM tb_rel_alternatif2 r --... truncated

返回一列,当您定义 b 时。在您创建的列数之间,然后使用b对其进行寻址,您可能会遇到一个错误。或者不止一个人。假设第二个查询为您创建10列,第三个查询返回15行,您将很快用完代码,使用代码中的.Cells(b).Value来解决。

我不清楚你要对此做些什么,但我建议你再次尝试定义你的查询并将其绑定到数据网格。 顺便说一下:我还建议使用参数来构建查询,因为你做的方式太安全了...... SQL注入等等。

答案 1 :(得分:0)

为什么您在一个地方使用dr.Read()而在另一个地方使用dr.Read。在RED中加下划线。可能还没有填充DataReader!它应该是dr.Read()

Here