Sorting DataGridView By Decimal - vb.net

I know there is numerous post like this one exists but I can't find the right solution. I need to sort the first column of datagridview in ascending order. but sorting order is wrong. the first column is a primary key and contains decimal values.
Below is my sample code. I have tried to change the data type after populating the column, but it's not working.
Imports System.Data.SQLite
Public Class Form1
Dim conn As SQLiteConnection
Dim da As SQLiteDataAdapter
Dim table As New DataTable
Dim cmdbl As SQLiteCommandBuilder
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Const filename As String = "database.db"
conn = New SQLiteConnection("Data Source=" & filename & ";Version=3;")
conn.Open()
Dim sql As String = "select * from 'item_rate' ORDER BY 'SL NO' ASC"
da = New SQLiteDataAdapter(sql, conn)
da.Fill(table)
DataGridView1.DataSource = table
DataGridView1.Columns(0).CellTemplate.ValueType = GetType(Decimal)
DataGridView1.Sort(DataGridView1.Columns(0), 0)
End Sub

I Have finally found the solution. Instead of changing the column datatype of DGV change the column datatype of DataTable. In order to do this, you need to clone the DataTable and change the column Datatype. You can not change the datatype once your table filled with data. Below is the sample code.
Imports System.Data.SQLite
Public Class Form1
Dim conn As SQLiteConnection
Dim da As SQLiteDataAdapter
Dim table As New DataTable
Dim cmdbl As SQLiteCommandBuilder
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Const filename As String = "database.db"
conn = New SQLiteConnection("Data Source=" & filename & ";Version=3;")
conn.Open()
Dim sql As String = "select * from 'item_rate'"
da = New SQLiteDataAdapter(sql, conn)
da.Fill(table)
'clone the DataTable to change the data type of a column for sorting
Dim dtCloned As DataTable = table.Clone()
dtCloned.Columns(0).DataType = GetType(Single) 'Assign the first column to decimal type AKA Single
For Each row As DataRow In table.Rows
dtCloned.ImportRow(row)
Next
'End Of Clone Table
'Assign cloned table to DGV
DataGridView1.DataSource = dtCloned
'Sort DGV
DataGridView1.Sort(DataGridView1.Columns(0), 0)
End Sub

Related

Adding more rows to a datagridview in vb.net

Private Sub btnAddSub_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddSub.Click
Dim comboboxvalue As String
comboboxvalue = "'" & CBClass.SelectedItem & "'"
Dim sql As String
sql = "Select * From class Where ClassCode=" & comboboxvalue
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=H:\ProjectDatabase.mdb"
Dim MyConn As OleDbConnection
Dim da As OleDbDataAdapter
Dim ds As DataSet
Dim tables As DataTableCollection
Dim source1 As New BindingSource
MyConn = New OleDbConnection
MyConn.ConnectionString = connString
ds = New DataSet
tables = ds.Tables
da = New OleDbDataAdapter(sql, MyConn)
da.Fill(ds, "Class")
Dim view As New DataView(tables(0))
source1.DataSource = view
Form1.dgv.DataSource = view
End Sub
I can currently add one piece of data to the datagrid. When I try to add a second piece of data it replaces the current data stored.
How do I make it so that when I add more data it goes to a new line.
The source code you provided looks a lot like you are just refreshing the data source for the DGV on every btnAddSub click, by assigning to form1.dgv.datasource each time. If you want to simply append new rows to the DGV you will need to manipulate the DGV.Rows collection by adding DataGridViewRow objects to it.

Issue with Comobox on DataGridView

