Please any one help me, I just making a micro finance type software, there was a problem I want to show every week data from access database to vb.net datagrid view but don't work my code,
I insert EntryDate Savings Entry Lable Date (lblSavingsEntryDate.Text = Date.Now.ToString("dd/MM/yyyy"))
Here is my Code
Private Sub btnBalanceWeekly_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBalanceWeekly.Click
Dim Sunday = DateTime.Now.AddDays((Today.DayOfWeek - DayOfWeek.Sunday) * -1).ToString("dd/MM/yyyy")
Dim todate = DateTime.Now.AddDays(0).ToString("dd/MM/yyyy")
Try
Dim sqlstr1 As String
sqlstr1 = "SELECT * FROM Receivedtbl WHERE EntryDate BETWEEN '" + Sunday + "' And '" + todate + "'"
Dim da As New OleDbDataAdapter(sqlstr1, conn2)
Dim dt As New DataTable("Receivedtbl")
da.Fill(dt)
dgvBalanceSavings.DataSource = dt
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
conn2.Close()
Me.BalanceTotalSeavings()
Me.BalanceGrpReceived()
Me.BalanceCusReceived()
End Try
End Sub
Please Help... How can show data in every week.
It's much more secure and safer way using Parameters (DataAdapter will convert in proper way date, datetime format in sql) instead converting date into string, especially because different date formats and avoiding sql injection.
Bellow is example with using Parameters in, let say, source format (in this case date data type) :
Private Sub btnBalanceWeekly_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBalanceWeekly.Click
Dim Sunday = DateTime.Now.AddDays((Today.DayOfWeek - DayOfWeek.Sunday) * -1)
Dim todate = DateTime.Now.AddDays(0)
Try
Dim sqlstr1 As String
sqlstr1 = "SELECT * FROM Receivedtbl WHERE EntryDate BETWEEN #sunday AND #todate;"
Dim da As New OleDbDataAdapter(sqlstr1, conn2)
da.SelectCommand.Parameters.AddWithValue("#sunday", Sunday)
da.SelectCommand.Parameters.AddWithValue("#todate", todate)
Dim dt As New DataTable("Receivedtbl")
da.Fill(dt)
dgvBalanceSavings.DataSource = dt
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
conn2.Close()
Me.BalanceTotalSeavings()
Me.BalanceGrpReceived()
Me.BalanceCusReceived()
End Try
End Sub
By this way You don't have to worry about date format conversion.
You trying to compare a date (string date) as "dd/MM/yyyy" format and you have a big problem because your query will be like this in runtime :
WHERE EntryDate BETWEEN '11/02/2018' And '12/02/2018'
Result : Tons of strings are between these dates
For example : '11/02/2018','11/03/2018','11/04/2018', even another year like '11/02/2019'
In string compare, early characters always compare first and they are more important in compare system (in this case your 4 chars for year have less priority than month and even day)
Solution :
Use this format for saving your date :
.ToString("yyyy/MM/dd")
So your code should be like this :
Private Sub btnBalanceWeekly_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBalanceWeekly.Click
Dim Sunday = DateTime.Now.AddDays((Today.DayOfWeek - DayOfWeek.Sunday) * -1).ToString("yyyy/MM/dd")
Dim todate = DateTime.Now.AddDays(0).ToString("yyyy/MM/dd")
Try
Dim sqlstr1 As String
sqlstr1 = "SELECT * FROM Receivedtbl WHERE EntryDate BETWEEN '" + Sunday + "' And '" + todate + "'"
Dim da As New OleDbDataAdapter(sqlstr1, conn2)
Dim dt As New DataTable("Receivedtbl")
da.Fill(dt)
dgvBalanceSavings.DataSource = dt
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
conn2.Close()
Me.BalanceTotalSeavings()
Me.BalanceGrpReceived()
Me.BalanceCusReceived()
End Try
End Sub
But remember you need save your date string with this format too (old dates which already saved in your database)
First and forever turn on Option Strict. Compile Time errors - good, you can fix them. Runtime errors bad, you might not catch them.
Add two DateTimePicker controls to your form and appropriate labels. There are all kinds of properties you can set if the defaults don't suit you.
The following code shows you how to use parameters with your SQL strings. This not only saves you headaches formating your string but could save your database from malicious input.
Private Sub GetSavings()
Dim da As New OleDbDataAdapter
Dim strSQL As String = "SELECT * FROM Receivedtbl WHERE EntryDate BETWEEN #FromDate And #ToDate;"
Dim FromDate As Date = DateTimePicker1.Value.Date
Dim ToDate As Date = DateTimePicker2.Value.Date
If FromDate >= ToDate Then
MessageBox.Show("From date must be earlier than To date.")
Exit Sub
End If
Dim cmd As New OleDbCommand With {
.Connection = conn2,
.CommandType = CommandType.Text,
.CommandText = strSQL}
'Access cares not about the parameter names but about there order
cmd.Parameters.Add("#FromDate", OleDbType.Date).Value = FromDate
cmd.Parameters.Add("#ToDate", OleDbType.Date).Value = ToDate
da.SelectCommand = cmd
'now continue with your .Fill code
End Sub
Related
I am working on a project using vb and one of my forms has to display the current active reminders (reminders that haven't hit their deadline yet) into a datagridview and I have another datagridview for reminders that are past the deadline. The date and time along with reminder information is saved into my access database and I want to read the date and time from database and compare it to the system date and time and then display the reminder information.
This is how my form looks like; the top datagridview is for current reminders and the bottom one is for past/out of date reminders:
This the code for my form and what I’ve tried:
Imports System.Data.OleDb
Public Class frmReminderInfo
Private Sub frmReminderInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DisplayCurrentReminders()
End Sub
Private Sub DisplayCurrentReminders()
Dim ReminderDateTime As Date
Dim CurrentDateTime As Date
CurrentDateTime = Date.Now
CurrentDateTime = FormatDateTime(Date.Now, DateFormat.GeneralDate)
ReminderDateTime = FormatDateTime(ReminderDateTime, DateFormat.GeneralDate)
If DbConnect() Then
DgvCurrentReminders.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "SELECT ReminderDate FROM TblReminder "
Dim rs As OleDbDataReader = .ExecuteReader()
While rs.Read
ReminderDateTime = (rs(0).ToString)
End While
End With
End If
cn.Close()
If CurrentDateTime = ReminderDateTime Then
Dim SQLCmd As New OleDbCommand
With SQLCmd
Dim rs As OleDbDataReader = .ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvCurrentReminders)
NewStockRow.SetValues({rs("ReminderID"), rs("CustomerName"), rs("DeviceInfo"), rs("RepairPrice"), rs("ReminderDate")})
NewStockRow.Tag = rs("ReminderID")
DgvCurrentReminders.Rows.Add(NewStockRow)
End While
rs.Close()
End With
End If
cn.Close()
End Sub
End Class
Disposable database objects like Connection should be declared locally in the method where they are used in a Using block.
You don't seem to have any idea of what the parts of an Sql string mean. The Select portion list the fields you want to retrieve. A star (*) in this clause means select all the fields. Here we are using a Where clause to filter the records. Only records where the field ReminderDate is greater than or equal to a parameter will be returned. This will only work if the data has been inserted properly as a DateTime.
The While loop keeps overwriting the value of ReminderDateTime on each iteration so only the last value returned by the reader will remain. Also, you are trying to force a String into a variable declared as a Date. Won't work.
Assuming the code could get beyond If CurrentDateTime = ReminderDateTime Then you would be working with a closed connection. Commands can't execute on a closed connection.
You also don't seem to have an idea how class objects work. Dim SQLCmd As New OleDbCommand Here you declare a new instance of the Command. You have no connection and no CommandText so it can't possibly be executed.
Take a look at the following code until it starts to make sense. Look up what Using blocks do. Look up the Load method of a DataTable to see what it does. Check out what a DataSource property has to offer.
Private Sub frmReminderInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = GetCurrentReminders()
DgvCurrentReminders.DataSource = dt
End Sub
Private Function GetCurrentReminders() As DataTable
Dim dt As New DataTable
Using cn As New OleDbConnection("Your connection string"),
SQLCmd As New OleDbCommand("SELECT * FROM TblReminder Where ReminderDate >= #Date", cn)
SQLCmd.Parameters.Add("#Date", OleDbType.Date).Value = Now
cn.Open()
Using reader = SQLCmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function
In a booking form, i want to compare the entered date in the textbox(text mode is date) and all the dates in the database. So if there is an order already booked on that day, it will display already booked select another date otherwise it will carry on the form filling.(in vb.net-visual studio 2012)
this is the code
Protected Sub tbdate_TextChanged(sender As Object, e As EventArgs) Handles tbdate.TextChanged
Dim adaptor As New SqlDataAdapter
Dim ds As New DataSet
Try
objConn.Open()
Dim sqlcmd As New SqlCommand("select order_date from bookorder where order_date=' " & tbdate.Text & "'", objConn)
sqlcmd.ExecuteNonQuery()
adaptor.SelectCommand = sqlcmd
adaptor.Fill(ds)
If ds.Tables(0).Rows.Count > 0 Then
Label8.Visible = True
Label8.Text = "Enter different date"
End If
adaptor.Dispose()
ds.Clear()
Catch
e.ToString()
Finally
objConn.Close()
End Try
End Sub
End Class
select * from table where CAST(datecolumn as DATE) = textbox.date
Maybe you have to cast your textbox's date in order to match DB's format...
Use DateTime.ParseExact method
I've been trying this for some time now,
So in my MS access database i have a
Table named "reservations" and inside the table are
Name(sid,jen)
Roomtype(single,double)
Arrivaldate(3/20/17, 3/20/17 )
Departuredate(3/21/17, 3/21/17)
And in my visual studio form i have
2 labels = lblsingle , lbldouble
1 button named btnok and
Datetimepicker named Datetimepicker1 (properties format set to "Short")
So here is my code:
Private sub Form1_Load
Dim time as DateTime = DateTime.Now
Dim format As String = "MM/d/yyyy"
Datetimepicker1.Text = time.ToString(format)
Private sub btnok_click
Con.open
Dim cmb As new OleDbCommand("SELECT COUNT (*) FROM [reservations] WHERE [Roomtype] = 'Single' AND [Arrivaldate] = " & Datetimepicker1.Text & " ",Con)
Dim dr As OleDbDataReader = cmb.ExecuteReader
Dim userfound As Boolean = False
While dr.Read
userfound = True
lblsingle.text = (dr(0).ToString())
End While
Con.Close()
End Sub
End Class
.
So what i want to happen is when i choose date 3/20/17 in my datetimepicker1. my lblsingle.text should count to "1" because in my database there is a single with the same date as my datetkmepicker1. But the result is "0"......... i really think there is something that makes my datetimepicker1 and the date in my ms access different,,
Please help.... do i need to change time format somewhere?
First your "Private sub btnok_click" will not handle the button click.
To handle "button click" your implementation should be as shown below (proto):
Private Sub button1_Click(sender As Object, e As System.EventArgs) Handles button1.Click
..
..
..
..
End Sub.
Coming to business logic:
When you want to update/increment your label?
Based on the description in your question, you want to update/increment the label as soon as your "DatTimePicker" value is changed.
But in code you are trying to do it in "Ok" button click.
If you want update the label, when you select a date from "datetimepicker", handle below event (proto):
Private Sub DateTimePicker1_ValueChanged(sender as Object, e as EventArgs) _
Handles DateTimePicker1.ValueChanged
..
..
..
..
End Sub
You must handle dates as datetime and not text:
Dim time as DateTime = DateTime.Today
Dim format As String = "yyyy'/'MM'/'/dd"
Datetimepicker1.Value = time
Private sub btnok_click
Con.open
Dim cmb As new OleDbCommand("SELECT COUNT (*) FROM [reservations] WHERE [Roomtype] = 'Single' AND [Arrivaldate] = #" & time.ToString(format) & "# ",Con)
Do not use text representations of date and time - use DateTime for all purposes except rendering output for your users (or serializing as text output like CSV files).
Handling DateTime values for your control
Use the .Value property to get and set your controls value:
Datetimepicker1.Value = DateTime.Now
Handling DateTime values for your database query
Use a (typed) parameter to pass DateTime values to your database query:
Dim cmb As new OleDbCommand("SELECT COUNT (*) FROM [reservations] WHERE [Roomtype] = 'Single' AND [Arrivaldate] = ?", Con)
cmb.Parameters.Add(Datetimepicker1.Value)
OleDbCommand uses positional parameters - that means you need to match the order of your placeholders when adding parameters:
Dim roomtype As String
roomtype = "Single"
Dim cmb As new OleDbCommand("SELECT COUNT (*) FROM [reservations] WHERE [Roomtype] = ? AND [Arrivaldate] = ?", Con)
cmb.Parameters.Add(roomtype)
cmb.Parameters.Add(Datetimepicker1.Value)
Simplify retrieving scalar results like count(*)
If all you try to get is the count(*), you don't need a OleDbDataReader - let your command ExecuteScalar
lblsingle.Text = cmb.ExecuteScalar()
I am trying to take data from the database to the grid. The condition is SELECT * FROM entries WHERE edate='" & Me.dtpDate.Value.Date & "'" But I am getting the error message Data type mismatch in criteria expression. Please see the code below. Also I have attached a screenshot of the error message.
Private Sub dtpDate_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtpDate.Leave
'GetDayBookOpeningBalance()
If Me.lblHeading1.Text <> "Daybook entry" Then
Using MyConnection As OleDb.OleDbConnection = FrmCommonCodes.GetConnection(),
MyAdapter As New OleDb.OleDbDataAdapter("SELECT * FROM entries WHERE edate='" & Me.dtpDate.Value.Date & "'", MyConnection)
'Format(Me.dtpDate.Value.Date, "dd/MM/yyyy"))
If MyConnection.State = ConnectionState.Closed Then MyConnection.Open()
Using MyDataSet As New DataSet
MyAdapter.Fill(MyDataSet, "entries")
Me.grdDayBook.DataSource = MyDataSet.Tables("entries")
Dim DataSetRowCount As Integer = MyDataSet.Tables("entries").Rows.Count
If DataSetRowCount > 0 Then
SetGridProperty()
Else
ShowBlankGrid()
FrmCommonCodes.MessageDataNotFound()
End If
End Using
End Using
Else
ShowBlankGrid()
End If
End Sub
This is exactly what could happen for not using parameterized queries.
I bet that your column edate is a column of type Date/Time but you concatenate your Me.dtpDate.Value.Date to the remainder of your sql string command.
This forces an automatic conversion from DateTime to String but the conversion is not as your database would like to see.
If you use a parameter there is no conversion and the database engine understand exactly what you are passing.
Dim sqlText = "SELECT * FROM entries WHERE edate=#dt"
MyAdapter As New OleDb.OleDbDataAdapter(sqlText, MyConnection)
MyAdapter.SelectCommand.Parameters.Add("#dt", OleDbType.Date).Value = Me.dtpDate.Value.Date
....
I could use some hints on a problem i am stuck with,
I have a datatable with 3 columns(Username, time, event) that I extract from an excel file
I need to count the number of events and how much time they spend on it per user and present this in datagridviewer control. any idea apprecited
Here is part of my code
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DateTimePicker1.Format = DateTimePickerFormat.Custom
DateTimePicker1.CustomFormat = "yyyyMMdd"
TextBox1.Text = DateTimePicker1.Text
Using cn As New OleDbConnection With {.ConnectionString = String.Format(ConnectionNoHeader, FileName)}
cn.Open()
Dim cmd As OleDbCommand = New OleDbCommand(
<Text>
SELECT
Log_date,
username,
event,
time,
DateDiff('n', Min(time),Max(time)) as Duration
FROM [<%= SheetName %>$]
WHERE Log_Date = <%= TextBox1.Text %> GROUP BY username
</Text>.Value,
cn
)
Dim dt As New DataTable
dt.Load(cmd.ExecuteReader)
dt.AcceptChanges()
bsData.DataSource = dt
DataGridView1.DataSource = bsData
End Using
end sub
I know this is a very old question but I have found a very simple solution which I hope might help someone out there. It is a very easy way to create a pivot table and display it in a DGV. The DGV automatically creates all the necessary columns. Sorry, I don't have any reputation to post an image of the resulting DGV
MyDGV.DataSource = GetPivotTable(MySQLcommand)
Private Function GetPivotTable2(ByVal a_SQLCommand As String) As DataTable
'Pivot table SQL structure
'TRANSFORM SUM(ValueField) AS SumOfValueFIeld
'SELECT RowHeadingField, RowHeadingField, ..., TotalField
'FROM TableName
'WHERE SelectionClause
'GROUP BY FirstRowField, SecondRowField...
'PIVOT ColumnHeadingField
'Example SQL:
'TRANSFORM SUM(Hours]) AS [SUMHours]
'SELECT [Member]
'FROM TimesheetTable
'WHERE ([Date] >= #7/01/2019# AND [Date] < #7/01/2020#)
'GROUP BY [Member]
'PIVOT [Activity]
‘This example creates a row for each Member and totals their hours under
‘each activity
Try
Dim PivotTable As New DataTable
Using Connection = New OleDbConnection(MyConnectionString)
If Connection IsNot Nothing Then
Dim Expression As New OleDbCommand(a_SQLCommand, Connection)
Connection.Open()
Dim da As New OleDbDataAdapter(Expression)
da.Fill(PivotTable)
End If
End Using
Return PivotTable
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function