How to call the datatable fill code without double in vb.net - vb.net

How to call the datatable fill code without double in vb.net?.
in the code below you might see I wrote back the fill datatable code if there is a solution without me writing it back in "GenerateReport()". Please Recommend.
Thanks
Private WithEvents dt As New DataTable
Public Sub fillDataGridView1()
dt = New DataTable
Dim query As String = "SELECT NOD,ITM,CIA,DPR,QTY FROM RSD WHERE QTY > 0 AND PNM=#PNM"
Using con As OleDbConnection = New OleDbConnection(GetConnectionString)
Using cmd As OleDbCommand = New OleDbCommand(query, con)
cmd.Parameters.AddWithValue("#PNM", ComboBox1.SelectedValue)
Using da As New OleDbDataAdapter(cmd)
da.Fill(dt)
da.Dispose()
Dim totalColumn As New DataColumn()
totalColumn.DataType = System.Type.GetType("System.Double")
totalColumn.ColumnName = "Total"
totalColumn.Expression = "[CIA]*[QTY]*(1-[DPR]/100)"
dt.Columns.Add(totalColumn)
Me.grid.DataSource = dt
Me.grid.Refresh()
End Using
End Using
End Using
End Sub
Private Sub GenerateReport()
KtReport1.Clear()
'the code below actually already exists but I reuse it
dt = New DataTable
Dim query As String = "SELECT NOD,ITM,CIA,DPR,QTY FROM RSD WHERE QTY > 0 AND PNM=#PNM"
Using con As OleDbConnection = New OleDbConnection(GetConnectionString)
Using cmd As OleDbCommand = New OleDbCommand(query, con)
cmd.Parameters.AddWithValue("#PNM", ComboBox1.SelectedValue)
Using da As New OleDbDataAdapter(cmd)
da.Fill(dt)
Dim dtCloned As DataTable = dt.Clone()
dtCloned.Columns("CIA").DataType = GetType(String)
For Each row As DataRow In dt.Rows
dtCloned.ImportRow(row)
Next row
KtReport1.AddDataTable(dtCloned)

The issue is that you are essentially duplicating code despite the fact that you have a variable setup to hold the filled DataTable at the Form level.
What I would suggest doing is creating a function that returns the filled DataTable, then at the top of your two existing methods do a null check against the Form level variable.
Take a look at this example:
Private _dt As DataTable
Private Function GetAndFillDataTable() As DataTable
Dim dt As New DataTable()
Dim query As String = "SELECT NOD,ITM,CIA,DPR,QTY FROM RSD WHERE QTY > 0 AND PNM=#PNM"
Using con As OleDbConnection = New OleDbConnection(GetConnectionString)
Using cmd As OleDbCommand = New OleDbCommand(query, con)
cmd.Parameters.AddWithValue("#PNM", ComboBox1.SelectedValue)
Using da As New OleDbDataAdapter(cmd)
da.Fill(dt)
da.Dispose()
Dim totalColumn As New DataColumn()
totalColumn.DataType = System.Type.GetType("System.Double")
totalColumn.ColumnName = "Total"
totalColumn.Expression = "[CIA]*[QTY]*(1-[DPR]/100)"
dt.Columns.Add(totalColumn)
Return dt
End Using
End Using
End Using
End Function
Private Sub FillDataGridView1()
If (_dt Is Nothing) Then
_dt = GetAndFillDataTable()
End If
grid.DataSource = _dt
grid.Refresh()
End Sub
Private Sub GenerateReport()
If (_dt Is Nothing) Then
_dt = GetAndFillDataTable()
End If
Dim dtCloned As DataTable = _dt.Clone()
dtCloned.Columns("CIA").DataType = GetType(String)
For Each row In _dt.Rows
dtCloned.ImportRow(row)
Next row
KtReport1.AddDataTable(dtCloned)
End Sub

Related

Data not showing up in DataGridView after a search query

Hello i am trying to search for data from a table using a funcion, however when i Input the number of the customerID it doesnt show up in the data gridview but the data is still passed to my textboxes. Could anyone help me in explaining what I did wrong?
Private Function SearchData(Fname As String, ID As Int32) As DataTable
Dim dt As New DataTable
Dim newds As New DataSet
Dim ssql As String = "SELECT * FROM customers WHERE fname LIKE #Fname OR CustomerID =#ID"
Using con As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(ssql, con)
con.Open()
cmd.Parameters.Add("#Fname", DbType.String).Value = Fname
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
dt.Load(cmd.ExecuteReader)
Dim da As New SQLiteDataAdapter(cmd)
da.Fill(newds, "customers")
dt = newds.Tables(0)
If dt.Rows.Count > 0 Then
ToTextbox(dt)
End If
dgvCustomerInfo.DataSource = dt
con.Close()
End Using
Return dt
End Function
Private Sub IbtnSearch_Click(sender As Object, e As EventArgs) Handles ibtnSearch.Click
If txtSearchName.Text <> "" Then
SearchData(txtSearchName.Text, "0")
Dim dt = GetSearchResults(txtSearchName.Text)
dgvCustomerInfo.DataSource = dt
ElseIf txtSearchID.Text <> "" Then
SearchData("0", txtSearchID.Text)
Dim dt = GetSearchResults(txtSearchID.Text)
dgvCustomerInfo.DataSource = dt
End If
End Sub
Try to think about what each line of code is doing. See in line comments
Private Function SearchData(Fname As String, ID As Int32) As DataTable
Dim dt As New DataTable
'Delete this line - there is no need for a Dataset
Dim newds As New DataSet
Dim ssql As String = "SELECT * FROM customers WHERE fname LIKE #Fname OR CustomerID =#ID"
Using con As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(ssql, con)
con.Open() 'Move this line - don't open the connection until directly before the .Execute...
'The Like operator would expect a pattern to match
'The interpolated string with the percent signs add wildcard characters
cmd.Parameters.Add("#Fname", DbType.String).Value = $"%{Fname}%"
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
dt.Load(cmd.ExecuteReader)
'Delete - We don't need a DataAdapter
Dim da As New SQLiteDataAdapter(cmd)
'Delete - We already have a filled DataTable
da.Fill(newds, "customers")
'Delete - same as above
dt = newds.Tables(0)
'Delete - Have no idea what this does. You are already going to display your data in a grid
If dt.Rows.Count > 0 Then
ToTextbox(dt)
End If
'Delete - You will set the DataSource in the User Interface code
dgvCustomerInfo.DataSource = dt
'Delete - End Using closes the connection and disposes the connection and command.
con.Close()
End Using
Return dt
End Function
The corrected code will look like this.
Private Function SearchData(Fname As String, ID As Int32) As DataTable
Dim dt As New DataTable
Dim ssql As String = "SELECT * FROM customers WHERE fname LIKE #Fname OR CustomerID =#ID"
Using con As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(ssql, con)
con.Open()
cmd.Parameters.Add("#Fname", DbType.String).Value = $"%{Fname}%"
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
In the user interface code I have added in line comments.
Private Sub IbtnSearch_Click(sender As Object, e As EventArgs) Handles ibtnSearch.Click
'Declare the DataTable outside the If block
'We do not need a New DataTable because SearchData is returning a DataTable
Dim dt As DataTable
If txtSearchName.Text <> "" Then
'Call only one function to return the DataTable
'SearchData is expecting 2 parameters, a String and an Integer
'Putting 0 in quotes makes it a String
dt = SearchData(txtSearchName.Text, 0)
'I removed the DataSource, Don't repeat yourself
'Assign it once after the If
ElseIf txtSearchID.Text <> "" Then
'The second argument must be an Integer, therefore the CInt()
dt = SearchData("", CInt(txtSearchID.Text))
Else
'Needed to add an Else to assign a value to dt if all else fails
dt = Nothing
End If
dgvCustomerInfo.DataSource = dt
End Sub

i have change the background color of row in datagridview if already expired the medicine?