I am using VB.NET to pull some data from an SQL database into a Datagridview.
I then want the user to be able to modify the information and save it back to the database, which I have working fine.
What I need to be able to do now is to restrict the values, but way of a combobox for the field Tarrif.
I have configured a DataSource called Tarrif1 and I am using the below code.
I have a couple of issues/questions.
Firstly the dropdown shows a single value of "System.Data.DataViewManagerListItemTypeDescriptor" not the Tarrif1 values.
Secondly, I now have 2 columns on my datatable called Tarrif, the original database one and the one I have added - How can I get the ComboBox to right back to the appropriate Tarrif database field.
Here is my code:
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class ViewCustomersForm
Dim ds As DataSet = New DataSet()
Dim connStr As String = "server=barry-laptop\SQLEXPRESS; database=BillingReferenceData; integrated security=yes"
Dim sql As String = "SELECT * FROM Customers"
Dim conn As SqlConnection = New SqlConnection(connStr)
Dim comm As SqlCommand = New SqlCommand(Sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)
Private Sub ViewCustomersForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'---open the connection and fill the dataset---
conn.Open()
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
comboBoxCol.DataSource = Tarrifs1
'comboBoxCol.DisplayMember = "Tarrif" // when I add these rows the new Tarrif column is not visible
'comboBoxCol.ValueMember = "Tarrif" // when I add these rows the new Tarrif column is not visible
'---add a combobox column to the DataGridView control---
DataGridView1.Columns.Add(comboBoxCol)
End Sub
Private Sub Button_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter)
sqlCmdBuilder.GetUpdateCommand()
dataadapter.Update(ds.Tables("Customers_table"))
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
End Class
Hope that makes sense. Any help greatly appreciated.
A few things in this code:
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
comboBoxCol.DataSource = Tarrifs1
First, I'm not sure what happens whenever the code attempts to fill a DataSet that already has data in it. In my code, I never assume, so I always reinitialize it each time unless I need it:
ds = new DataSet()
Next, you are setting the DataSource for comboBoxCol as Tarrifs1, but I do not see that defined anywhere. You might want to look into that.
Finally, about the SQL: Dim sql As String = "SELECT * FROM Customers" I don't know what columns are in your Customers table. Is Tarrif an actual column?
I figured half my issue out.
I configured a second data connection to pull the Tarrif drop down from the Tarrifs table and display this as part of the customer data table.
My outstanding issues now, is that I need to write the select Tarrif value back to the Customers table.
All the other updated values save, just not sure how to write the Tarrif dropdown back to my SQL table
Here is my latest code.
Imports System.Data.SqlClient
Imports System.Data.Common
Public Class ViewCustomersForm
Dim ds As DataSet = New DataSet()
Dim connStr As String = "server=barry-laptop\SQLEXPRESS; database=BillingReferenceData; integrated security=yes"
Dim sql As String = "SELECT [Customer ID] ,[Customer Name] ,[Address] ,[City] ,[County] ,[Post Code] FROM [BillingReferenceData].[dbo].[Customers]"
Dim conn As SqlConnection = New SqlConnection(connStr)
Dim comm As SqlCommand = New SqlCommand(Sql, conn)
Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm)
Dim con As New System.Data.SqlClient.SqlConnection("server=barry-laptop\SQLEXPRESS; database=Test; integrated security=yes")
Dim strSQL As String = "SELECT * FROM Tarrifs"
Dim da As New System.Data.SqlClient.SqlDataAdapter(strSQL, con)
Private Sub ViewCustomersForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'---open the connection and fill the dataset---
conn.Open()
dataadapter.Fill(ds, "Customers_table")
conn.Close()
DataGridView1.DataSource = ds
DataGridView1.DataMember = "Customers_table"
'---create a combobox column---
Dim comboBoxCol As New DataGridViewComboBoxColumn
'---set the header---
comboBoxCol.HeaderText = "Tarrifs"
'---data bind it---
da.Fill(ds, "Tarrifs")
comboBoxCol.DataSource = ds.Tables("Tarrifs")
comboBoxCol.DisplayMember = "Tarrif"
comboBoxCol.ValueMember = "Tarrif"
'---add a combobox column to the DataGridView control---
DataGridView1.Columns.Add(comboBoxCol)
End Sub
Private Sub Button_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim sqlCmdBuilder As New SqlCommandBuilder(dataadapter)
sqlCmdBuilder.GetUpdateCommand()
dataadapter.Update(ds.Tables("Customers_table"))
dataadapter.Update(ds.Tables("Tarrifs"))
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
End Class

vb database connection gives no information as to whether connection was successful

