VB.NET-A way to insert rows into datagrid or datatable - vb.net

Hi once again am stuck in middle where i need some pointer.... I need a way fill the datagrid in a for loop...
Dim rs As SqlCommand
Dim dt As New DataTable
For Each line As String In RichTextBox1.Lines
query = "myquery '" & RichTextBox1.Lines(i).ToString & "'"
rs = New SqlCommand(query, Module1.dtsrv_conn)
dt.load(rs.Executereader)
If i < 1 Then
DataGridView1.DataSource = dt
Else
datagridview1.rows.Add(rs.ExecuteReader)
End If
i = i + 1
Next
many lines of text will be entered in RichTextBox and each line need to be compared with values in database and the resulted table need to be shown in datagrid... I tried adding the newly queried row to datagrid directly but it throws exception so i tried to add new row to datatable and load the datagrid later but i cant find a way....

If I understand your question which isn't very clear, the user is entering values that you want to query against rows in your database and if they exist, display some corresponding data or message.
It sounds like what you want to do is bind your datagrid to a datasource, in my example an in-memory datatable, then intercept the data binding via DataGridView1.CellFormatting to compare/modify your data accordingly.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sqlConnection As SqlConnection
Dim sqlConnectionString As String = "YourConnectionString"
Dim sqlDataAdapter As SqlDataAdapter
Dim dataTable As New DataTable
Dim sqlCommand As SqlCommand
Dim sqlString As String
Try
sqlString = "SELECT * FROM YourTable" 'if user input values are filters, loop through and append them in WHERE clause
sqlConnection = New SqlConnection(sqlConnectionString)
sqlCommand = New SqlCommand(sqlString, sqlConnection)
sqlConnection.Open()
sqlDataAdapter = New SqlDataAdapter(sqlCommand)
sqlDataAdapter.Fill(dataTable)
sqlConnection.Close()
DataGridView1.DataSource = dataTable
Catch ex As Exception
'Handle error
End Try
End Sub
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
If Me.DataGridView1.Columns(e.ColumnIndex).Name = "YourColumnNameToCompare" Then
If e.Value IsNot Nothing Then
'do your comparison to user input text here and if necassary change the value like so..
For Each line In RichTextBox1.Lines
If line = e.Value Then
e.Value = "Value modified"
Exit For
End If
Next
e.FormattingApplied = True
End If
End If
End Sub

Related

count of rows in MS access database in vb.net

Does anyone know what is wrong?
I am trying to count number of rows in MS access Database.
Here is code which I tried:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim conn As New OleDbConnection
conn.ConnectionString = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\Test Database\Database.accdb")
conn.Open()
Dim strsql As String
strsql = "Select count(*) from TABLA" '" select Panel from PANELS where ID"
Dim cmd As New OleDbCommand(strsql, conn)
Dim myreader As OleDbDataReader
myreader = cmd.ExecuteReader
myreader.Read()
PanelsInDatabase = myreader.Item(strsql)
Label1.Text = PanelsInDatabase
conn.Close()
For i As Integer = 0 To PanelsInDatabase - 1
CreatePanels()
CreateDeleteButton(_PanelName)
CreateLabels(_PanelName)
CreateLabel2(_PanelName)
Next
End Sub
if I start code, I get an error:
System.IndexOutOFRangeException
I have separated you user interface code from your database code. Of course, I don't know what CreatePanels is doing or where _PanelName is coming from. In your UI code you call the GetTABLACount function which returns as Integer.
In the database code use Using...End Using blocks for the connection and command so they are properly disposed even if there is an error.
Since you are only retrieving a single piece of data, you can use .ExecuteScalar which returns the first column of the first row of the result set As Object. Use CInt to get the Integer.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim count = GetTABLACount()
Label1.Text = count.ToString
For i As Integer = 0 To count - 1
CreatePanels()
CreateDeleteButton(_PanelName)
CreateLabels(_PanelName)
CreateLabel2(_PanelName)
Next
End Sub
Private Function GetTABLACount() As Integer
Dim dbCount As Integer
Using conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\Test Database\Database.accdb"),
cmd As New OleDbCommand("Select count(*) from TABLA", conn)
conn.Open()
dbCount = CInt(cmd.ExecuteScalar)
End Using
Return dbCount
End Function
Use ExecuteScalar when you are selecting a single value
Dim connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\Test Database\Database.accdb"
Dim sql = "select count(*) from tabla"
Using cmd As New OleDbCommand(sql, New OleDbConnection(connStr))
cmd.Connection.Open()
Dim ct = CInt(cmd.ExecuteScalar())
End Using

How to feed results of SQL statement into a GridView, not the SQL statement itself?

