簡體   English   中英

如何使用 Visual Studio 計算 Access 數據庫中的值 VB.NET

[英]How to Count Values in Access Database using Visual Studio VB.NET

我有一個訪問數據庫,它將數據存儲在由 Visual Studio 程序記錄的表(稱為 DataCollection)中。 我一直在努力尋找解決方案來計算特定列中包含特定值的記錄數。

例如,在我的數據庫中,有兩列。 一列標題為“M/Y OF LOG”,它返回格式如下“1/1/2021”的日期。 另一列標題為“MISSED PART”,它只能返回兩個值,“Missed Part”或“NEATOL”。 理想情況下,我想使用 Visual Studio 計算某個月“遺漏部分”發生的次數。

有沒有人對代碼的外觀有任何想法,或者是否有可能這樣計算?

我的連接字符串:

connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database1.accdb"

我的 Access 數據庫格式預覽:

您會看到比提到的要多得多的列。 請忽略除“M/Y of Log”和“Missed Part”以外的任何欄目

在此處輸入圖像描述

我的代碼中有這些變量。 它們將是從數據庫中獲取返回值的變量,用作圖表中的 y 值以顯示數據:

私有 Function CountMissedParts() 處理 MyBase.Load

    Dim sql = $"SELECT COUNT(*)
        FROM DataCollection
        WHERE [MISSED PART] = 'Missed Part'
        AND [M/Y OF LOG] = @MY_OF_LOG;"
    Dim JANmyOfLog = #1/1/2021#
    Dim FEBmyOfLog = #2/1/2021#
    Dim MARmyOfLog = #3/1/2021#
    Dim APRmyOfLog = #4/1/2021#
    Dim MAYmyOfLog = #5/1/2021#
    Dim JUNmyOfLog = #6/1/2021#
    Dim JULmyOfLog = #7/1/2021#
    Dim AUGmyOfLog = #8/1/2021#
    Dim SEPmyOfLog = #9/1/2021#
    Dim OCTmyOfLog = #10/1/2021#
    Dim NOVmyOfLog = #11/1/2021#
    Dim DECmyOfLog = #12/1/2021#
    Dim count As Integer
    Dim JanuaryMP As Double
    Dim FebruaryMP As Double
    Dim MarchMP As Double
    Dim AprilMP As Double
    Dim MayMP As Double
    Dim JuneMP As Double
    Dim JulyMP As Double
    Dim AugustMP As Double
    Dim SeptemberMP As Double
    Dim OctoberMP As Double
    Dim NovemberMP As Double
    Dim DecemberMP As Double

    Using connection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database1.accdb"),
            command As New OleDbCommand(sql, connection)
        JanuaryMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = JANmyOfLog
        FebruaryMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = FEBmyOfLog
        MarchMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = MARmyOfLog
        AprilMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = APRmyOfLog
        MayMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = MAYmyOfLog
        JuneMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = JUNmyOfLog
        JulyMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = JULmyOfLog
        AugustMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = AUGmyOfLog
        SeptemberMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = SEPmyOfLog
        OctoberMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = OCTmyOfLog
        NovemberMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = NOVmyOfLog
        DecemberMP = command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = DECmyOfLog
        connection.Open()
        count = command.ExecuteScalar()




        ' set 0,0
        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(0, 0)
        ' other points
        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(1, JanuaryMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(2, FebruaryMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(3, MarchMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(4, AprilMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(5, MayMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(6, JuneMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(7, JulyMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(8, AugustMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(9, SeptemberMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(10, OctoberMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(11, NovemberMP)

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(12, DecemberMP)

    End Using
    NotInEpicorCHRT.ChartAreas(0).AxisX.Minimum = 0.0
    NotInEpicorCHRT.ChartAreas(0).AxisX.Maximum = 12
    NotInEpicorCHRT.ChartAreas(0).AxisX.Interval = 1
    NotInEpicorCHRT.ChartAreas(0).AxisY.Minimum = 0.0
    NotInEpicorCHRT.ChartAreas(0).AxisY.Maximum = 45
    NotInEpicorCHRT.ChartAreas(0).AxisY.Interval = 5
End Function
Dim sql = $"SELECT COUNT(*)
            FROM DataCollection
            WHERE [MISSED PART] = 'Missed Part'
            AND [M/Y OF LOG] = @MY_OF_LOG"
Dim myOfLog = #1/01/2021#
Dim count As Integer

Using connection As New OleDbConnection("connection string here"),
      command As New OleDbCommand(sql, connection)
    command.Parameters.Add("@MY_OF_LOG", OleDbType.Date).Value = myOfLog
    connection.Open()
    count = CInt(command.ExecuteScalar())
End Using

該示例使用硬編碼日期,但您可以從任何您喜歡的地方獲取日期值。 一個Date就是一個Date

無需為每個月定義變量,您可以使用循環代替。

檢查以下代碼:

    Dim count As Integer
    Dim lst As List(Of Double) = New List(Of Double)

    Dim sql = $"SELECT COUNT(*) FROM DataCollection WHERE [MISSED PART] = 'Missed Part' AND [M/Y OF LOG] = @MY_OF_LOG;"

    Using connection As New OleDbConnection("your connection String"),
            command As New OleDbCommand(sql, connection)
        connection.Open()

        For i As Integer = 1 To 12
            command.Parameters.Clear()
            Dim dtime = New DateTime(2021, i, 1).ToString("MM/dd/yyyy")
            command.Parameters.AddWithValue("@MY_OF_LOG", dtime)
            count = command.ExecuteScalar()
            lst.Add(count)
        Next

        NotInEpicorCHRT.Series("Missed Part").Points.AddXY(0, 0)
        For j As Integer = 1 To lst.Count
            NotInEpicorCHRT.Series("Missed Part").Points.AddXY(j, lst(j - 1))
        Next

    End Using
    NotInEpicorCHRT.ChartAreas(0).AxisX.Minimum = 0.0
    NotInEpicorCHRT.ChartAreas(0).AxisX.Maximum = 12
    NotInEpicorCHRT.ChartAreas(0).AxisX.Interval = 1
    NotInEpicorCHRT.ChartAreas(0).AxisY.Minimum = 0.0
    NotInEpicorCHRT.ChartAreas(0).AxisY.Maximum = 45
    NotInEpicorCHRT.ChartAreas(0).AxisY.Interval = 5

好吧,我假設日期列實際上是一個實際的日期列。 這樣,您顯示的日期就沒有關系了。 作為一般規則,所有日期都以內部格式存儲 - 您不關心外部格式。

所以,我們真正需要的只是您想要的月份和年份。

因此,構建一個包含兩個文本框的表單。 一個文本框有年份,另一個有月份。

像這樣說:

在此處輸入圖像描述

所以,這段代碼會提示你輸入年份,然后是月份,然后輸出結果。

按鈕代碼可以是這個,它將給出 Missed 和 NeatOL 的總數

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

    Dim strSQL As String

    strSQL = "SELECT abs(SUM([Missed Part] = 'Missed Part')) As MissPCount " &
             "abs(SUM([Missed Part] = 'NEATOL')) As MissNCount " &
             "FROM DataCollection WHERE Month([M/Y OF LOG]) = @Month " &
             "AND Year([M/Y OF LOG]) = @Year"

    Using cmdSQL As New OleDbCommand(strSQL,
            New OleDbConnection(My.Settings.TestDB))

        cmdSQL.Parameters.Add("@Month", OleDbType.Integer).Value = txtMonth.Text
        cmdSQL.Parameters.Add("@Year", OleDbType.Integer).Value = txtYear.Text

        cmdSQL.Connection.Open()
        Dim rstTable As New DataTable

        rstTable.Load(cmdSQL.ExecuteReader)

        ' display the reuslts in the two text boxes.
        With rstTable.Rows(0)

            txtNeatCount.Text = .Item("MissNCount")
            txtPartCount.Text = .Item("MissPCount")

        End With

    End Using

End Sub

編輯:

作為跟進? 看起來您有一個始終設置為每月 1 日的列。 給出這個,我使用了 month() 和 year() 函數? 好吧,使用 month() 和 year() 非常適合說誰在這個月過生日,(我們可以使用 month() 和 day() 來提取月份、日期並忽略年份。

但是,我們仍然應該包括一個有效的日期范圍。 原因當然是“索引”或所謂的術語“可搜索”。 上面寫的查詢不能對結果使用索引。 因此對於大表,發布的查詢將運行得相當慢。

假設 MY/Y 列上有一個索引,執行 SQL 查詢會更好(也更快)。 因此,我建議這個解決方案:

    strSQL = "SELECT abs(SUM([Missed Part] = 'Missed Part')) As MissPCount " &
             "abs(SUM([Missed Part] = 'NEATOL' As MissNCount " &
             "FROM DataCollection WHERE [M/Y OF LOG] = @MyDate "

    Dim dtMyDate As Date = DateSerial(txtYear.Text, txtMonth.Text, 1)

    Using cmdSQL As New OleDbCommand(strSQL,
            New OleDbConnection(My.Settings.TestDB))

        cmdSQL.Parameters.Add("@MyDate", OleDbType.DBDate).Value = dtMyDate

        cmdSQL.Connection.Open()
etc. etc. etc. etc.

我認為以下代碼將為您提供所需的數據。 如果您需要將 data.table 列轉換為圖表,請提出另一個問題。

Private Sub OPCode()
    Dim sql = $"SELECT [M/Y OF LOG], COUNT([Missed Part]) As Total
                FROM [Data Collection]
                WHERE [MISSED PART] = 'MISSED PART'
                GROUP BY [M/Y OF LOG] 
                ORDER BY [M/Y OF LOG];"
    Dim dt As New DataTable
    Using cn As New OleDbConnection(My.Settings.DataCollection),
            cmd As New OleDbCommand(sql, cn)
        cn.Open()
        dt.Load(cmd.ExecuteReader)
    End Using
    DataGridView1.DataSource = dt
End Sub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM