new records to add first row of datagrid view in vb.net - vb.net

In my VB.Net application I am filling my data grid view like this:
Dim cmdd1 As New SqlCommand("DashBordFetch1", con.connect)
cmdd1.CommandType = CommandType.StoredProcedure
cmdd1.Parameters.Add("#locid", SqlDbType.Int).Value = locid
da1.SelectCommand = cmdd1 dr = cmdd1.ExecuteReader
While dr.Read
flag = False
carid1 = dr("Car_Id")
For j = 0 To dcnt1 - 2
If carid1 = dgv.Item(0, j).Value Then
flag = True
Exit For
End If
Next
If flag = False Then
If dr("Car_Id") Is DBNull.Value Then
carid1 = "null"
Else
carid1 = dr("Car_Id")
End If
If dr("Plate_Source") Is DBNull.Value Then
platesource1 = "Null"
Else
platesource1 = dr("Plate_Source")
End If
Dim row1 As String() = {carid1, platesource1}
DGVDeliverd.Rows.Add(row1)
End If
End While
..also i am using Timer..every 2 minutes timer will work .some time new records will added to my datagridview..while adding new record that is adding to last row of my datagrid view,,i want to add every time new records to my first row of datagridview. how i can do this?
I am using windows forms

You can use Insert instead of Add to specify the position for the new row. So always insert at position zero:
DGVDeliverd.Rows.Insert(0, row1)
See MSDN here for details (screenshot below).

Use:
Order by your primary id desc
to keep the latest data on top of the grid
update #1
DGVDeliverd.Controls[0].Controls.AddAt(0, row1);

Related

Adding new row to unbound datagridview