This has got to be close, but it's been a long day and I'm tired now so I can;t really see what the problem is. Basically, I have a table in SQL Server with 2 columns; one has the names of reports and the other has some SQL Scripts that I want to pass into a GridView, based on what a user selects from a ListBox. Here is my code.
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim sqlConn As New SqlClient.SqlConnection("Data Source=EXCEL-PC\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True")
sqlConn.Open()
Dim cmd As New SqlClient.SqlCommand("Select ReportName From [Table_1] order by ReportName", sqlConn)
Dim dsColumns As New DataSet
Dim daAdapter As New SqlClient.SqlDataAdapter(cmd)
daAdapter.Fill(dsColumns)
If dsColumns.Tables(0).Rows.Count > 0 Then
ListBox1.Items.Clear()
For i As Integer = 0 To dsColumns.Tables(0).Rows.Count - 1
ListBox1.Items.Add(dsColumns.Tables(0).Rows(i)(0).ToString())
Next
End If
Catch ex As Exception
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connetionString As String
Dim SqlStr As String
Dim connection As SqlConnection
Dim adapter As SqlDataAdapter
Dim ds As New DataSet
Dim myItem As String
connetionString = "Data Source=EXCEL-PC\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True"
connection = New SqlConnection(connetionString)
'Dim iIndex As Integer = ListBox1.SelectedIndex
myItem = ListBox1.SelectedItem
SqlStr = "select SqlScript from [Table_1] Where ReportName = '" & myItem & "'"
Try
connection.Open()
adapter = New SqlDataAdapter(SqlStr, connection)
adapter.Fill(ds)
connection.Close()
DataGridView1.DataSource = ds.Tables(0)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class
I guess the problem is passing the SQL to the GridView. When I select the first Item, I see this in my GridView.
SELECT [OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
,[RequiredDate]
,[ShippedDate]
,[ShipVia]
,[Freight]
,[ShipName]
,[ShipAddress]
,[ShipCity]
,[ShipRegion]
,[ShipPostalCode]
,[ShipCountry]
FROM [Test].[dbo].[Orders]
That's pretty close, but I want to get that SQL fed into the GridView, and get the results of the SQL displayed in the GridView, not eh SQL statement itself.
This is what I see now.
I want to see something more like this.
Finally, I am curious to know of the GridView can be made dynamic, so if I stretch out the window the GridView shows more columns. Now, if I stretch out the form window, the GridView stays static.
You need to actually run the retrieved Sql statement:
sqlstr = "select SqlScript from [Table_1] Where ReportName = '" & myItem & "'"
Try
connection.Open()
Dim cmd As New SqlCommand(sqlstr, connection)
Dim sqlstr_report As String = CStr(cmd.ExecuteScalar())
cmd.Dispose()
adapter = New SqlDataAdapter(sqlstr_report, connection)
adapter.Fill(ds)
connection.Close()
DataGridView1.DataSource = ds.Tables(0)
Use the .Anchor property of the DataGridView to make it resize with the form

VB.net/MS Access Monthly Donations System Assistance

I'm doing a project for my Database Management subject. I cannot figure out how to add an amount to a previously added amount. For now, I'm only able to update the amount. Here's the code. I'm sorry if I cannot explain it well.
I have 2 forms. My first form allows me to enter a last name and retrieve the data to my list view.
My second form lets me retrieve the data I entered in my first form and it will show up on a separate list view with a "Last Name | Amount" tab.
I have two textboxes. One for last name set to readonly to disable editing, and another for the amount I want to enter.
After entering an amount, let's say 20, it will update on the listview and my database as 20.
The problem is that when I enter a new amount for the same last name, let's say 30, the 30 will replace the 20 but it should be 50 because 20+30 = 50.
I understand the logic and I have tried adding another textbox for addition but I simply do not know the codes for it.
Imports System.Data.OleDb
Public Class Form2
Dim conString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Israel De Leon\Documents\testing.accdb;"
Dim con As OleDbConnection = New OleDbConnection(conString) 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database2.accdb
Dim cmd As OleDbCommand
Dim adapter As OleDbDataAdapter
Dim dt As DataTable = New DataTable()
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'SET LISTVIEW PROPERTIES
ListView1.View = View.Details
ListView1.FullRowSelect = True
'Construct Columns
ListView1.Columns.Add("Last Name", 100)
ListView1.Columns.Add("Amount", 100)
End Sub
Private Sub UpdateLV(lname As String)
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName='" + TextBox1.Text + "',Amount='" + TextBox2.Text + "' WHERE LastName='" + lname + "'"
cmd = New OleDbCommand(sql, con)
'OPEN CON, EXECUTE, UPDATE, CLOSE
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.UpdateCommand = con.CreateCommand()
adapter.UpdateCommand.CommandText = sql
If (adapter.UpdateCommand.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Retrieve()
ListView1.Items.Clear()
'SQL STM
Dim sql As String = "SELECT * FROM Table1 "
cmd = New OleDbCommand(sql, con)
'OPEN CON, RETRIEVE, FILL LISTVIEW
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.Fill(dt)
'LOOP THROUGH DT
For Each row In dt.Rows
Populate(row(0), row(1)) 'Index of database row
Next
'CLEAR DATATABLE
dt.Rows.Clear()
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Populate(lname As String, aamount As String)
'ROW ARRAY
Dim row As String() = New String() {lname, aamount}
Dim item As ListViewItem = New ListViewItem(row)
'ADD TO ROWS COLLECTION
ListView1.Items.Add(item)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Retrieve()
End Sub
Private Sub ListView1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListView1.MouseClick
Dim llname As String = ListView1.SelectedItems(0).SubItems(0).Text
Dim amounts As String = ListView1.SelectedItems(0).SubItems(1).Text
TextBox1.Text = llname
TextBox2.Text = amounts
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim amounts As String = ListView1.SelectedItems(0).SubItems(0).Text
UpdateLV(amounts)
End Sub
Private Sub ClearBox()
TextBox1.Text = ""
TextBox2.Text = ""
End Sub
End Class
Mathematical operation should not be done using strings. This is a real basic principle that many VB.NET programmers don't think enough thanks to the forgiveness allowed by Option Strict Off in the VB.NET project settings.
If you are just starting a new project in VB.NET don't use this setting but switch it ASAP to On. This will give you an halt when you try to use strings as they were numbers and force you to do the appropriate conversion and checking on the values provided.
So your code that updates the amount rewritten
Private Sub UpdateLV(lname As String)
' Get the amount as a number (decimal for currency is the best)
Dim addAmt As Decimal
if Not decimal.TryParse(textbox2.Text, addAmt) Then
MessageBox.Show("Insert a valid amount please")
return
End If
' Sanity check
if addAmt <= 0 Then
MessageBox.Show("Amount should be > 0")
return
End If
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName=#name
,Amount=Amount+#amt
WHERE LastName=#oldname"
cmd = New OleDbCommand(sql, con)
Try
con.Open()
' Using an adapter here is wrong. You use directly the command
cmd.Parameters.Add("#name", OleDbType.VarWChar).Value = textBox1.Text
cmd.Parameters.Add("#amt", OleDbType.Decimal).Value = addAmt
cmd.Parameters.Add("#oldname", OleDbType.VarWChar).Value = lName
If (cmd.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Something else is not clear in your code. What is the purpose of changing also the LastName here? Finally do not keep a global connection object. Instead create it when you need it and destroy it afterward with Using statement. It will be better for your memory footprint and for your database

vb.net : Input array is longer than the number of columns in this table

i have follow code in my vb.net project
the connection to the sql db is fine & ok , only when i try to fill the listbox i get a error
Public Class Form1
Private myTable As New DataTable()
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GetSerialPortNames()
FillListBox()
'------------
myTable.Columns.Add("naam", GetType(String))
myTable.Columns.Add("waarde", GetType(Integer)) '<<<< change the type of this column to what you actually need instead of integer.
ListBox1.DisplayMember = "naam"
ListBox1.ValueMember = "waarde"
ListBox1.DataSource = myTable
End Sub
and
Private Sub FillListBox()
Dim naam As String
Dim stringConn As String
Dim stringCmd As String
Dim myConn As MySqlConnection
Dim myCmd As MySqlCommand
'Frame your query here.
stringCmd = "SELECT id,naam,voornaam FROM deelnemers WHERE finger = FALSE ORDER BY naam "
'Frame your connection string here.
stringConn = "********************************************"
'Get your connection here.
myConn = New MySqlConnection(stringConn)
'Get a command by using your connection and query.
myCmd = New MySqlCommand(stringCmd, myConn)
'Open the connection.
myConn.Open()
'create a reader to store the datum which will be returned from the DB
Dim myReader As MySqlDataReader
'Execute your query using .ExecuteReader()
myReader = myCmd.ExecuteReader()
'Reset your List box here.
ListBox2.Items.Clear()
While (myReader.Read())
'Add the items from db one by one into the list box.
naam = myReader.GetString(1) & " " & myReader.GetString(2)
'ListBox2.Items.Add((naam))
myTable.Rows.Add(naam, myReader.GetString(0))
End While
'Close the reader and the connection.
myReader.Close()
myConn.Close()
End Sub
i get error on follow line
myTable.Rows.Add(naam, myReader.GetString(0))
with follow description : Input array is longer than the number of columns in this table.
someone who see ??
I suspect that your myTable datatable does not have any columns...
Try changing:
While (myReader.Read())
'Add the items from db one by one into the list box.
naam = myReader.GetString(1) & " " & myReader.GetString(2)
'ListBox2.Items.Add((naam))
myTable.Rows.Add(naam, myReader.GetString(0))
End While
to this:
Dim row As DataRow
While (myReader.Read())
'Add the items from db one by one into the list box.
row = myTable.NewRow()
row("naam") = myReader.GetString(1) & " " & myReader.GetString(2)
row("waarde") = myReader.GetString(0)
myTable.Rows.Add(row)
End While
you should still get an error, but at least this way you'll know what columns are missing...
update
Also, change this:
FillListBox()
'------------
myTable.Columns.Add("naam", GetType(String))
myTable.Columns.Add("waarde", GetType(Integer)) '<<<< change the type of this column to what you actually need instead of integer.
to this:
'------------
myTable.Columns.Add("naam", GetType(String))
myTable.Columns.Add("waarde", GetType(Integer)) '<<<< change the type of this column to what you actually need instead of integer.
FillListBox()

Showing all fields in listbox from database, vb.net

I'm trying to make a list box to show all the fields of a particular table in an Access database. I have a few tables, and the idea would be to have each table loaded by a different button (and the items in the box cleared). One trick is that tables aren't all the same size. How do I get all the fields to show up for each table. What I have now is only showing one field:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source='C:\dummy_data.accdb';"
Dim conn As New OleDbConnection(connString)
Dim sql As String = "SELECT * FROM Customers"
Dim cmd As New OleDbCommand(sql, conn)
conn.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader()
ClientList.Items.Clear()
While reader.Read()
ClientList.Items.Add(reader(0).ToString())
End While
reader.Close()
conn.Close()
End Sub
If you are not averse to using a DataGridView instead of a ListView, you could do it this way:
Dim connString As String = "Provider=Microsoft.Jet.OLEDB.4.0;data source='PathToMyDatabase';"
Dim sql As String = "SELECT * FROM Tメイン;"
Dim dt As DataTable
With New OleDbDataAdapter(sql, connString)
Dim ds As New DataSet()
.Fill(ds)
dt = ds.Tables(0)
End With
Me.DataGridView1.DataSource = dt
I do not have 'ACE.OLEDB' on my computer, so had to use the JET provider instead, but it should work the same way.
I should add that you can use this method to retrieve the data from the DB, but there is no easy way as far as I understand to bind a DataTable to a ListView (see this MSDN question for example) and you would have to loop through the columns in your DataTable first and add the column headers to your ListView and then loop through the rows and add the data.
UPDATE:
To answer your questiona s to how to export data from the DataGridView I remembered that I wrote code to do that a little while back.
Private Function ExportToExcelFile(ByVal FileName As String) As Boolean
With New Excel.Application
With .Workbooks.Add()
For Each sheet As Worksheet In .Worksheets
If sheet.Index > 1 Then
Call sheet.Delete()
End If
Next
With CType(.Worksheets(1), Worksheet).Range("A1")
For Each column As DataGridViewColumn In Me.dgvData.Columns
.Offset(0, column.Index).Value = column.HeaderText
For Each row As DataGridViewRow In Me.dgvData.Rows
.Offset(row.Index + 1, column.Index).Value = row.Cells(column.Index).Value
Next
Next
End With
Call .SaveAs(FileName)
End With
Call .Quit()
End With
End Function
I hope this will help to get you started.
Using a Listview control, the following code should do the trick. For simplicity I defined only 4 customer fields - you will need to define them according to your table field defintions:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ClientList.View = View.Details
ClientList.FullRowSelect = True
ClientList.Columns.Add("ID", 120)
ClientList.Columns.Add("Name", 120)
ClientList.Columns.Add("Address", 140)
ClientList.Columns.Add("Email", 100)
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=C:\dummy_data.accdb;"
ClientList.Items.Clear()
Using conn As New Data.OleDb.OleDbConnection(connString)
conn.Open()
Dim sql As String = "SELECT * FROM Customers"
Using cmd As New Data.OleDb.OleDbCommand(sql, conn)
Dim lvi As ListViewItem
Using oRDR As Data.OleDb.OleDbDataReader = cmd.ExecuteReader
While oRDR.Read()
lvi = ClientList.Items.Add(oRDR.GetValue(0).ToString)
For i = 1 To oRDR.FieldCount - 1
lvi.SubItems.Add(oRDR.GetValue(i).ToString)
Next
End While
End Using
End Using
conn.Close()
End Using
End Sub