VB.Net Inserting DateTimePicker to MS Access Database - vb.net

Good day to everyone here at stackoverflow! I have a simple question that maybe you guys could help me out with. I created a prototype for inserting a DateTimePicker into the MS Access database. I followed this guide:
date time conversion problem when inserting data into sql database and although it helped the person asking the question, it did not help me at all :(
This is the picture and this is my code. This is just a simple prototype that if solved, I will be able to implement it into the actual system I am working on with my classmates.
There is a syntax error apparently. But if I remove just the datetimepicker codes I can insert my last name without any problems and have it show up in MS Access. These are the codes.
Imports System.Data.OleDb
Public Class Form1
Dim conString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Israel De Leon\Documents\dateinsert.accdb;"
Dim con As OleDbConnection = New OleDbConnection(conString)
Dim cmd As OleDbCommand
Dim adapter As OleDbDataAdapter
Dim dt As DataTable = New DataTable()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListView1.View = View.Details
ListView1.FullRowSelect = True
ListView1.Columns.Add("Last Name", 100)
ListView1.Columns.Add("Date", 100)
End Sub
Public Sub add()
Dim SQL As String = "INSERT INTO Table1(LastName, Time) VALUES (#LastName, #Time)"
cmd = New OleDbCommand(SQL, con)
cmd.Parameters.AddWithValue("#LastName", TextBox1.Text)
cmd.Parameters.AddWithValue("#Time", DateTime.Parse(DateTimePicker1.Value))
'OPEN CONNECTION AND INSERT
Try
con.Open()
If cmd.ExecuteNonQuery() > 0 Then
MsgBox("Succesfully Inserted")
End If
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
add()
End Sub
End Class
Please help this mate out. Thank you :D

The problem is the name of the column Time. Time is a reserved word in MS-Access. You need to put square brackets around that name
Dim SQL As String = "INSERT INTO Table1(LastName, [Time]) VALUES (#LastName, #Time)"
I also strongly suggest you to not use AddWithValue, but the more precise Add where you can properly set the datatype of your parameter and avoid the hidden code of AddWithValue that translates your inputs to the expected ones
cmd.Parameters.Add("#LastName", OleDbType.VarWChar, 100).Value = TextBox1.Text
cmd.Parameters.Add("#Time", OleDbType.DateTime).Value =DateTimePicker1.Value
Notice that the Add method allows you to define also the size of your data in case of text. This allows the database engine to optimize your insert query. (Not sure if this happens also with access but surely with Sql Server this is an important optimization)

Better to use monthCalendar control:
textBox1.Text = monthCalendar1.SelectionRange.Start.Date.ToShortDateString()
cmd.Parameters.AddWithValue("#Time", textBox1.Text)

Related

SELECTing data from database in vb and outputting data into label

I have the following code which SELECTs data from a database and outputs a value to a label on the form:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim strConn As String = System.Configuration.ConfigurationManager.ConnectionStrings("yourConnectionString").ToString()
Dim sql As String = "SELECT aid FROM tbl_RAPA WHERE username=#username"
Dim conn As New Data.SqlClient.SqlConnection(strConn)
Dim objDR As Data.SqlClient.SqlDataReader
Dim Cmd As New Data.SqlClient.SqlCommand(sql, conn)
Cmd.Parameters.AddWithValue("#username", User.Identity.Name)
conn.Open()
objDR = Cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
While objDR.Read()
Label1.Text = objDR("aid")
End While
End Sub
However, if the value in the database is empty, the program runs into an error. Is there a way for me to do this so the program just returns an empty value rather than crashing?
The error message i am given is System.InvalidCastException: 'Unable to cast object of type 'System.DBNull' to type 'System.Windows.Forms.Label'.' on the line Label1.Text = objDR("aid")
Database objects generally need to be closed and disposed. Using...End Using blocks will do this for you even if there is an error.
Since you are only expecting one piece of data you can use .ExecuteScalar which provides the first column of the first row of the result set. This method returns an object.
Try to always use the the .Add method with Parameters. See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
Here is another
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
I had to guess at the database type so, check your database for the real value.
Don't update the User Interface until after the connection is closed and diposed. (End Using). I declared aid before the Using block so, it could be used after the block. Check if the object, aid, is not Nothing before adding it to the label's Text.
Imports MySql.Data.MySqlClient
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim aid As Object
Using conn As New MySqlConnection(ConfigurationManager.ConnectionStrings("yourConnectionString").ToString),
cmd As New MySqlCommand("SELECT aid FROM tbl_RAPA WHERE username=#username", conn)
cmd.Parameters.Add("#username", MySqlDbType.VarChar).Value = User.Identity.Name
aid = cmd.ExecuteScalar
conn.Open()
End Using
If Not IsNothing(aid) Then
Label1.Text = aid.ToString
End If
End Sub
I would add this before While objDR.Read() as a precaution in case your query returns no rows:
if objDR.HasRows
...
Then, to handle the null values (this is probably what you mean by empty):
If Not String.IsNullOrEmpty(objDR.Item("aid")) Then
Label1.Text = objDR("aid")
Else
Label1.Text = "Null !"
End if
You could also use ExecuteScalar() if you are only expecting one record. But you would need to handle the situation where no matching record is found.

Visual Basic 2017 - DataGridView

So I am having difficulty with my sub routines. I am creating an app to help with dungeon masters. Part of what my application will do is display several spreadsheets, in separate tabs, containing a list of items and details related to them. I want to reuse several my code instead of writing 20 or so nearly identical sub routines.
Here is my code, I am not sure how to solve my problem.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
loadExcel("C:\Users\secretUserName\source\repos\QUILLandDAGGER\QUILLandDAGGER\bin\Debug\recIntKnowl.xls",dgvRecEntKnowl)
End Sub
Private Sub loadExcel(strFilename As String, dgvView As DataGridView)
Try
Dim MyConnection As OleDb.OleDbConnection
Dim Ds As System.Data.DataSet
Dim MyAdapter As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='strFileName';Extended Properties=Excel 8.0;")
MyAdapter = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
Ds = New System.Data.DataSet
MyAdapter.Fill(Ds)
dgvView.DataSource = Ds.Tables(0)
MyConnection.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Build the method like this:
Private Function LoadExcel(ByVal strFilename As String, Optional ByVal SheetName As String = "Sheet1$") As DataTable
Dim SQL As String = "SELECT * FROM [" & SheetName & "]"
Dim result As New DataTable
Using MyConnection As New OleDb.OleDbConnection(), _
MyCommand As New OleDb.OleDbCommand(SQL, MyConnection)
MyConnection.Open()
Using reader As OleDb.OleDbDataReader = MyCommand.ExecuteReader()
result.Load(reader)
End Using
End Using
Return result
End Function
There are numerous improvements in this new code, both great and small. The most important are adding Using blocks, separating the data access from the UI, and designing functions that accept input in order to return a result.
Call it like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
dgvRecEntKnowl.DataSource = LoadExcel("C:\Users\secretUserName\source\repos\QUILLandDAGGER\QUILLandDAGGER\bin\Debug\recIntKnowl.xls.xls")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
As to whether this will actually fix anything... that depends on the problem you're having, which wasn't included in the posted question.
Sorry for failing to post my problem. I actually didn't know directly where my problem was and I've spent hours trying to find that.
My first problem was passing the string that contains directly to the file. It's poorly pointing to the file, which I'll resolve and have it point to a sub directory at a later point.
My second problem was with a specific line and I resolved that.
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\Users\seidl\source\repos\QUILLandDAGGER\QUILLandDAGGER\bin\Debug\detect.xls';Extended Properties=Excel 8.0;")
This line of code was my original text and it worked.
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='strFileName';Extended Properties=Excel 8.0;")
Was what I tried and it didn't work. I even removed the ' that surrounded the text and it didn't work.
So it finally clicked with me, to try something I used in Java when writing strings of texts and I needed variables in my lines of text. +
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + strFileName + "';Extended Properties=Excel 8.0;")
This ended up working like a charm. I am guessing that OleDbConnection takes in a long string of characters and breaks down the string to read in what is needed. I could be wrong but this is incredibly interesting! It only took a many hours to finally see this.
Joel, I will investigate what you replied with and try and clean up my code. Thank you!

