在datagridview中保存数据,以便在关闭程序后它仍然存在

时间:2015-04-24 22:19:48

标签: database vb.net datagridview save

我知道这个主题有很多,但我似乎无法获取信息并将其自定义为我的代码。 我在保存数据时遇到问题,因此当我关闭程序并再次打开数据时数据仍然存在。这是一个简单的程序,数据通过文本框输入到数据中网格视图。起初没有任何事情发生,但在我的代码工作数小时之后,我开始在dataAdapter.Update(dt)行上收到此错误消息:

  

多个基表不支持动态SQL生成。

我知道我的代码并没有遵循最佳实践规则,但我对编程非常陌生,所以玩得很好。在此先感谢,我真的很感激帮助。

这是我的代码:

Public Class frmGradeBook
    'data grid view for recording students grades
    Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=GRADEBOOK.accdb"
    Dim sqlStr As String = "SELECT firstName,lastName,firstExam,secondExam,finalExam " & _
                    "FROM Students INNER JOIN Grades ON Students.studentID = Grades.studentID "
    Dim dataAdapter As New OleDb.OleDbDataAdapter(sqlStr, connStr)
    Dim dt As New DataTable()

    'secondary data grid view for displaying students grade
    Dim connStr1 As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=GRADEBOOK.accdb"
    Dim sqlStr1 As String = "SELECT firstName, lastName, finalExam FROM Students INNER JOIN Grades ON Students.studentID = Grades.studentID "
    Dim dataAdapter1 As New OleDb.OleDbDataAdapter(sqlStr1, connStr1)
    Dim dt1 As New DataTable()

Private Sub frmGradeBook_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    dataAdapter.Fill(dt)
    dgvRecordGrades.DataSource = dt

    dataAdapter1.Fill(dt1)
    dgvDisplayGrades.DataSource = dt1

    dgvDisplayGrades.Visible = False
    lstGrade.Visible = False

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnRecord.Click

    dgvDisplayGrades.Visible = False
    dgvRecordGrades.Visible = True
    lstGrade.Visible = False

    'validates the data
    Dim studentID As String = txtID.Text.ToUpper
    Dim row As Integer
    Dim dataGridRow As DataGridViewRow = dgvRecordGrades.Rows(1)

        If IsNumeric(txtFirstExam.Text) And IsNumeric(txtSecExam.Text) And IsNumeric(txtFinalExam.Text) Then
            If (txtFirstExam.Text).ToString().IndexOf(".") = -1 Then
                Dim firstExam As Double = CDbl(txtFirstExam.Text)
                Dim secondExam As Double = CDbl(txtSecExam.Text)
                Dim finalExam As Double = CDbl(txtFinalExam.Text)

                If firstExam <= 100 And secondExam <= 100 And finalExam <= 100 Then
                    If firstExam >= 0 And secondExam >= 0 And finalExam >= 0 Then

                        If studentID = "AJ-123456" Then
                            row = 0
                        ElseIf studentID = "FA-192837" Then
                            row = 1
                        ElseIf studentID = "GG-567876" Then
                            row = 2
                        ElseIf studentID = "GJ-987654" Then
                            row = 3
                        ElseIf studentID = "LS-222333" Then
                            row = 4
                        Else
                            MessageBox.Show("The student ID provided is not valid. Please try again.")
                        End If

                    'records the grades
                        dgvRecordGrades.Item(2, row).Value = firstExam
                        dgvRecordGrades.Item(3, row).Value = secondExam
                        dgvRecordGrades.Item(4, row).Value = finalExam

                    Else
                        MessageBox.Show("Invalid input. Please try again")
                    End If
                Else
                    MessageBox.Show("Invalid input. Please try again")
                End If
            Else
                MessageBox.Show("Please enter whole numbers. Try again.")
            End If

        Else
            MessageBox.Show("Invalid input. Please try again")
        End If


End Sub

