[英]How to Count Values in Access Database using Visual Studio VB.NET
I have an access database that stores data in a table (called DataCollection) that is logged by a Visual Studio program.我有一个访问数据库,它将数据存储在由 Visual Studio 程序记录的表(称为 DataCollection)中。 I have been struggling to find a solution to how to count the number records that contain specific values in specific columns.
我一直在努力寻找解决方案来计算特定列中包含特定值的记录数。
For example, in my database, there are two columns.例如,在我的数据库中,有两列。 One column is titled "M/Y OF LOG" and it returns dates formatted like this "1/1/2021".
一列标题为“M/Y OF LOG”,它返回格式如下“1/1/2021”的日期。 The other column is titled "MISSED PART", and it can return only two values, "Missed Part" or "NEATOL".
另一列标题为“MISSED PART”,它只能返回两个值,“Missed Part”或“NEATOL”。 Ideally, I would like to count, using Visual Studio, the number of times "Missed Part" occurs in a certain month.
理想情况下,我想使用 Visual Studio 计算某个月“遗漏部分”发生的次数。
Does anyone have any ideas on how the code for this may look, or if counting like this is even possible?有没有人对代码的外观有任何想法,或者是否有可能这样计算?
My connection string:我的连接字符串:
connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database1.accdb"
Preview of my Access database formatting:我的 Access 数据库格式预览:
You will see there are many more columns than mentioned.您会看到比提到的要多得多的列。 Please ignore any columns other than "M/Y of Log" and "Missed Part"
请忽略除“M/Y of Log”和“Missed Part”以外的任何栏目
I have these variables in my code.我的代码中有这些变量。 They will be the variables that hole the return values from the database, used as y values in graphs to display the data:
它们将是从数据库中获取返回值的变量,用作图表中的 y 值以显示数据:
Private Function CountMissedParts() Handles MyBase.Load私有 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
That example uses a hard-coded date but you can get the date value from anywhere you like.该示例使用硬编码日期,但您可以从任何您喜欢的地方获取日期值。 A
Date
is a Date
.一个
Date
就是一个Date
。
There is no need to define variable for each month, you can use loop instead.无需为每个月定义变量,您可以使用循环代替。
Check the following code:检查以下代码:
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
Well, I assume that the date column is a in fact a actual date column.好吧,我假设日期列实际上是一个实际的日期列。 That way, your display of the date does NOT matter.
这样,您显示的日期就没有关系了。 As a general rule, all dates are stored in a internal format - you don't care about the external.
作为一般规则,所有日期都以内部格式存储 - 您不关心外部格式。
So, all we REALLY need is the month, and year you want.所以,我们真正需要的只是您想要的月份和年份。
So, build a form with two text boxes.因此,构建一个包含两个文本框的表单。 One text box has year, the other the month.
一个文本框有年份,另一个有月份。
Say like this:像这样说:
So, this code would prompt you for the year, then the month, and then spit out the results.所以,这段代码会提示你输入年份,然后是月份,然后输出结果。
the button code can be this, and it will give a total for both Missed and NeatOL按钮代码可以是这个,它将给出 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
Edit:编辑:
As a follow up?作为跟进? It looks like you have a single column that is ALWAYS set to the 1st of the month.
看起来您有一个始终设置为每月 1 日的列。 Give this, and that I used month() and year() functions?
给出这个,我使用了 month() 和 year() 函数? Well, using month() and year() is great for things like say who has a birthday this month, ( we can use month() and day() to extract the month, day and ignore the year.
好吧,使用 month() 和 year() 非常适合说谁在这个月过生日,(我们可以使用 month() 和 day() 来提取月份、日期并忽略年份。
HOWEVER, we should STILL include a valid date range.但是,我们仍然应该包括一个有效的日期范围。 The reason is of course "indexing" or the so called term "sargable".
原因当然是“索引”或所谓的术语“可搜索”。 The above query as written can't use indexing for the results.
上面写的查询不能对结果使用索引。 Thus for a large table, the posted query will run quite slow.
因此对于大表,发布的查询将运行得相当慢。
A better (and much faster) performing SQL query would be this, assuming there is a index on the MY/Y column.假设 MY/Y 列上有一个索引,执行 SQL 查询会更好(也更快)。 Thus, I suggest this solution:
因此,我建议这个解决方案:
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.
I think the following code will get you the data you need.我认为以下代码将为您提供所需的数据。 Ask another question if you need the data.table columns translated to the chart.
如果您需要将 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.