Add column to SQL table and populate to datagridview

I have a windows form application with databound datagridview. I want to add column at run time (if user wants to add more column to it). So on button click I wanted to add column. I have added following code to event it adds column in server explorer view under tables column's list but does not show in table definition neither in data source window (in column list under table) nor in datagridview.
Imports System.Configuration
Imports System.Data.SqlClient
Public Class Form3
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'Small_databaseDataSet.newtable' table. You can move, or remove it, as needed.
Me.NewtableTableAdapter.Fill(Me.Small_databaseDataSet.newtable)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddColumn()
End Sub
Private Sub AddColumn()
Dim connString As String = "Data Source=(localDb)\ProjectsV13;Initial Catalog=small database;Integrated Security=True"
Dim dt As New DataTable
Using conn As New SqlConnection(connString)
Dim str As String = "ALTER TABLE newtable ADD " & TextBoxX1.Text & " INT null;"
Using comm As New SqlCommand(str, conn)
conn.Open()
comm.ExecuteNonQuery()
End Using
End Using
Validate()
DataGridViewX1.Columns.Clear()
NewtableTableAdapter.Update(Small_databaseDataSet.newtable)
NewtableTableAdapter.Fill(Small_databaseDataSet.newtable)
DataGridViewX1.DataSource = NewtableBindingSource
End Sub
End Class
Change this line of code:
' Add the keyword NULL and brackets around the column name
Dim comm As New SqlCommand("ALTER TABLE testTable ADD [col1] INT NULL", conn)
If I wanted to have the new column to show up automatically, I would re-query the database, retrieving the data on that table and just set the datagridview datasource to the resultset like:
'I assume the datagridview name is DataGridView1
DataGridView1.Columns.Clear()
DataGridView1.DataSource = USTDatabaseDataSet
DataGridView1.DataMember = "testTable"
DataGridView1.DataBind()
A DataReader is used to retrieve data. Since there is no data retrieved nothing is loaded into your DataTable except maybe a return value of success or failure. The Using statements ensure that your objects are closed and disposed properly even if there is an error.
Private Sub AddColumn()
Dim connString As String = ConfigurationManager.ConnectionStrings("USTDatabaseConnectionString").ConnectionString
Dim dt As New DataTable
Using conn As New SqlConnection(connString)
Using comm As New SqlCommand("ALTER TABLE testTable ADD col1 INT;", conn)
conn.Open()
comm.ExecuteNonQuery()
End Using
Using com2 As New SqlCommand("Select * From testTable;", conn)
Using reader As SqlDataReader = com2.ExecuteReader
dt.Load(reader)
conn.Close()
End Using
End Using
End Using
DataGridView1.DataSource = dt
End Sub

