Select cell in dataGridView by header text - vb.net

I'm looping through rows in a datagridview, and selecting a cell from the 3rd column each time:
Dim customer_name as String
For Each dgvr As DataGridViewRow In myDataGridView.Rows
customer_name= dgvr.Cells(2).Value
'....
next dgvr
However, I'd really like to make it dynamic, in case a new column gets added to the grid, so that I need the 4th column, not the 3rd.
Ideally I'd like to use the column's header text. So something like...
customer_name= dgvr.Cells("Customer").value
Can this be done?

This code works well for selected cells under a specific column name. Maybe you can use it for what you're looking for. The best part is, it auto scrolls to the selected column.
This basically runs from a text box and a button. User can enter a string of text and hit the button, then it will go find the column. If no column exists, it tells you.
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
Dim search As String = tbSearch.Text
Dim Found As Integer = 0
If dgv.Rows.Count > 0 Then
For Each col As DataGridViewColumn In dgv.Columns
Dim colname As String = col.HeaderText
If search = colname Then
'MsgBox(search & " = " & colname)
dgv.Rows.Item(0).Cells(search).Selected = True
Found = 1
End If
Next
If Found = 1 Then
'do nothing
Else
MsgBox("No columns with the name " & search)
End If
Else
MsgBox("No data to analyze... ")
End If
End Sub

This can be done, it is possible to select by header text. You can loop through each row and find the value for the name of a column.
For Each dgvr As DataGridViewRow In myDataGridView.Rows
Dim testString As String
testString = dgvr("Customer").ToString()
This should set the value of the test string to the current cell under the column name.
Hope this helps :)

Related

search text in access database and show msg box with find text

can you help me please? I have a two columns in ms access database and I want search text based on inputbox if find text show me msg box with text from input box and text from next column on the same row. is it possible?
first column name: zak
second column name: cisl
thank you
Private Sub PictureBox12_Click(sender As Object, e As EventArgs) Handles PictureBox12.Click
Dim rngVis As String
Dim VisCell As String
Dim barcode As String = Nothing
barcode = InputBox("")
barcode = InputBox("Naskenujte čárový kód ||||||||||||||||||||||||||||||||||||")
If Len(Trim(barcode)) = 0 Then Exit Sub 'Pressed cancel
Dim table As DataTable = SdfDataSet.Tables("vyhl")
Me.Refresh()
'Vytvoreni dotazu
Dim expression As String
expression = ("[zak] = '" & barcode & "'")
Dim foundRows() As DataRow
'vykonani dotazu
foundRows = table.Select(expression)
MsgBox("")
End Sub

Multiline Textbox to Datagridview

I have a multi-line textbox with this appearance:
A#B
C#
D#E
and I want to populate my datagridview to something like this:
_________
|A|BC|D|E|
I mean, I want to split when there's a "#" , but I don't want multi-line cells in datagridview.
I tried this code:
Dim sup() As String = TextBox1.Text.Split(vbCr, vbLf, vbTab, " "c, "#")
DataGridView1.Rows.Add(sup(0), sup(1), sup(2),sup(3))
but it says it goes outta bounds ... Thanks!
edit:
"Index out of range exception" Error.
If i paste the textbox values to microsoft word they come like this:
If you are sure you will be splitting your textbox with 3 #'s, you could use something like this after creating 3 columns in your datagridview
Dim myStr As String
Dim substring As String
Dim strArray() As String
Dim columnInt as Integer = 0
myStr = Textbox1.Text
strArray = myStr.Split("#")
For i = 0 to strArray.Length - 1
Datagridview.Rows(0).Cells(columnInt).Value = strArray(i)
columnInt += 1
next
As I am not quite sure how you want this data to appear exactly, you may also need to declare the count of your columns should it be larger than 3. Add this code before the first For Statement:
For i = 0 to strArray.Length - 1
DataGridView.Columns.Add("YourText","YourText")
Next
Untested but it should get you in the right spot!
*Edit: Updated after testing
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer4.Tick
If DataGridView1.RowCount = 1 Then DataGridView1.Rows.Clear()
Call dgvstuff()
Timer1.Stop()
End Sub
Sub dgvstuff()
Dim sup2 = TextBox2.Text.Replace("#", "").Replace(">", " "c)
Dim sup() = sup2.Split(" "c, "#", vbCrLf, vbTab)
With DataGridView1
.Rows(0).Cells(0).Value = sup(1).ToString
.Rows(0).Cells(1).Value = sup(7).ToString
.Rows(0).Cells(3).Value = sup(4).ToString
End With
End Sub
I really don't know why but it works like this. Anyone knows a better/cleaner way? Tks

How to compare DataGridView cell data to DataSet cell data

