繁体   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