VB.Net Global DataSet在公共函数中

时间:2013-10-27 16:09:14

标签: vb.net winforms datatable dataset global

我对某项功能有些疑问,希望你能提供帮助。

我的应用程序很简单,它使用Access数据库加载员工信息,并根据用户可以打印并保存回数据库的单词模板创建信函和财务分类表。

我首先创建了一个包含每个表单子例程的几个数据表的数据集,但它产生了数百行重复代码。但它奏效了。

我想要做的是,有一个数据集包含员工所需的所有信息,并且能够同时通过多个表单引用它。所以我创建了一个如下所示的公共模块:

Public Module Datasets
Public update As String
Dim pCn As OleDb.OleDbConnection

Public Function CSofwareDataSet() As DataSet
    'open new connection to database
    pCn = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=G:\CGI Project\CorrespondenceSoftware\Database1.accdb; Persist Security Info=False;")
    Try
        Call pCn.Open() 'opens the connection
    Catch ex As Exception
        MessageBox.Show("Could not open a database connection! 1")
        MessageBox.Show(ex.ToString)
    End Try

    CSofwareDataSet = New DataSet
Dim daOPG As New OleDb.OleDbDataAdapter("SELECT * FROM Overpayment WHERE PayNumber='" & Main.tbPayNumber.Text & "' AND Gross=1", pCn) 'get all data from Overpayment Details table
Dim daOPN As New OleDb.OleDbDataAdapter("SELECT * FROM Overpayment WHERE PayNumber='" & Main.tbPayNumber.Text & "' AND Net=1", pCn) 'get all data from Overpayment Details table
Dim daOPR As New OleDb.OleDbDataAdapter("SELECT * FROM OvpReasons", pCn) 'get overpayment reasons
Dim daREC As New OleDb.OleDbDataAdapter("SELECT * FROM TaxYear", pCn) 'get recovery date options
Dim daEMP As New OleDb.OleDbDataAdapter("SELECT * FROM EmployeeDetails WHERE PayNumber='" & Main.tbPayNumber.Text & "' AND Active=1 ", pCn) 'get all data from Employee Details table
Dim daCON As New OleDb.OleDbDataAdapter("SELECT * FROM Consultant", pCn) 'get all data from Consultant Details table
Dim daSET As New OleDb.OleDbDataAdapter("SELECT * FROM Settings", pCn) 'get all data from Consultant Details table
'Find the primary key (if missing)
    daOPG.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daOPN.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daOPR.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daREC.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daEMP.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daCON.MissingSchemaAction = MissingSchemaAction.AddWithKey
    daSET.MissingSchemaAction = MissingSchemaAction.AddWithKey
'setup prefixes
Dim cbOPG As New OleDb.OleDbCommandBuilder(daOPG)
    cbOPG.QuotePrefix = "["
    cbOPG.QuoteSuffix = "]"
Dim cbOPN As New OleDb.OleDbCommandBuilder(daOPN)
    cbOPG.QuotePrefix = "["
    cbOPG.QuoteSuffix = "]"
Dim cbOPR As New OleDb.OleDbCommandBuilder(daOPR)
    cbOPG.QuotePrefix = "["
    cbOPG.QuoteSuffix = "]"
Dim cbREC As New OleDb.OleDbCommandBuilder(daREC)
    cbOPG.QuotePrefix = "["
    cbOPG.QuoteSuffix = "]"
Dim cbEMP As New OleDb.OleDbCommandBuilder(daEMP)
    cbEMP.QuotePrefix = "["
    cbEMP.QuoteSuffix = "]"
Dim cbCON As New OleDb.OleDbCommandBuilder(daCON)
    cbEMP.QuotePrefix = "["
    cbEMP.QuoteSuffix = "]"
Dim cbSET As New OleDb.OleDbCommandBuilder(daSET)
    cbEMP.QuotePrefix = "["
    cbEMP.QuoteSuffix = "]"



    If CSofwareDataSet.HasChanges Then
        Try
            daEMP.Update(CSofwareDataSet, "EmployeeDetails")
            daOPG.Update(CSofwareDataSet, "OverPaymentGross")
            daOPN.Update(CSofwareDataSet, "OverPaymentNet")
            daSET.Update(CSofwareDataSet, "Settings")

            MessageBox.Show("Success! Records updated.")
            update = "0"
        Catch ex As Exception
            MessageBox.Show("Oops - something went wrong and it didn't update")
            update = "0"
        End Try
    ElseIf CSofwareDataSet.Tables.Count = 0 Then
        daOPG.Fill(CSofwareDataSet, "OverPaymentGross")
        daOPN.Fill(CSofwareDataSet, "OverPaymentNet")
        daOPR.Fill(CSofwareDataSet, "OverPaymentReasons")
        daREC.Fill(CSofwareDataSet, "RecoveryDates")
        daEMP.Fill(CSofwareDataSet, "EmployeeDetails")
        daCON.Fill(CSofwareDataSet, "ConsultantDetails")
        daSET.Fill(CSofwareDataSet, "Settings")

    End If


    'If update = "1" Then
    ' Try
    ' daEMP.Update(CSofwareDataSet, "EmployeeDetails")
    ' daOPG.Update(CSofwareDataSet, "OverPaymentGross")
    ' daOPN.Update(CSofwareDataSet, "OverPaymentNet")
    ' daSET.Update(CSofwareDataSet, "Settings")
    '
    '        MessageBox.Show("Success! Records updated.")
    '        update = "0"
    '        Catch ex As Exception
    ' MessageBox.Show("Oops - something went wrong and it didn't update")
    ' update = "0"
    ' End Try
    ' End If

    pCn.Close()

End Function
End Module

在每个表单上,它都会被引用(例如):

Imports WeifenLuo.WinFormsUI.Docking
Imports Word = Microsoft.Office.Interop.Word
Imports CorrespondenceSoftware.Datasets

Public Class GrossInput

Dim loading = "1"
Dim NewEmployee = "0" 'sets the default new employee flag to 0
Private pCn As OleDb.OleDbConnection