Private Sub Button1_Click_2(sender As Object, e As EventArgs) Handles btnPostable.Click
    dgvRecordGrades.Visible = False
    dgvDisplayGrades.Visible = False
    lstGrade.Visible = True

    lstGrade.Items.Clear()

    If Not IsDBNull((dgvDisplayGrades.Item(2, 0).Value)) Then
        lstGrade.Items.Add("3456    " & LetterGrade(CDbl(dgvDisplayGrades.Item(2, 0).Value)))
    Else
        lstGrade.Items.Add("3456    NO GRADE AVAILABLE")
    End If

    If Not IsDBNull((dgvDisplayGrades.Item(2, 1).Value)) Then
        lstGrade.Items.Add("2837    " & LetterGrade(CDbl(dgvDisplayGrades.Item(2, 1).Value)))
    Else
        lstGrade.Items.Add("2837    NO GRADE AVAILABLE")
    End If

    If Not IsDBNull((dgvDisplayGrades.Item(2, 2).Value)) Then
        lstGrade.Items.Add("7876    " & LetterGrade(CDbl(dgvDisplayGrades.Item(2, 2).Value)))
    Else
        lstGrade.Items.Add("7876    NO GRADE AVAILABLE")
    End If

    If Not IsDBNull((dgvDisplayGrades.Item(2, 3).Value)) Then
        lstGrade.Items.Add("7654    " & LetterGrade(CDbl(dgvDisplayGrades.Item(2, 3).Value)))
    Else
        lstGrade.Items.Add("7654    NO GRADE AVAILABLE")
    End If

    If Not IsDBNull((dgvDisplayGrades.Item(2, 4).Value)) Then
        lstGrade.Items.Add("2333    " & LetterGrade(CDbl(dgvDisplayGrades.Item(2, 4).Value)))
    Else
        lstGrade.Items.Add("2333    NO GRADE AVAILABLE")
    End If
End Sub

Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles btnDisplay.Click
    dgvDisplayGrades.Visible = True
    dgvRecordGrades.Visible = False
    lstGrade.Visible = False

    For col As Integer = 2 To 2
        For row As Integer = 0 To 4
            If Not IsDBNull(dgvRecordGrades.Item(col, row).Value) Then
                Dim firstExam As Double = CDbl(dgvRecordGrades.Item(2, row).Value)
                Dim secExam As Double = CDbl(dgvRecordGrades.Item(3, row).Value)
                Dim finalExam As Double = CDbl(dgvRecordGrades.Item(4, row).Value)
                dgvDisplayGrades.Item(2, row).Value = SemAvg(firstExam, secExam, finalExam)
            Else
            End If
        Next
    Next

End Sub


Function SemAvg(firstMid As Double, secondMid As Double, final As Double) As Double
    Dim semAverage As Double
    semAverage = (firstMid + secondMid + (2 * final)) / 4
    Math.Round(semAverage)
    Return semAverage
End Function


Function LetterGrade(semAvg As Double) As String
    Select Case semAvg
        Case Is >= 90
            Return "A"
        Case Is >= 80
            Return "B"
        Case Is >= 70
            Return "C"
        Case Is >= 60
            Return "D"
        Case Else
            Return "F"
    End Select
End Function



Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    Dim changes As Integer
    Dim commandBuilder As New  _
                            OleDb.OleDbCommandBuilder(dataAdapter)
    changes = dataAdapter.Update(dt)
    If changes > 0 Then
        MessageBox.Show(changes & " changed rows.")
    Else
        MessageBox.Show("No changes made.")
    End If

End Sub


Private Sub frmGradeBook_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    dataAdapter.Dispose()
    dataAdapter1.Dispose()

End Sub
End Class

1 个答案:

答案 0 :(得分:0)

我认为以下是问题。

您正在填写dataAdapter中的 datatable dt ,其中包含以下内容

  

的CommandText =

"SELECT firstName,lastName,firstExam,secondExam,finalExam " & _
            "FROM Students INNER JOIN Grades ON Students.studentID = Grades.studentID "

两个表中检索数据。

要从 dataAdapter 获取自动更新命令,您必须从只有一个主表表中检索数据主键< / em>的

  

您无法从多个表中检索以使用 dataAdapter.UpdateCommand 属性。

希望这有帮助。