我想问一下是否有人知道这个错误发生的原因?所以有两种形式。第一个计算形式没有错误,这是产生错误的第二个计算形式,在搜索到这里和那里masi尚未启示后,也许有人可以帮忙吗?
这个完整的源代码
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
答案 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)