I have an unbound datagridview. Because of the various things I am doing with the data in the grid I do not want to bind it. The columns are predefined in the settings (Edit Columns) of the datagridview.
I want to create a new row and then populate the grid row with data. I am trying to use the .Add.Rows method but it is failing with
{"Index was out of range. Must be non-negative and less than the size of the collection." & vbCrLf & "Parameter name: index"}
The following SQL retrieves data:
USE CCAP
declare #ScheduleName as varchar(30) = 'Walk-In Center April Wk 1 2019'
Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1,
Name1,ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5,
Name5, ADP_ID6, Name6, ADP_ID7, Name7
from FormattedSchedules
where ScheduleName = #ScheduleName;
and the rowcount is greater than 0 so it is getting results.
I do not understand what index is out of range or why the collection is 0
Code is below:
Tried .Rows.Add(1) and .Rows.Add() and .Rows.Add("")
Dim FSchedCmd As SqlCommand
Dim FSchedSQL As String
Dim FSchedConn As New SqlConnection()
Dim FSchedadapter As New SqlDataAdapter()
Dim i As Integer = 0
Dim rowIndex As Integer
Dim row As DataGridViewRow
AddedNewRow = 1
Dim dsFSched As New DataSet()
FSchedSQL = "Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1, Name1, ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5, Name5, ADP_ID6, Name6, ADP_ID7, Name7 from FormattedSchedules where ScheduleName = #ScheduleName;"
Try
If GlobalVariables.logProd = 1 Then
GlobalVariables.strConnection = "CCAPProdConnectionString"
Else
GlobalVariables.strConnection = "CCAPTestConnectionString"
End If
FSchedConn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings(GlobalVariables.strConnection).ConnectionString
FSchedConn.Open()
FSchedCmd = New SqlCommand(FSchedSQL, FSchedConn)
FSchedCmd.Parameters.Add("#ScheduleName", SqlDbType.VarChar).Value = cboCreateScheduleName.Text
FSchedadapter.SelectCommand = FSchedCmd
FSchedadapter.Fill(dsFSched)
FSchedadapter.Dispose()
FSchedCmd.Dispose()
FSchedConn.Close()
'dgvCreateSchedule.DataSource = dsFSched.Tables(0)
dgvCreateSchedule.Rows.Clear()
With dgvCreateSchedule
Dim RowNo As Long = 0
'.RowCount = 0
While RowNo <= dsFSched.Tables(0).Rows.Count - 1
.Rows.Add(1)
.Rows(RowNo).Cells(0).Value = dsFSched.Tables(0).Rows(RowNo).Item(0) 'ShiftName
'.Rows(RowNo).Cells(1).Value = dsFSched.Tables(0).Rows(RowNo).Item(1) 'Start Time
.Rows(RowNo).Cells(1).Value = Convert.ToDateTime(dsFSched.Tables(0).Rows(RowNo).Item(1)).TimeOfDay
'.Rows(RowNo).Cells(2).Value = dsFSched.Tables(0).Rows(RowNo).Item(2) 'End Time
.Rows(RowNo).Cells(2).Value = Convert.ToDateTime(dsFSched.Tables(0).Rows(RowNo).Item(2)).TimeOfDay 'End Time
.Rows(RowNo).Cells(3).Value = dsFSched.Tables(0).Rows(RowNo).Item(3) 'Position
.Rows(RowNo).Cells(4).Value = dsFSched.Tables(0).Rows(RowNo).Item(4) 'ADP_ID1
.Rows(RowNo).Cells(5).Value = dsFSched.Tables(0).Rows(RowNo).Item(5) 'Name1
.Rows(RowNo).Cells(6).Value = dsFSched.Tables(0).Rows(RowNo).Item(6) 'ADP_ID2
.Rows(RowNo).Cells(7).Value = dsFSched.Tables(0).Rows(RowNo).Item(7) 'Name2
.Rows(RowNo).Cells(8).Value = dsFSched.Tables(0).Rows(RowNo).Item(8) 'ADP_ID3
.Rows(RowNo).Cells(9).Value = dsFSched.Tables(0).Rows(RowNo).Item(9) 'Name3
.Rows(RowNo).Cells(10).Value = dsFSched.Tables(0).Rows(RowNo).Item(10) 'ADP_ID4
.Rows(RowNo).Cells(11).Value = dsFSched.Tables(0).Rows(RowNo).Item(11) 'Name4
.Rows(RowNo).Cells(12).Value = dsFSched.Tables(0).Rows(RowNo).Item(12) 'ADP_ID5
.Rows(RowNo).Cells(13).Value = dsFSched.Tables(0).Rows(RowNo).Item(13) 'Name5
.Rows(RowNo).Cells(14).Value = dsFSched.Tables(0).Rows(RowNo).Item(14) 'ADP_ID6
.Rows(RowNo).Cells(15).Value = dsFSched.Tables(0).Rows(RowNo).Item(15) 'Name6
.Rows(RowNo).Cells(16).Value = dsFSched.Tables(0).Rows(RowNo).Item(16) 'ADP_ID7
.Rows(RowNo).Cells(17).Value = dsFSched.Tables(0).Rows(RowNo).Item(17) 'Name7
RowNo = RowNo + 1
End While
End With
If dgvCreateSchedule.RowCount > 0 Then
dgvCreateSchedule.Rows(0).Selected = True
dgvCreateSchedule.CurrentCell = dgvCreateSchedule.Rows(0).Cells(0)
'dgvCreateSchedule.FirstDisplayedScrollingRowIndex = dgvCreateSchedule.CurrentRow.Index
End If
Catch ex As Exception
MessageBox.Show("Cannot open FormattedSchedules to load grid")
End Try
AddedNewRow = 0
Error message from line: .Rows.Add(1)
Index was out of range. Must be non-negative and less than the size of the collection." & vbCrLf & "Parameter name: index
This should be the fastest option:
dgvCreateSchedule.Rows.Clear()
For Each xrow As DataRow In TempDataTable.dsFSched.Tables(0).Rows
dgvCreateSchedule.Rows.Add(xrow.ItemArray)
Next
What it does adds all "Cells" along with row.
And when editing cells, I prefer to use
dgvCreateSchedule(y,x).Value = somevalue
'Though it's a little bit strange, as it's column first then row for location hence y then x axis , opposed to usual row then column thats x then y axis
Add it like this, assuming there is the same column count/order
.Rows.Add(dsFSched.Tables(0).Rows(RowNo).ItemArray)
I changed the name of the DGV to DataGridView1 because that is what I happened to have in my test project.
You can use conditional compile statements to chose the correct connection string. Not necessary to keep a Boolean variable somewhere to determine correct string. I know I would forget to change it for the release version.
You did a good job closing and disposing of database objects but if there is an error all that good work will be for naught. A Using...End Using block will accomplish the close, dispose even if there is an error.
Pass the connection string directly to the constructor of the connection and pass the Sql statement and the connection directly to the constructor of the command.
Don't open your connection until the last minute. In the case of a DataAdapter.Fill, the connection is opened and closed for you however, if the adapter finds and open connection it leaves it open. In this case there is no need for an adapter or a DataSet.
I do not see anything wrong with your line .Rows.Add(1). The problem comes on the next line. The index of DataGridView.Rows is an Int32, Integer in vb.net, and you have declared RowNo as Long. Of course you will want to use the code suggested by #CruleD answer.
Private Sub OPCode()
Dim dt As New DataTable
Dim FSchedSQL = "Select ShiftName, ScheduleStart, ScheduleEnd, Position, ADP_ID1, Name1, ADP_ID2, Name2, ADP_ID3, Name3, ADP_ID4, Name4, ADP_ID5, Name5, ADP_ID6, Name6, ADP_ID7, Name7 from FormattedSchedules where ScheduleName = #ScheduleName;"
Try
#If Not DEBUG Then
GlobalVariables.strConnection = "CCAPProdConnectionString"
#Else
GlobalVariables.strConnection = "CCAPTestConnectionString"
#End If
Using FSchedConn As New SqlConnection(ConfigurationManager.ConnectionStrings(GlobalVariables.strConnection).ConnectionString)
Using FSchedCmd As New SqlCommand(FSchedSQL, FSchedConn)
FSchedCmd.Parameters.Add("#ScheduleName", SqlDbType.VarChar).Value = cboCreateScheduleName.Text
FSchedConn.Open()
dt.Load(FSchedCmd.ExecuteReader)
End Using
End Using
DataGridView1.Rows.Clear()
For Each xrow As DataRow In dt.Rows
DataGridView1.Rows.Add(xrow.ItemArray)
Next
If DataGridView1.RowCount > 0 Then
DataGridView1.Rows(0).Selected = True
DataGridView1.CurrentCell = DataGridView1.Rows(0).Cells(0)
End If
Catch ex As Exception
MessageBox.Show("Error loading grid")
End Try
End Sub