I am trying to connect to an access database THROUGH CODE. I capitalized that last bit because I am well aware of the visual method of doing it but can't use that method in this instance. Basically I just want to create a databinding to a combobox on a single column from a table Title that displays the column Year. To clear that up I want to populate cboYearsFillBy with the data from the column YearPublished. The thing I am finding to be the biggest pain is that vb doesn't throw any sort of fuss when the db isn't found so I don't even know if it is finding it. My code is below
Imports System.Data.OleDb
Public Class frmTitle
' Create untyped dataTables
Dim dtYears As New DataTable
' Declare a variable to represent the DataAdapter
Dim daYears As OleDbDataAdapter
' Create BindingSource objects for Employee & Dept tables:
Dim WithEvents bsYears As New BindingSource
Private Sub frmTitle_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim connStr As String = "Provider=Microsoft.ace.OLEDB.12.0;Data Source=D:\VisualStudioProjects\Biblio.accdb"
MessageBox.Show(connStr)
Dim titleSQLStr As String = "SELECT * FROM Title"
daYears = New OleDbDataAdapter(titleSQLStr, connStr)
Dim commandBuilder As New OleDb.OleDbCommandBuilder(daYears)
daYears.Fill(dtYears)
dtYears.PrimaryKey = New DataColumn() {dtYears.Columns("YearPublished")}
bsYears.DataSource = dtYears
cboYearsFillBy.DataSource = bsYears
cboYearsFillBy.DisplayMember = "YearPublished"
cboYearsFillBy.ValueMember = "YearPublished"
End Sub
End Class
I get the following output
Imports System.Data.OleDb
Public Class frmTitle
' Create untyped dataTables
Dim dtYears As New DataTable
' Declare a variable to represent the DataAdapter
Dim daYears As OleDbDataAdapter
' Create BindingSource objects for Employee & Dept tables:
Dim WithEvents bsYears As New BindingSource
Private Sub frmTitle_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim connStr As String = "Provider=Microsoft.ace.OLEDB.12.0;Data Source=D:\VisualStudioProjects\Biblio.accdb; Persist Security Info=True"
MessageBox.Show(connStr)
Dim con As New OleDbConnection
con = New OleDbConnection(connStr)
If con.State = ConnectionState.Closed Then
con.Open()
End If
Dim titleSQLStr As String = "SELECT * FROM Title"
daYears = New OleDbDataAdapter(titleSQLStr, connStr)
daYears.Fill(dtYears)
cboYearsFillBy.DataSource = dtYears
cboYearsFillBy.DisplayMember = "YearPublished"
cboYearsFillBy.ValueMember = "YearPublished"
con.Close()
End Sub
End Class
I simplified your code just try now

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

vb.net load record data in a text field

im fairly new to databases in vb.net and i have just learned how to use datagridview. im gonna show some of my code for the connection and datagridview display
Public Class Form1
Dim con As New OleDb.OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim ds As New DataSet 'holds table data
Dim da As OleDb.OleDbDataAdapter 'connection to database connectionobject
Dim sql As String
Dim inc As Integer
Dim MaxRows As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
dbSource = "Data Source = C:/AddressBook.mdb"
con.ConnectionString = dbProvider & dbSource
'alternative way of connection
'Dim fldr As String
'Environment is the user profile
'fldr = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "/AddressBook.mdb"
'dbSource = "Data Source = " & fldr
con.Open()
MsgBox("Database is now Open")
sql = "select * from tblContacts"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "Addressbook")
con.Close()
MsgBox("Database is now Closed")
MaxRows = ds.Tables("AddressBook").Rows.Count
inc = -1
MsgBox(MaxRows)
TextBox1.Text = inc
DataGridView1.DataSource = ds
DataGridView1.DataMember = "AddressBook"
End Sub
End Class
i want to display in a textfield the first name based on where is the pointer is positioned after i clicked Button1, how do i do this? thank you for the replies!
You need to get that value from the data grid itself, and then show it on the form. There are other ways, but try this (and add null checks!):
Dim row as DataRow = CType(DataGridView1.CurrentRow.DataBoundItem, DataRowView).Row
myTextBox.Text = row["firstName"].ToString();
C#
var row = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
myTextBox.Text = row["firstName"].ToString();
Alternately:
If you use a DataSource, and bind the grid to that first, then fill the DataSource with the data, you can use the .Current property to get the selected row.
Edit:
Mistake in code. It should be "DataBoundItem". Not "DataItem". From memory... Also, you need to cast to string, ctype(...,string) or call .ToString().
If you bind to a list of objects, then you won't need to call the .Row, the DataBoundItem will be the actual object type, eg Customer