Visual Basic 2017 - DataGridView - vb.net

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!

Related

UPDATE Button not working in VB . and no error is showing [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
datafile = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
connString = provider & datafile
myconnection.ConnectionString = connString
'to update employee status ' not working
myconnection.Open()
Dim str As String
str = "update[HR_Employee_Details]set[Status]='" & cboHREmployeeInfoStatus.Text & "'Where[EmployeeID]='" & txtHREmployeeInfoNewEmployeeID.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, myconnection)
Try
cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox("not updated", MsgBoxStyle.OkOnly, "Update fail")
End Try
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
myconnection.Close()
End Sub
There are some really bad patterns in that code, and as so often happens just updating the code to use better practice will help find the underlying problem. You'll need to read the comments below to see exactly how:
'Isolate and group the DB access in it's own class, module, or class library.
'ALL access to the database in the application should run through here.
Public Module DB
'Move these out of the individual methods, so you don't
'have to repeat them everywhere
Private Readonly Property provider As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
Private Readonly Property datafile As String = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
Private Readonly Property connString As String = provider & datafile
'Each query gets its own public method in this module,
'but everything else should be marked Private
Public Sub UpdateEmployeeStatus(NewStatus As String, EmployeeID As Integer)
'Ole provider for ADO.Net uses ? As parameter placeholders.
'This string could be a CONSTANT!
Dim sql As String = "UPDATE [HR_Employee_Details] SET [Status]= ? WHERE [EmployeeID]= ?"
'The Using block will guarantee your connection is
'closed, even if an exception is thrown.
'The old code could have leaked connection objects
'when there were exceptions.
'Also, ADO.Net works **much** better when you
'create new connection objects for most queries.
Using conn As New OleDbConnection(connString), _
cmd As New OleDbCommand(sql, conn)
'I have to guess at parameter types here.
'You should change this to use exact types &
'lengths from the database.
'ADO.Net will figure out what value goes to
'what parameter based on the order of the
'placeholders in the sql string.
'These parameters are the ONLY correct
'way to include data in an sql command.
'Anything else leaves you open to sql injection.
cmd.Parameters.Add("?", OleDbType.VarWChar, 20).Value = NewStatus
'If this is not an integer, change it to correct type.
'But I wanted to be sure to show two different
'parameter types
cmd.Parameters.Add("?", OleDbType.Integer).Value = EmployeeID
'wait as long as possible to call Open
conn.Open()
cmd.ExecuteNonQuery()
End Using 'No need to call conn.Close() -- the Using block took care of it
End Sub
End Module
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
'Exception handling can still live in the UI
Try
'Again: integer here is just to demonstrate a
'different parameter type.
'If your employee IDs really are strings, it's
'easy to remove this.
Dim EmployeeID As Integer = Integer.Parse(txtHREmployeeInfoNewEmployeeID.Text)
DB.UpdateEmployeeStatus(cboHREmployeeInfoStatus.Text, EmployeeID)
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
Catch ex As Exception
'This is where your real problem was!
'This catch block hid the detail from the exception
'you would need to solve the problem!
'If you don't want to show this to the user, which
'is reasonable, you can at least log it somewhere.
'Once you see the exception message, it will probably
'be much clearer how to fix the issue.
MsgBox($"Error updating the database:{vbCrLf}{Ex.Message}", MsgBoxStyle.OkOnly, "Not Updated")
End Try
End Sub
But so you don't feel like the "good" code needs to be so much longer, here it is again with the comments removed. Especially note how clean the event handler method has become.
Public Module DB
Private Readonly Property provider As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
Private Readonly Property datafile As String = "C:\Users\Asus\Documents\Visual Studio 2008\Projects\WindowsApplication7\WindowsApplication7\Tea.accdb"
Private Readonly Property connString As String = provider & datafile
Public Sub UpdateEmployeeStatus(NewStatus As String, EmployeeID As Integer)
Dim sql As String = "UPDATE [HR_Employee_Details] SET [Status]= ? WHERE [EmployeeID]= ?"
Using conn As New OleDbConnection(connString), _
cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add("?", OleDbType.VarWChar, 20).Value = NewStatus
cmd.Parameters.Add("?", OleDbType.Integer).Value = EmployeeID
conn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
End Module
Private Sub btnHREmployeeInfoUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHREmployeeInfoUpdate.Click
Try
Dim EmployeeID As Integer = Integer.Parse(txtHREmployeeInfoNewEmployeeID.Text)
DB.UpdateEmployeeStatus(cboHREmployeeInfoStatus.Text, EmployeeID)
MsgBox("Updated!", MsgBoxStyle.OkOnly, "Updated")
Catch ex As Exception
MsgBox($"Error updating the database:{vbCrLf}{Ex.Message}", MsgBoxStyle.OkOnly, "Not Updated")
End Try
End Sub

Excel to DataGridView with OleDbConnection using two DataAdapter