How do I transfer data from Text Boxes in a form to an Access Table

I'm currently trying to write code for a form that has text boxes for a user to input the required data into which then with the use of button the data in the text boxes will be sent to an access table.
If you need any more information to help solve the problem I'm willing to provide it if you ask (I would upload pictures/screenshots but I need "10 reputation" apparently.
You can do this
Imports System.Data.OleDb
Public Class Form1
Dim AccessConection As OleDbConnection
Private Sub btSave_Click(sender As Object, e As EventArgs) Handles btSave.Click
Dim cmd As New OleDbCommand
Dim mySql As String
mySql = "INSERT INTO Customs (CustomName,Address) VALUES(#Name,#Address)"
Try
cmd.Parameters.AddWithValue("#Name", txName.Text)
cmd.Parameters.AddWithValue("#Address", txAddress.Text)
cmd.Connection = AccessConection
cmd.CommandType = CommandType.Text
cmd.CommandText = mySql
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Whatever you want to say..." & vbCrLf & ex.Message)
End Try
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim myDataBasePath As String = "C:\Users\user\Source\Workspaces\......\SOF003\Data.accdb" 'Here you put the full name of the database file (including path)
'The next line is for Access 2003 .mdb files
'Dim CadenaConection As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}", myDataBasePath)
Dim CadenaConection As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0; Data Source={0}", myDataBasePath)
AccessConection = New OleDbConnection(CadenaConection)
AccessConection.open()
End Sub
End Class
btSave is the command button.
Customs is the table's name.
CustomName and Address are two fields.
txName and txAddress are two TextBox Control.
Obviously you should be careful with the data types (here I use only strings), validation, etc, etc... But, this is a starting point. If you search, you'll find another ways, more elaborated.

How can I have 2 gridviews in one form with same dataset, but other population?

Here you see my code of a form with 2 gridviews. Both have the same dataset, bindingsource. The dataset which is made out of a datasource, has 2 different sql queries.
filld() and fillauswahl() filld shows in the gridview a "select distinct" query.
When the user hits the button1, the selected item from that gridview is saved in "verzeichnis1" this var gets pasted to fillauswahl() which is
select* from mytable where columnx = verzeichnis1
The problem I have is that both gridviews get filled during formload with filld() and by clicking the button with fillverzeichnis() i dont know how to seperate that!? i guess it´s very easy. Cheers and thanks
Public Class Importverzeichnis
Public verzeichnis1 As String
Private Sub Importverzeichnis_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Me.SKM2TableAdapter.Filld(Me.SLXADRIUMDEVDataSet.SKM2)
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each cell As DataGridViewCell In DataGridView1.SelectedCells
verzeichnis1 = cell.Value
Next
Me.SKM2TableAdapter.Fillauswahl(Me.SLXADRIUMDEVDataSet.SKM2, verzeichnis1)
End Sub
End Class
Edit: I created a new connection a new datset and new dataadapter and now it works:
Dim connectionString As String = My.Settings.SLXADRIUMDEVConnectionString
Dim sql As String = "SELECT * FROM SKM2 where
Benutzerdefiniert_10 ='" & verzeichnis1 & "' "
Dim connection As New SqlConnection(connectionString)
Dim dataadapter As New SqlDataAdapter(sql, connection)
Dim ds As New DataSet()
connection.Open()
dataadapter.Fill(ds, "verzeichnis")
connection.Close()
datagridview2.DataSource = ds
datagridview2.DataMember = "verzeichnis"
but I would be more happy if can use my first dataset and my first adapter. If anyobdy knows how I can do this, I would be happy for the answer
To me the best way would be to just pull down the data as a your normal select statement and then filter the data in your code-behind. By populating a dataset with the same data twice your just making the traffic from the database slower. However, if you wish to keep your current dataset, I would assume that there are two tables in it, one for each select. If that is the case then change:
datagridview2.DataSource = ds
to:
datagridview2.DataSource = ds.Tables(1) 'assumes the second table is used for this datasource