Data grid view with combo box , add rows from data table

Search and display data in data grid view
Dim cmd As New OracleCommand("Select JV_CODE,JV_ACC_NAME,DEBIT,CREDIT From VOUCHER_DETAIL where VOUCHERNO =:Vno", sgcnn)
cmd.Parameters.Add("#Vno", OracleDbType.NVarchar2).Value = txtJVNo.Text.ToString.Trim
Dim daVD As New OracleDataAdapter(cmd)
Dim dtVD As New DataTable()
daVD.Fill(dtVD)
dgvAccDetail.AutoGenerateColumns = False
dgvAccDetail.DataSource = dtVD
dgvAccDetail.Rows(0).Cells(0).Value = dtVD.Rows(0).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(0).Cells(1).Value = dtVD.Rows(0).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(0).Cells(2).Value = dtVD.Rows(0).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(0).Cells(3).Value = dtVD.Rows(0).Item("CREDIT").ToString.Trim
Catch ex As Exception
MsgBox(ex.Message)
End Try
There are two rows in dtVD data table but result shows only one I stack with this some can tell what I'm doing wrong ?
The reason for this is that you are only assigning the one row. You have a couple options:
First, this code below here shouldn't really be necessary, of you setup the property binding on the grid. You'll get better performance that way if you use a bind. You don't have your GUI code here, but essentially your DataPropertyName field on the columns should be set.
dgvAccDetail.Rows(0).Cells(0).Value = dtVD.Rows(0).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(0).Cells(1).Value = dtVD.Rows(0).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(0).Cells(2).Value = dtVD.Rows(0).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(0).Cells(3).Value = dtVD.Rows(0).Item("CREDIT").ToString.Trim
If you insist on manually assigning the cell values, you cannot just do row 0 (that's the first row). You need to do all the rows in a loop.
For i as Integer = 0 to dtVD.Rows.Count - 1
dgvAccDetail.Rows(i).Cells(0).Value = dtVD.Rows(i).Item("JV_CODE").ToString.Trim
dgvAccDetail.Rows(i).Cells(1).Value = dtVD.Rows(i).Item("JV_ACC_NAME").ToString.Trim
dgvAccDetail.Rows(i).Cells(2).Value = dtVD.Rows(i).Item("DEBIT").ToString.Trim
dgvAccDetail.Rows(i).Cells(3).Value = dtVD.Rows(i).Item("CREDIT").ToString.Trim
Next

Looping through a specific dataset column to check if it contains a certain value

I load a datagridview and am trying to find a quick way of looping through a certain column, given column name....
This is how my datagridview is loaded....
ad = New SqlDataAdapter(sql, con)
ad.Fill(ds, "Fields")
dgvFields.DataSource = ds.Tables("Fields")
dgvFields.ReadOnly = True
dgvFields.RowHeadersVisible = False
dgvFields.Columns(0).Width = 156
dgvFields.Columns(1).Width = 156
dgvFields.Columns(2).Width = 156
dgvFields.Columns(3).Width = 157
'Now I want to be able to loop through dgvfields.columns(3) or column name "Field1a" and check if dgvfields.rows="ValueA"
something along the lines...
For Each row As DataRow In dgvFields.Columns(5)
if dgvfields.rows.value="ValueA" then
'do something
End if
Next
The issue is the type you are looking at for your row... DataRow is for a DataTable not a DataGridViewRow... I would recommend using the index...
Note: this can be done many way's.
For i As Integer = 0 To dgvFields.Rows.Count - 1
If dgvfields.Rows(i).Cells("THE COLUMN NAME").Value="ValueA" Then
'do something
End if
Next

Editing Datable before binding to listview in vb.net

hi this is my code to get datable from query but i need to check for some values like if there is 0 in any column then replace it with N.A.
Dim op As New cad
Dim dt As DataTable = op.Fetchbooks().Tables(0)
Dim sb As New StringBuilder()
Dim rp As System.Data.DataRow
If dt.Rows.Count > 0 Then
ListView1.DataSource = dt
ListView1.DataBind()
DropDownList1.DataSource = dt
DropDownList1.DataTextField = "Description"
DropDownList1.DataValueField = "Description"
DropDownList1.DataBind()
End if
so is there any way to check some values and edit in datable before binding ???
First, if possible i would modify your sql-query in Fetchbooks instead to replace 0 with N.A.. I assume you are querying the database.
However, if you want to do it in memory:
For Each row As DataRow In dt.Rows
For Each col As DataColumn In dt.Columns
If row.IsNull(col) OrElse row(col).ToString = "0" Then
row(col) = "N.A."
End If
Next
Next
Sure: you can iterate through the table, making whatever value replacements are appropriate (assuming that your replacement values are type-compatible with what came from the query).
Something like:
For Each row as DataRow in dt.Rows
if row("columnname") = "left" then
row("columnname") = "right"
Next
Then bind it to the grid, and you should see your updated values.
Once you have the DataTable object you can manipulate it as you need:
For Each rp In dt.Select("COLUMN_A = '0'")
rp("COLUMN_A") = "N.A."
Next
Note that this assumes that COLUMN_A is defined as a string type, not a numeric.
The challenge will be if you intend on saving this data back to it's source and you don't want the original 0 value to be saved instead of N.A.. You could add dt.AcceptChanges immediately after the above loop so that it will appear as the Fetchbooks query had these values all along.

Adding two column values to listbox in vb.net

I have a table named users which has the following columns in it
User_id,user_name,user_pwd,First_Name,Middle_Name,Last_Name and user_type.
I have dataset named dst and created a table called user in the dataset. Now I want to populate listbox with user_Name, First_Name, Last_name of each and every row in the table user.
I am able to add one column value at a time but not getting how to add multiple column values of each row to listbox
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(row("User_Name"))
Next
Above code works perfectly but I also want to add First_name as well as last_name to the list box at the same time.
Use same approach as you have, but put all values you want in one string.
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
Dim sItemTemp as String
sItemTemp = String.Format("{0},{1},{2}", row("User_Name"), row("First_Name"), row("Last_Name"))
lstUsers.Items.Add(sItemTemp)
Next
String.Format() function will call .ToString() on all parameters.
In this case if row(ColumnName) is NULL value then .ToString() return just empty string
You have 2 choices:
Using the ListBox:
To use the ListBox, set the font to one that is fixed width like courier new (so that the columns line up), and add the items like this:
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(RPAD(row("User_Name"),16) & RPAD(row("First_Name"),16) & RPAD(row("Last_Name"),16))
Next
The RPAD function is defined like this:
Function RPAD(a As Object, LENGTH As Object) As String
Dim X As Object
X = Len(a)
If (X >= LENGTH) Then
RPAD = a : Exit Function
End If
RPAD = a & Space(LENGTH - X)
End Function
Adjust the LENGTH argument as desired in your case. Add one more for at least one space. This solution is less than ideal because you have to hard-code the column widths.
Use a DataGridView control instead of a ListBox. This is really the best option, and if you need, you can even have it behave like a ListBox by setting the option to select the full row and setting CellBorderStyle to SingleHorizontal. Define the columns in the designer, but no need to set the widths - the columns can auto-size, and I set that option in the code below. if you still prefer to set the widths, comment out the AutoSizeColumnsMode line.
The code to set up the grid and add the rows goes like this:
g.Rows.Clear() ' some of the below options are also cleared, so we set them again
g.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.AllCells
g.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal
g.SelectionMode = DataGridViewSelectionMode.FullRowSelect
g.AllowUserToAddRows = False
g.AllowUserToDeleteRows = False
g.AllowUserToOrderColumns = True
For Each row As DataRow In dt.Rows
g.Rows.Add(row("User_Name"), row("First_Name"), row("Last_Name"))
Next
You might solved your problem by now but other users like me might have issue with it.
Above answers given worked for me even but I found a same answer in a simple way according to what I want..
cmd = New SqlCommand("select User_Name, First_Name, Last_Name from User")
Dim dr As SqlDataReader = cmd.ExecuteReader(YourConnectionString)
If dr.HasRows Then
Do While dr.Read
lst.Items.Add(dr.Item(0).ToString & " " & dr.Item(1).ToString & " " & dr.Item(2).ToString)
Loop
End If
This worked for me, maybe wrong way but I found it simple :)
May I suggest you use a ListView control instead of Listbox?
If you make the switch, here's a sample subroutine you could use to fill it up with the data you said you want. Adapt it the way you like; there's much room for improvement but you get the general idea:
Public Sub FillUserListView(lstUsers As ListView, Dst As DataSet)
Dim columnsWanted As List(Of String) = New List(Of String)({"User_Name", "First_Name", "Last_Name"})
Dim dt As DataTable = Dst.Tables("user")
Dim columns As Integer = 0
Dim totalColumns = 0
Dim rows As Integer = dt.Rows.Count
'Set the column titles
For Each column As DataColumn In dt.Columns
If columnsWanted.Contains(column.ColumnName) Then
lstUsers.Columns.Add(column.ColumnName)
columns = columns + 1
End If
totalColumns = totalColumns + 1
Next
Dim rowObjects(columns - 1) As ListViewItem
Dim actualColumn As Integer = 0
'Load up the rows of actual data into the ListView
For row = 0 To rows - 1
For column = 0 To totalColumns - 1
If columnsWanted.Contains(dt.Columns(column).ColumnName) Then
If actualColumn = 0 Then
rowObjects(row) = New ListViewItem()
rowObjects(row).SubItems(actualColumn).Text = dt.Rows(row).Item(actualColumn)
Else
rowObjects(row).SubItems.Add(dt.Rows(row).Item(actualColumn))
End If
lstUsers.Columns.Item(actualColumn).Width = -2 'Set auto-width
actualColumn = actualColumn + 1
End If
Next
lstUsers.Items.Add(rowObjects(row))
Next
lstUsers.View = View.Details 'Causes each item to appear on a separate line arranged in columns
End Sub