i have change the background color of row in datagridview if already expired the medicine?
con.Open()
Dim query As String
query = "Select product_code,drug_name,quantity,expiration_date from medicine where expiration_date"
command = New MySqlCommand(query, con)
readers = command.ExecuteReader
Dim count As Integer
count = 0
While readers.Read
count = count + 1
End While
con.Close()
If count = 0 Then
MsgBox("no expiration")
Else
Dim SQL As String = ""
Dim da As MySqlDataAdapter = Nothing
Dim dt As New DataTable
SQL = "Select product_code,drug_name,quantity,expiration_date from medicine where expiration_date"
command = New MySqlCommand(SQL, con)
End If
Ok fist of all you need to load de grid with the database data in this way:
con.Open()
Dim query As String
Dim da As new MySqlDataAdapter
Dim dt As New DataTable
query = "Select product_code,drug_name,quantity,expiration_date from medicine where expiration_date is not null"
command = New MySqlCommand(query, con)
da.SelectCommand = cm
da.Fill(dt)
dgv1.datasource = dt
Then you have to set the color in the cellformating event:
Private Sub dgv1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles dgv1.CellFormatting
If dgv1.Rows(e.RowIndex).Cells("expiration_date").Value < now Then
dgv1.Rows(e.RowIndex).cells("expiration_date").Style.BackColor = Color.Red
End If
I do not understand what you are trying to do or how you are going to load the grid. any way to change the color of a column all you have to do is:
dgv1.Columns("columnsName").DefaultCellStyle.BackColor = Color.Red

How to add dynamic Data in to the datagridviewcombobox column?

I am Developing VB.net application.
In that application I take DataGirdView to display data.
I took DataSource property of the datagridview to display 3 columns' data directly from database.
After those columns I add another DataGridViewComboBoxColumn. Then I a want to add dynamic the data into that ComboBoxColumn.
how to do this?
Private Function CreatComboBoxWithEnum() As DataGridViewComboBoxColumn
Dim combo As New DataGridViewComboBoxColumn()
Sqlconn = New SqlConnection
Sqlconn.ConnectionString = "server=.\SQLEXPRESS_2005;Initial Catalog=MachineShopScheduling ;Integrated Security=SSPI;"
Dim adpter As New SqlDataAdapter
Dim ds As New DataTable
Try
Sqlconn.Open()
Dim Query As String
For Each dr As DataGridViewRow In DataGridView1.Rows
Dim val As String = dr.Cells("SrDataGridViewTextBoxColumn").Value.ToString
Query = "select OperationNo from RoutingCalculation where Sr ='" & val & "' "
COMMAND = New SqlCommand(Query, Sqlconn)
adpter.SelectCommand = COMMAND
adpter.Fill(ds)
combo.DataSource = ds
combo.DataPropertyName = "OperationNo"
combo.Name = "OperationNo"
OperationNo.ValueMember = "OperationNo"
OperationNo.DisplayMember = "OperationNo"
Next
Sqlconn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Return combo
End Function
Private Sub load_operationNo()
Sqlconn = New SqlConnection
Sqlconn.ConnectionString = "server=.\SQLEXPRESS_2005;Initial Catalog=MachineShopScheduling ;Integrated Security=SSPI;"
Try
op.Name = "OperationNo"
DataGridView1.Columns.Add(op)
Sqlconn.Open()
Dim Query As String
Dim i As Integer = 0
For Each dr As DataGridViewRow In DataGridView1.Rows
Dim OPno As New DataGridViewComboBoxCell
With OPno
Dim adpter As New SqlDataAdapter
Dim dt As New DataTable
Dim val As String = dr.Cells("SrDataGridViewTextBoxColumn").Value.ToString
Query = "select OperationNo from RoutingCalculation where Sr = " & val & " order by sr"
Using cmd As New SqlCommand(Query, Sqlconn)
adpter.SelectCommand = cmd
adpter.Fill(dt)
End Using
.DataSource = dt
.ValueMember = "OperationNo"
.DisplayMember = "OperationNo"
DataGridView1.Rows(i).Cells("OperationNo") = OPno
i = i + 1
End With
Next
Sqlconn.Close()
Catch ex As Exception
'MessageBox.Show(ex.Message)
End Try
End Sub
This is the code to add dynamically add the data into DatagridViewComboboxColumn

get single value from sql-query into a textbox