In a VB.NET WinForms project I'm working on in VS2013 I am detecting when the user changes something in a cell on the CellValueChanged event. When a row in the DataGridView is found that is different from the DataSet I highlight the row in pink.
In my code though, I only know how to iterate through all of the rows, rather than just compare the row that fired the CellValueChanged event to the DataSet.
Here's my current code:
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Force ending Edit mode so the last edited value is committed
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dt As DataTable In dsChanged.Tables
For Each row As DataRow In dt.Rows
For i As Integer = 0 To dt.Columns.Count - 1
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
If Not row(i, DataRowVersion.Current).Equals(row(i, DataRowVersion.Original)) Then
Console.WriteLine("Row index: " & dt.Rows.IndexOf(row))
' This works
dgvEmployees.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
Next
Next
End If
End Sub
As you can see, I'm passing the row and column index of the changed cell, so how can I take that and compare it to the specific row and/or cell in the unchanged DataSet?
UPDATE
Nocturnal reminded me that I need to allow for sorting of the DGV, so using row indexes won't work. He offered this as a solution (changed slightly to work with my objects):
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanged.Tables("employees").Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
However, I'm getting an error on the If DirectCast... line saying "Column named "employeeID" cannot be found." I'm not sure if the error is on the DataSet or on the DGV, but there is an employeeID column in the database and DataSet. There is an employeeID as a bound column for the DataGridView, but it is set to Visible = False. That's the only thing I can think of that could possibly cause that error, but if it's a bound column, I would think it could be compared against as in this case.
FINAL WORKING VERSION
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource("employees", e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal dataSetName As String, ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Takes a dataset and the row and column indexes, checks if the row is different from the DataSet and colors the row appropriately
EmployeesBindingSource.EndEdit()
Dim dsChanges As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanges Is Nothing Then
For Each dtrow As DataRow In dsChanges.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanges.Tables("employees").Columns.Count - 1
If dtrow.RowState.ToString = DataRowState.Added.ToString Then
' TODO: Color entire new row
ElseIf dsChanges.Tables(dataSetName).Rows(0).HasVersion(DataRowVersion.Original) Then
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' TODO: Need to change the BackColor back to what it should be based on its original alternating row color
End If
End If
Next
End If
Next
End If
End Sub
My project has four DGVs in it, so this will eventually be expanded to allow for all four DGVs to be checked for changes.
have a look at this approach it is simlar but only iterating the specific Table
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex, sender.DataSource.datamember.ToString)
End Sub
and comparing the ID of the given Table
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer, tablename As String)
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables(tablename).Rows
If DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID = dgvEmployees.Rows(rowIndex).Cells("EmployeeID").Value Then
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
For i As Integer = 0 To dsChanged.Tables(tablename).Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID)
' This works
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
End Sub
and i am only changing the backcolor of the cell that was changed not the entire row....but depends how you would use that information anyways
EDIT:
with
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Original).ToString())
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Current).ToString())
you can see Current and Original Values
123456

System.NullReferenceException on a ForEach of a datagrid

So all is in the question, I have a datagrid view who's parcoured by a foreach in his rows collection like so dataGridView1.Rows and I get and error of null type in the second if of the for each
Sub DataColumnFirstDouble(ByRef dGridView As DataGridView, ByVal iCol As Integer)
Dim bFirstRow As Boolean = False
Dim sTemp As String = ""
For Each RW As DataGridViewRow In dGridView.Rows
If (bFirstRow) Then
If (RW.Cells(iCol).Value.ToString() = sTemp) Then
RW.Cells(iCol).Selected = True
dGridView.CurrentCell.Style.BackColor = Color.LightGreen
dGridView.CurrentCell.Style.ForeColor = Color.White
End If
End If
sTemp = RW.Cells(iCol).Value.ToString()
bFirstRow = True
Next
End Sub
By the way the Datagrid is populated with 1 entry going
LongString, Number, Number
Hello , 8 , 8
The bug occur when I click on a new row also the function is called on the event of row leave
Need some help
By the way what I try to do is to check when the user enter the name in the longstring space who's a primary unique key in a database but It seems I can't find anythings to handle it by vb so I try to parse it every times he leave the rows to check if there's any double
It isn't clear where the error is, you should debug to figure out which variable exactly is null. So I'll assume it's RW.Cells(iCol).Value.
If there's no value in the cell, it might be null. This mean ToString won't work.
If (bFirstRow) Then
If RW.Cells(iCol).Value IsNot Nothing AndAlso RW.Cells(iCol).Value.ToString() = sTemp Then
RW.Cells(iCol).Selected = True
dGridView.CurrentCell.Style.BackColor = Color.LightGreen
dGridView.CurrentCell.Style.ForeColor = Color.White
End If
End If
You could even check if RW.Cells(iCol) exists, maybe it's trying to fetch the data in a cell that doesn't exists in the row.

How to Set DataGridView Row Tag

I am using a double click event on a listview that will add three columns to a datagridview. I'm not sure how to set the "Tag" property on the "selectedText" variable.
Private Sub lwArticles_DoubleClick(sender As Object, e As System.EventArgs) Handles lwArticles.DoubleClick
Dim selectedText = lwArticles.SelectedItems(0).SubItems.Item(0).Text 'Article No
Dim selectedDesc = lwArticles.SelectedItems(0).SubItems.Item(1).Text 'Description
Dim currRowNo As String = ""
Dim alreadyExists = False
For i As Integer = 0 To dgvDetail.Rows.Count - 1
currRowNo = dgvDetail.Rows(i).Cells(0).Value
If currRowNo = selectedText Then
alreadyExists = True
dgvDetail.Rows(i).Cells(2).Value += 1
Exit For
End If
Next
'If the entry doesn't exist, add it
If Not alreadyExists Then
dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
End If
End Sub
After this I loop through the row's tags to see the article numbers. It will be near my dgvDetail.Rows.Add() that I should be setting the Tag property to equal the selectedText ... Any one know how to do this?
Edit:
The datagridview columns being populated are: "Article Number", "Description" and "Quantity". The quantity is set in the loop, basically if I've double clicked on the same thing twice, it will increment the third column (Cell(2)) by one.
The Add "function" for the DataGridView control returns the index of the row in the grid, so you can try using that to reference the row:
Dim rowIndex As Integer
rowIndex = dgvDetail.Rows.Add(New String() {selectedText, selectedDesc, 1})
dgvDetails.Rows(rowIndex).Tag = selectedText