Private Sub GrossInput_Load(ByVal Sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Try

        Try
            If CSofwareDataSet.Tables("EmployeeDetails").Rows.Count > 0 Then
                For i As Integer = 0 To CSofwareDataSet.Tables("EmployeeDetails").Rows.Count - 1
                    cbTitle.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(2)
                    tbFName.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(3)
                    tbLName.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(4)
                    tbAddress1.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(5)
                    tbAddress2.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(6)
                    tbAddress3.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(7)
                    tbAddress4.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(8)
                    tbPostcode.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(9)
                    tbWorkLocation.Text = CSofwareDataSet.Tables("EmployeeDetails").Rows(i)(10)
                    tbWorkLocation.Enabled = False
                    tbPostcode.Enabled = False
                    tbAddress4.Enabled = False
                    tbAddress3.Enabled = False
                    tbAddress2.Enabled = False
                    tbAddress1.Enabled = False
                    tbLName.Enabled = False
                    tbFName.Enabled = False
                    cbTitle.Enabled = False
                    chkMSC.Enabled = False
                    chkOfficer.Enabled = False
                    chkStaff.Enabled = False
                    bnSaveEmp.Enabled = False
                    bnEditEmp.Enabled = True

                Next
            End If
            If CSofwareDataSet.Tables("EmployeeDetails").Rows(0)(11) = "1" Then
                chkOfficer.Checked = True
            Else
                chkOfficer.Checked = False

            End If
            If CSofwareDataSet.Tables("EmployeeDetails").Rows(0)(12) = "1" Then
                chkStaff.Checked = True
            Else
                chkStaff.Checked = False

            End If
            If CSofwareDataSet.Tables("EmployeeDetails").Rows(0)(13) = "1" Then
                chkMSC.Checked = True
            Else
                chkMSC.Checked = False

            End If

        Catch ex As Exception
            MessageBox.Show(ex.ToString)
            MessageBox.Show("Employee not found. Ensure pay number is correct and create a new record")
            NewEmployee = "1" ' tells the program to create a new record if saved
            cbReference.Enabled = False
            cbReference.Text = ""
            bnEditEmp.Enabled = False
        End Try

        'display the overpayment references to the user
        If CSofwareDataSet.Tables("OverPaymentGross").Rows.Count > 0 Then
            For i As Integer = 0 To CSofwareDataSet.Tables("OverPaymentGross").Rows.Count - 1
                cbReference.Items.Add(CSofwareDataSet.Tables("OverPaymentGross").Rows(i)(2))
            Next
        End If
        'display the available consultants to the user
        If CSofwareDataSet.Tables("ConsultantDetails").Rows.Count > 0 Then
            For i As Integer = 0 To CSofwareDataSet.Tables("ConsultantDetails").Rows.Count - 1
                cbConsultant.Items.Add(CSofwareDataSet.Tables("ConsultantDetails").Rows(i)(1) & " " & CSofwareDataSet.Tables("ConsultantDetails").Rows(i)(2))
            Next
        End If
        'display the available Overpayment reasons to the user
        If CSofwareDataSet.Tables("OverPaymentReasons").Rows.Count > 0 Then
            For i As Integer = 0 To CSofwareDataSet.Tables("OverPaymentReasons").Rows.Count - 1
                cbReason.Items.Add(CSofwareDataSet.Tables("OverPaymentReasons").Rows(i)(1))
            Next
        End If
        'Load other recovery date options 
        If CSofwareDataSet.Tables("RecoveryDates").Rows.Count > 0 Then
            For i As Integer = 0 To CSofwareDataSet.Tables("RecoveryDates").Rows.Count - 1
                cbStartRecovery.Items.Add(CSofwareDataSet.Tables("RecoveryDates").Rows(i)(1))
            Next
        End If


    Catch ex As Exception
        MessageBox.Show(ex.ToString) 'Show any errors to the user
    End Try
    loading = "0"
End Sub

现在!我遇到的问题是,这确实有效并且运行没有任何错误但是每次CSSoftwareDataSet函数运行时它都会正确填充表并返回预期的结果但是它会删除数据表数据,所以每次引用函数时一个winform,它需要从头开始从访问数据库中提取所有数据,严重影响程序的性能。这些表不会正确更新,因为它不存储数据表信息,一旦插入它被遗忘但是再次产生没有错误。我的更新脚本的示例如下所示:

 Else 'create a new record
        'create a new reference
        Dim REFRowCount = CSofwareDataSet.Tables("OverPaymentGross").Rows.Count + 1 'count the number of rows in table and add 1
        Dim NewREF = "OVPG" & Main.tbPayNumber.Text & "-" & REFRowCount
        'Find todays date and reply dates

        Dim TodayDatedate = Format(Now.Date(), "dd/MM/yyyy")
        Dim ReplyDatedate = Format(Now.Date.AddDays(21), "dd/MM/yyyy")

        'Create a new row
        Dim OPNew As DataRow = CSofwareDataSet.Tables("OverPaymentGross").NewRow() 'create a variable to contain the new row
        OPNew.Item(1) = Main.tbPayNumber.Text
        OPNew.Item(2) = NewREF
        OPNew.Item(3) = tbOverpaymentAmount.Text.ToString
        OPNew.Item(4) = tbMonRec.Text
        OPNew.Item(5) = tbTaxP.Text
        OPNew.Item(6) = TodayDatedate
        OPNew.Item(7) = ReplyDatedate
        OPNew.Item(8) = tbMoRep.Text
        OPNew.Item(9) = cbStartRecovery.Text
        OPNew.Item(10) = "1" 'Set as gross
        OPNew.Item(11) = "0" 'do not set as net
        OPNew.Item(12) = cbReason.Text
        OPNew.Item(13) = tbAI.Text
        OPNew.Item(14) = dtpStart.Value.Date
        OPNew.Item(15) = dtpFinish.Value.Date
        OPNew.Item(16) = cbConsultant.Text
        OPNew.Item(17) = tbPosition.Text

        Call CSofwareDataSet.Tables("OverPaymentGross").Rows.Add(OPNew) 'fill the new row and insert the data

必须有一个解决方案。创建一个数据集,在打开其他winforms时将其数据保存在会话中,直到重置为止。我没有想法,因为我真的不想回到我的程序中几乎每个子程序重复所有这些代码。

我希望我已经解释好了..任何帮助都将非常感谢。

非常感谢, 沙恩

1 个答案:

答案 0 :(得分:1)

您可以全局声明DataSet,将其填充到刚开始时调用的函数(sub)中,并通过访问变量而不是一遍又一遍地调用函数来检索信息。你的代码使用了某种模糊的方法(函数和变量的相同名称),它与VB规则(函数可能不包含Return语句但是包含函数名称的变量)不符合你的喜好。

示例代码将DataSet转换为公共变量并重命名该函数(并将其转换为子函数:现在函数的重点是什么?):

Public CSofwareDataSet As DataSet
Public Sub populateDS()
    'open new connection to database
    pCn = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=G:\CGI Project\CorrespondenceSoftware\Database1.accdb; Persist Security Info=False;")
    Try
        Call pCn.Open() 'opens the connection
    Catch ex As Exception
        MessageBox.Show("Could not open a database connection! 1")
        MessageBox.Show(ex.ToString)
    End Try

    CSofwareDataSet = New DataSet

    'Remaining code

End Sub

只调用此sub一次(在应用程序开始时;或每次必须从数据库中检索新数据)并继续使用CSofwareDataSet到目前为止(尽管作为变量,通过删除Call位;另一方面,在VB.NET中根本不需要它。