I have an access database that stores data in a table (called DataCollection) that is logged by a Visual Studio program. 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". The other column is titled "MISSED PART", and it can return only two values, "Missed Part" or "NEATOL". Ideally, I would like to count, using Visual Studio, the number of times "Missed Part" occurs in a certain month.
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:
You will see there are many more columns than mentioned. Please ignore any columns other than "M/Y of Log" and "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:
Private Function CountMissedParts() Handles 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
.
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
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. Give this, and that I used month() and year() functions? 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.
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. 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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.