所以我在尝试运行我的代码时遇到此错误“System.IndexOutOfRangeException:'索引超出了数组的范围。'”我不确定问题是什么。用户应该能够输入3个分配等级,然后查看平均值
我在“这就是错误”
标记了我收到错误的行
Public Class GradeBook
Dim grade(9, 2) As Integer 'Store 10 student grades on 3 tests'
Dim studentCount As Integer = 0 'Number of students entered'
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
End Sub
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
grade(studentCount, 0) = Convert.ToInt32(Assignment1TextBox.Text)
grade(studentCount, 1) = Convert.ToInt32(Assignment2TextBox.Text)
grade(studentCount, 2) = Convert.ToInt32(Assignment3TextBox.Text)
Dim output As String = "Student " & studentCount & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(studentCount, column))
Else
output &= vbTab & grade(studentCount, column)
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
End Select
Return output
End Function
Function CalculateStudentAverage(ByVal row As Integer) As String
Dim gradeTotal As Integer = 0
For column = 0 To grade.GetUpperBound(1)
gradeTotal += grade(row, column) 'THIS IS THE ERROR'
Next
Dim studentAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
studentAverage = LetterGrade(gradeTotal / (grade.GetUpperBound(1) + 1))
Else
studentAverage = String.Format("{0:F}", (gradeTotal / grade.GetUpperBound(1) + 1))
End If
Return studentAverage
End Function
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For row = 0 To studentCount - 1
For column = 0 To grade.GetUpperBound(1)
classTotal += grade(row, column)
Next
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = LetterGrade(classTotal / (studentCount * (grade.GetUpperBound(1) + 1)))
Else
classAverage = String.Format("{0:F}", (classTotal / (studentCount * (grade.GetUpperBound(1) + 1))))
End If
Return classAverage
End Function
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For row = 0 To studentCount - 1
Dim output As String = "Student " & row & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(row, column))
Else
output &= vbTab & (grade(row, column))
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
If studentCount = grade.GetUpperBound(0) + 1 Then
InputGradeGroupBox.Enabled = False
End If
Next
End Sub
End Class
答案 0 :(得分:0)
说实话,我怀疑你是否以不适合OOP的方式处理它。对多个数据使用数组很容易出错,以后难以维护。
让我们考虑一下您希望如何表示数据。你有一群学生。在一个更完整的例子中,每个学生都会有一个姓名,个人详细信息,例如地址,他们正在接受的课程列表以及每门课程,每个作业的作业列表和分数,也可以表示为级。
所以从本质上讲,你有一个名为Student
的类,各种信息都是该学生的属性。
最后你有一个这些学生的名单
在您的代码中,您只需拥有一个学号和三个作业分数。
您的基础学生课程应具有Number,Test1Score,Test2Score和Test3Score的属性。您还希望能够从每个分数,所有分数的平均分数和所有分数的平均分数中获得分数。
下面的代码定义了Student
类,并记住了这些信息
Friend Class Student
Public Property Number As Integer
Public Property Test1Score As Integer
Public Property Test2Score As Integer
Public Property Test3Score As Integer
Public Function Test1Grade() As String
Return LetterGrade(Test1Score)
End Function
Public Function Test2Grade() As String
Return LetterGrade(Test2Score)
End Function
Public Function Test3Grade() As String
Return LetterGrade(Test3Score)
End Function
Friend Shared Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
Case Else
output = "F"
End Select
Return output
End Function
Friend Function AverageScore() As Double
Return (Test1Score + Test2Score + Test3Score) / 3
End Function
Friend Function AverageGrade() As String
Dim avgscore As Double = AverageScore()
Return LetterGrade(avgscore)
End Function
End Class
LetterGrade函数为Shared
,因此可以在主表单中使用它来计算整个班级的平均成绩。
确定接下来想想您希望程序如何运作。你需要一份学生名单,所以在你的表格课程开始时,你需要这个......
Public Class Form1
Private Students As New List(Of Student)
这样,您可以使用列表中的studentCount
属性.Count
,而不是尝试跟踪变量Students.Count
。您不需要添加任何内容,因为Students
列表会自动跟踪它。
接下来,您将需要计算班级平均分数/成绩的函数。
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For Each tmpStudent As Student In Students
With tmpStudent
classTotal += .Test1Score + .Test2Score + .Test3Score
End With
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = Student.LetterGrade((classTotal / Students.Count) / 3)
Else
classAverage = String.Format("{0:F}", (classTotal / (Students.Count)) / 3)
End If
Return classAverage
End Function
正如您所看到的,由于您的数据存储方式,这里存在许多差异,但您应该能够遵循它。一个区别是With
语句,这允许您节省输入。在With.. End With
块内,您只需输入tmpstudent.Test1Score
.Test1Score
等。
另一点需要注意的是这条线..
classAverage = Student.LetterGrade(... etc
您可能认为没有声明名为Student
的变量。有一个类,但不是变量。这实际上是在调用LetterGrade
类定义中共享的Student
函数。看看共享函数。
接下来是在ListBox中显示信息的代码。我没有改变名称,即使它误导了btw。
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For Each tmpstudent As Student In Students
Dim output As String = "Student " & tmpstudent.Number & vbTab
With tmpstudent
If LetterRadioButton.Checked = True Then
output &= .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade & vbTab & .AverageGrade
Else
output &= .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score & vbTab & .AverageScore
End If
End With
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
Next
If Students.Count = 10 Then
InputGradeGroupBox.Enabled = False
End If
End Sub
再次使用With..End With
语句,但其余内容应该直截了当。
一点点代码..当您点击LetterRadioButton
时,listBox和ClassAveragelabel中的数据将使用相应的字母/成绩进行刷新
Private Sub LetterRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles LetterRadioButton.CheckedChanged
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
最后,要将所有内容整合在一起,您需要点击按钮的代码..
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
Dim tmpStudent As New Student With {.Number = Students.Count + 1,
.Test1Score = Convert.ToDouble(Assignment1TextBox.Text),
.Test2Score = Convert.ToDouble(Assignment2TextBox.Text),
.Test3Score = Convert.ToDouble(Assignment3TextBox.Text)}
Dim output As String = "Student " & tmpStudent.Number & vbTab
With tmpStudent
If LetterRadioButton.Checked = True Then
output &= vbTab & .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade
Else
output &= vbTab & .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score
End If
End With
Students.Add(tmpStudent)
If LetterRadioButton.Checked Then
output &= vbTab & tmpStudent.AverageGrade
Else
output &= vbTab & tmpStudent.AverageScore
End If
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
End Sub
希望除了我对您的问题的评论之外,这还可以更好地了解OOP。