The result of my sql-query is a single value i want display that in a lable but dont know how. I have a solution creating a dataset put the result of the query into that dataset and get it by row(0),column(0) but i guess there is a smarter way doing it.
Private myquery As String
Sub New(ByVal query As String)
myquery = query
End Sub
Public Sub query_Send()
Dim myconn As New SqlConnection("Data Source=DB;Integrated Security=TRUE")
Dim mycmd As SqlCommand = New SqlCommand(Me.myQuery, myconn)
Dim myTable As New DataTable
Dim previousConnectionState As ConnectionState = myconn.State
Try
If myconn.State = ConnectionState.Closed Then
myconn.Open()
Dim myDA As New SqlDataAdapter(mycmd)
myDA.Fill(myTable)
tb.text = **...**
End If
If previousConnectionState = ConnectionState.Closed Then
myconn.Close()
End If
End Try
End Sub
You can use SqlCommand.ExecuteScalar Method
Dim querystr as String = "select value from MyTable where ID=5"
Dim mycmd As New SqlCommand(querystr, connection)
dim value as Object = mycmd.ExecuteScalar()
The value you can put to your textbox. ExecuteScalar returns first value of first row of the resultset (equivalent of row(0).column(0) ) When no record is returned the value is nothing.
Try something more along the lines of:
Using myconn As New SqlConnection("Data Source=DB;Integrated Security=TRUE")
Dim myDA As New SqlDataAdapter()
myDA.SelectCommand = New SqlCommand(myQuery, myconn)
myDA.Fill(myTable)
Return myTable
End Using
Or you can just get ahold of the first item in the first row with
myTable.Rows(0).ItemArray(0).ToString()

How to refresh datagridview without refresh button?

How can I automatically refresh and view the new current datagridview after add or delete?
what code should I put after "msgbox" to view the current data?
Private Sub add()
Dim conn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim sSQL As String = String.Empty
Try
conn = New OleDbConnection(Get_Constring)
conn.Open()
cmd.Connection = conn
cmd.CommandType = CommandType.Text
sSQL = "INSERT INTO course ( code, description)"
sSQL = sSQL & " VALUES (#cod, #des)"
cmd.CommandText = sSQL
cmd.Parameters.Add("#cod", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txtcode.Text)) > 0, Me.txtcode.Text, DBNull.Value)
cmd.Parameters.Add("#des", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txtdescription.Text)) > 0, Me.txtdescription.Text, DBNull.Value)
cmd.ExecuteNonQuery()
MsgBox("Data has been save.")
conn.Close()
Catch ex As Exception
MessageBox.Show("Already exist")
End Try
End Sub
You should bind your DataGridView to an appropriate DataSource, e.g. a DataTable.
Then, instead of inserting the data manually in the database, you could use a SqlDataAdapter and the DataTable your DataGridView is bound to.
Here's a simple example:
Dim cons = New SqlConnectionStringBuilder() With
{
.DataSource = "your_server",
.InitialCatalog = "your_db",
.UserID = "your_user",
.Password = "your_password"
}.ConnectionString
Dim con = New SqlConnection(cons)
con.Open()
' create a SqlDataAdapter and provide the SELECT command '
Dim adapter = New SqlDataAdapter()
Dim cb = New SqlCommandBuilder(adapter)
adapter.SelectCommand = New SqlCommand("SELECT code, description FROM course", con)
' the INSERT command can be generated '
adapter.InsertCommand = cb.GetInsertCommand()
' fill a new DataTable with data from database '
Dim dt = New DataTable()
adapter.Fill(dt)
' create a Form with DGV and Insert-Button '
Dim f = New Form()
Dim dgv = New DataGridView() With
{
.DataSource = dt,
.Dock = DockStyle.Fill
}
Dim addButton = New Button() With
{
.Text = "Add new",
.Dock = DockStyle.Bottom
}
Dim i = 0
AddHandler addButton.Click, Function(s, o)
' we insert the new data directly into the DataTable '
dt.Rows.Add(New Object() {"Some","Text"})
' and let the SqlDataAdapter handle the insert '
adapter.Update(dt)
End Function
f.Controls.Add(addButton)
f.Controls.Add(dgv)
f.ShowDialog()
Since the new data is written directly into the DataTable, the DataGridView is updated immediately.
Of course this is even easier when you use TableAdapters.