1- Create C:\Book1.xlsx file into C disk.
2- Ensure that you have one sheet in the C:\Book1.xlsx file named Sheet1.
3- Fill Sheet1 cells from A1 cell to E20 cell with some data.
4- Close C:\Book1.xlsx file.
5- Put one DataGridView into the Form1 and named it as DataGridView1.
6- Run code in order to see if you are able to get excel data to DataGridView correctly.
As you can see I have used two OleDbDataAdapters in order to get excel data to DataGridView.
I have prefer to use two OleDbDataAdapters because I come across out of memory exception if excel data is so big.
If you examine my code you will see that myDataAdapter1 gets excel data from A1 cell to E10 cell.
and myDataAdapter2 supposed to get excel data from A11 cell to E20 cell.
If you examine my code you will see that I tried to merge two DataTables and bind to DataGridView1.DataSource with no success.
Please correct my codes and show me how to merge two DataTables and bind to DataGridView1.DataSource?
I want to get excel data from A1 cell to E20 cell and put the DataGridView1 by using two DataAdapters and two DataTables.
If I use one data adapter then my app crashes with big data.
So I try to use two data adapters and two data tables.
The grid must first add columns to accomadate the data. Then add the rows in a While loop. I only have 3 columns in the test data from Excel.
Private Sub PrepareGrid()
DataGridView1.Columns.Add("col1", "Column 1")
DataGridView1.Columns.Add("col2", "Column 2")
DataGridView1.Columns.Add("col3", "Column 3")
End Sub
Private Sub FillFromExcel()
Dim FileName As String = "Book1.xlsx" '"C:\Book1.xlsx"
Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & FileName & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=NO;IMEX=1"";")
Using cmd As New OleDbCommand("SELECT * FROM [Sheet1$];", cn)
cn.Open()
Using reader = cmd.ExecuteReader
While reader.Read
DataGridView1.Rows.Add(reader(0), reader(1), reader(2))
End While
End Using
End Using
End Using
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PrepareGrid()
FillFromExcel()
End Sub
DataTable.Merge cannot work without a Primary Key. I fooled around with DataTable.Load(IDataReader) but that must use Merge underneath. So, you can either add a Primary Key to the Excel worksheet (just sort of a row number column) and set the appropriate properties in code or manually loop through the second DataTable adding the records to the grid. (slow)
Here is a slightly different method of filling the grid with all the data. I don't have a large Excel worksheet to test. It might address the memory problems but I am afraid it will use the same methods underneath.
Private Sub FillFromExcel()
Dim FileName As String = "Book1.xlsx" '"C:\Book1.xlsx"
Dim dt As New DataTable
Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & FILENAME & ";" & "Extended Properties=""Excel 12.0 Xml;HDR=NO;IMEX=1"";")
Using cmd As New OleDbCommand("SELECT * FROM [Sheet1$];", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
You can go from an Excel file to a DGV, like this.
Imports System.Data.SqlClient
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\vb.net-informations.xls';Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
MyCommand.TableMappings.Add("Table", "Net-informations.com")
DtSet = New System.Data.DataSet
MyCommand.Fill(DtSet)
DataGridView1.DataSource = DtSet.Tables(0)
MyConnection.Close()
End Sub
End Class

VB.Net Inserting DateTimePicker to MS Access Database

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)

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

Crystal report error message

ive been dealing with a kind of no error message my application is throwing after the setup has been installed on my machine.
The application run fine and generate a report exactly the way i want it. The problem is that after compiling it as set up, it throw this message:
System.Runtime.InteropServices.COMException (0x80000000);
No error.
at
CrystalDesisionsReportAppServer.Controllers.DatabaseControllerClass.ReplaceConnection(Object oldConnection, Object newConnection, Object parameterFields, Object crDBOptionUseDefault)
at
CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDataSourceInternal(Object val, Type type)
at
CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDataSource(DataSet dataSet)
at Presby_Soft.reportFrm.reportFrm_Load(Object sender, EventArgs e)
this is the code im using:
Private Sub reportFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If conn.State = ConnectionState.Closed Then
conn.Open()
End If
Try
Dim rpt As New CrystalReport1()
Dim da As New SQLiteDataAdapter
Dim ds As New presbydbDataSet
'Dim cmd As New SQLiteCommand("SELECT personal_details.fn, training.training_level FROM personal_details INNER JOIN training ON personal_details.Staff_ID ='" + detailsFrm.Label13.Text + "'", conn)
Dim cmd As New SQLiteCommand("SELECT * FROM personal_details WHERE personal_details.staff_ID='" + detailsFrm.Label13.Text + "'", conn)
cmd.ExecuteNonQuery()
da.SelectCommand = cmd
da.Fill(ds, "personal_details")
rpt.Subreports.Item("persoRpt").SetDataSource(ds)
CrystalReportViewer1.ReportSource = rpt
Catch ex As Exception
MsgBox(ex.ToString)
End Try
conn.Close()
End Sub
Please help, I really don't know how to go about this problem. Thanks for answering
Well I managed to get rid of this problem. The issue is that i was adding the business object files directly into the bin folder while the business object is already installed on the computer. I just removed the business object files i added and the application worked fine.