A new issue !!
I have a checkbox column in the datagridview and also a column named "partqty" which displays the quantity of materails available.. I would want that when the user checks on the checkbox, the quantities of checked rows should be added and displayed in the textbox..
I tired something like this.. But it displays 0(zero) in the textbox.. Please help..
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
'For Each _rw As DataGridViewRow In dataGridView1.Rows
' If _rw.Cells(0).Value = True Then
Dim totalSum As Integer
For i As Integer = 0 To HemDatabase1DataSet5.Tables(0).Rows.Count - 1
totalSum += HemDatabase1DataSet5.Tables(0).Rows(i).Item("partqty")
Next
textBox5.Text = totalSum.ToString()
' End If
'Next
End Sub
Hey !! This is something i could think upon trying !! however, there is no error during compile time, but there is an error at runtime, which says :
Operator '+' is not defined for type 'DBNull' and type 'Boolean'
Here is the code i tried :
For Each _rw As DataGridViewRow In dataGridView1.Rows
If _rw.Cells(0).Value = True Then
Dim totalSum As Integer
For i As Integer = 0 To dataGridView1.Rows.Count - 1
totalSum += dataGridView1.Rows(i).Cells(5).Value
Next
textBox5.Text = totalSum.ToString()
End If
Next
It gives error on this line :
totalSum += dataGridView1.Rows(i).Cells(5).Value
You first problem is that you are trying to add apples and oranges together.
In the line:
totalSum += dataGridView1.Rows(i).Cells(5).Value
totalSum is an integer while the Value property of a DataGridView cell is of type object.
This is a similar problem to what you see when trying to use the DataTable except there your Item property is givin you a DBNull rather than an object back.
Here is the code that you want (I'm mainly a C# dev so the VB.Net might be lacking elegance but it works).
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim sum As Integer
sum = 0
For Each row As DataGridViewRow In DataGridView1.Rows
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
Next
TextBox1.Text = sum.ToString
End Sub
Some things worth noting about that code:
I use a For Each rather than a for. The two perform basically identically but I find the foreach more readable
I use Integer.TryParse on the cell value before using it. This is safer than just casting the cell value directly.
Rather then using column indexes which is a little fragile I use column names.
With your check on whether or not the checkbox is checked you can do something similar:
Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb)
One final point to note is that if you try to execute this code in the cellclick method of the DataGridView you will run into problems - the checkbox state is not committed until after the cellclick, so the most recently checked cell will not get added to your count. Instead you will want to handle the CellDirtyStateChanged and commit the edits, then doing the sum in the CellValueChanged handler.
To illustrate that try this code:
Private Sub dgv_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim sum As Integer
sum = 0
Dim cb As Boolean
cb = False
If DataGridView1.Columns(e.ColumnIndex).Name <> "IsChecked" Then
Return
End If
For Each row As DataGridViewRow In DataGridView1.Rows
If Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb) Then
If cb Then
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
End If
End If
Next
TextBox1.Text = sum.ToString
End Sub
The sum will always lag one click behind (actually in VB.Net it appears to just nor really work - but I'm more a c# dev so that could be me missing something).
Instead you want:
Sub dataGridView1_CurrentCellDirtyStateChanged( _
ByVal sender As Object, ByVal e As EventArgs) _
Handles DataGridView1.CurrentCellDirtyStateChanged
If DataGridView1.IsCurrentCellDirty Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
' If a check box cell is clicked, this event handler disables
' or enables the button in the same row as the clicked cell.
Public Sub dataGridView1_CellValueChanged(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellValueChanged
If DataGridView1.Columns(e.ColumnIndex).Name = "IsChecked" Then
Dim sum As Integer
sum = 0
Dim cb As Boolean
For Each row As DataGridViewRow In DataGridView1.Rows
If Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb) Then
If cb Then
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
End If
End If
Next
TextBox1.Text = sum.ToString
End If
End Sub
This is the code that worked..
Dim iSselected As Boolean
Dim CurrentCellValue As String
Dim CumulativeSummer As Integer
Dim i As Integer
With Me.dataGridView1
For i = 0 To .RowCount - 1
iSselected = .Rows(i).Cells(0).Value
CurrentCellValue = .Rows(i).Cells(5).Value
If CurrentCellValue = "" Then CurrentCellValue = 0
If iSselected = True Then
CumulativeSummer += Convert.ToInt32(CurrentCellValue)
End If
Next
End With
Me.textBox5.Text = CumulativeSummer
Thank u for your help !! :)
Related
I have an error problem in the text label. Is there another solution?
Thanks
Private Sub CalculateGrandTotal()
Dim tot As Double = 0
'error this below code
Dim cash As Double = Double.Parse(lblDisTotal.Text)
For Each item As DataGridViewRow In grid.Rows
tot += Double.Parse(item.Cells(5).Value.ToString())
Next item
lblGrandTotal.Text = (tot * (1 - cash / 100)).ToString("N2")
End Sub
Private Sub BtnRefresh_Click(sender As Object, e As EventArgs) Handles BtnRefresh.Click
lblDisTotal.Text = ""
End Sub
when the button event is refreshed then lblDisTotal does not become blank but becomes "0" then the problem is solved
Private Sub CalculateGrandTotal()
Dim tot As Double = 0
'error this below code
Dim cash As Double = Double.Parse(lblDisTotal.Text)
For Each item As DataGridViewRow In grid.Rows
tot += Double.Parse(item.Cells(5).Value.ToString())
Next item
lblGrandTotal.Text = (tot * (1 - cash / 100)).ToString("N2")
End Sub
Private Sub BtnRefresh_Click(sender As Object, e As EventArgs) Handles BtnRefresh.Click
lblDisTotal.Text = "0"
End Sub
The appropriate solution would be Double.TryParse to handle someone typing "hello world" into your text box if it is not sanitized.
As a rule, you should avoid .parse whereever possible and opt for try parse unless you can guarantee with absolute certainty that your value CAN be parsed into the type you want. Otherwise, utilize tryParse to prevent exceptions that can be prevented.
Private Sub CalculateGrandTotal()
Dim tot As Double = 0
'error this below code
Dim cash As Double
'tryParse returns a boolean indicating successful parsing. You can check for that, however, if it fails, it assigns 0 to your passed in double
Double.TryParse(lblDisTotal.Text, cash)
For Each item As DataGridViewRow In grid.Rows
dim val as double
Double.TryParse(item.Cells(5).Value, val)
tot += val
Next item
lblGrandTotal.Text = (tot * (1 - cash / 100)).ToString("N2")
End Sub
Private Sub BtnRefresh_Click(sender As Object, e As EventArgs) Handles BtnRefresh.Click
lblDisTotal.Text = ""
End Sub
I have a VB.NET DataGridView that requires user input to fill Null Columns.
I have that functioning.
I want to have the date_time column populate with the current date/time when the other columns are not NULL. The goal being to have an accurate time attached to when the other cells were populated.
I expect that I can use a timer and monitor the cells not to be null and trigger the date/time being added but I am not sure how to code the date/time population to the cell.
Can anyone give me a push in the right direction?
Thanks
This should give you a good start:
Dim dateTimColumnIndex As Integer = 1 '(example number on my part)
Private Sub CellValueChanged(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellValueChanged
If (e.ColumnIndex <> dateTimColumnIndex) Then
For z As Integer = 0 To DataGridView1.ColumnCount -1
If DataGridView1.Item(z, e.RowIndex).Value Is Nothing Then
Return
End If
DataGridView1.Rows(e.RowIndex).Cells(dateTimColumnIndex).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
Next
End if
End Sub
Updated won't do anything until you change value of allDoneLoading to True
Dim allDoneLoading As Boolean = False
Dim dateTimColumnIndex As Integer = 1 '(example number on my part)
Private Sub CellValueChanged(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellValueChanged
If allDoneLoading = True Then
If (e.ColumnIndex <> dateTimColumnIndex) Then
For z As Integer = 0 To DataGridView1.ColumnCount - 1
If DataGridView1.Item(z, e.RowIndex).Value Is Nothing Then
Return
End If
DataGridView1.Rows(e.RowIndex).Cells(dateTimColumnIndex).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
Next
End If
End If
End Sub
I have a datagrid on a form with a checkbox to select all records. Column (0) of my datagrid is a checkbox column, and on the header I put a checkbox to select all records and display the number of records selected. Here is my code:
Private Sub chkSelectRecords_CheckedChanged(sender As Object, e As EventArgs) Handles chkSelectRecords.CheckedChanged
'Procedure runs when the checkSelectRecords is clicked.
'The loop selects all records on the datagrid when checked
'and clears selection when unchecked.
Dim chkRow As Integer = 0
If chkSelectRecords.Checked = True Then
For Each row As DataGridViewRow In grdDeleteRecord.Rows
row.Cells(0).Value = (row.Cells(0).Value IsNot DBNull.Value)
chkRow += 1
lblRowCount.Visible = True
lblRowCount.Text = chkRow.ToString & " Record(s) Selected"
Next
Else
For Each row As DataGridViewRow In grdDeleteRecord.Rows
row.Cells(0).Value = (row.Cells(0).Value Is DBNull.Value)
chkRow += 0
lblRowCount.Text = chkRow.ToString & " Record(s) Selected"
Next
End If
End Sub
I placed another procedure when the user selects one record at a time:
Private Sub grdDeleteRecord_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles grdDeleteRecord.CellContentClick
' Shows how to get count of checked or unchecked checkbox column count along with
' how to get column data back for checked items.
Dim chkRowCount As Integer = 0
grdDeleteRecord.EndEdit()
For Each row As DataGridViewRow In grdDeleteRecord.Rows
If row.Cells(0).Value = True Then
chkRowCount += 1
Else
chkRowCount += 0
lblRowCount.Visible = True
lblRowCount.Text = chkRowCount.ToString & " Record(s) Selected"
End If
Next
End Sub
Both procedures work as needed. The problem is when I select all records my label does not update the number of records that are now selected. I am sure this is happening because they are two separate events, I just don't know how to link the events or write a procedure that accomplishes all three tasks
Here's a function I wrote for you. You must use the CellValueChangedEvent and the CurrentCellDirtyStateChanged events...
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lblRowCount.Text = SetLabel()
End Sub
Private Function SetLabel() As String
Dim strRows As String = String.Empty
Dim intRows As Integer = 0
For i As Integer = 0 To grdDeleteRecord.Rows.Count - 1
If CBool(grdDeleteRecord(0, i).Value) Then
intRows += 1
End If
Next
If intRows > 0 Then
strRows = intRows.ToString & " Record(s) Selected"
lblRowCount.Visible = True
End If
Return strRows
End Function
Private Sub grdDeleteRecord_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles grdDeleteRecord.CellValueChanged
lblRowCount.Text = SetLabel()
End Sub
Private Sub grdDeleteRecord_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles grdDeleteRecord.CurrentCellDirtyStateChanged
If grdDeleteRecord.IsCurrentCellDirty Then
grdDeleteRecord.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
When you check or uncheck these checkboxes it will trigger this event and thus update your label. Then you can use this where ever you need it to be used.
I have a datagridview table that is populated by using a datatable as a datasource. The datagridview has been set to edittable and I can change the values of cells but of course, the changes do not reflect in the original database table since the grid view is not directly bound. Is it possible to have the datagridview in such a way that when I press enter (when editting a cell), the focus shifts to the cell on the right (rather then selecting the row below)? This would need to keep on going until I reach the right most column, in which case the following edit cell would be the first cell in the following row.
Thanks in advance!
Try this:
define a flag flag_edited that will be raised when an edit occurs (CellEndEdit event)
define a function changeSelectionToNextCell that will undo default behavior's selection change (SelectionChanged event)
Here is a sample:
Private flag_edited As Boolean
Private Sub DataGridView1_CellEndEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
flag_edited = True
End Sub
Private Sub DataGridView1_SelectionChanged(sender As Object, e As System.EventArgs) Handles DataGridView1.SelectionChanged
changeSelectionToNextCell()
End Sub
Private Sub changeSelectionToNextCell()
If flag_edited Then
flag_edited = False
If DataGridView1.CurrentCell IsNot Nothing Then
Dim row_index As Integer = DataGridView1.CurrentCell.RowIndex - 1
Dim col_index As Integer = DataGridView1.CurrentCell.ColumnIndex + 1
If col_index = DataGridView1.ColumnCount Then
col_index = 0
row_index += 1
End If
DataGridView1.CurrentCell = DataGridView1.Rows(row_index).Cells(col_index)
End If
End If
End Sub
I’v some query about my code. Im a beginner in VB2005, I js want to add some item n my dgCart(DataGrid) from my txtISBNInfo & txtTitleInfo (Textbox). Upon addin it, the itemx must be limited into 3, and the dgCart(DataGrid) should not contain any doubling or duplication ov items. What should I do?
In my for each it will to determine if it exists and then only after it has determined it doesn't exist, add a new row. By that I mean... Here I show you my code but regrettably it doesn’t work…
Private Sub btnAddToCart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddToCart.Click
Dim IsFound As Boolean = False
Dim Count As Integer = dgCart.Rows.Count
For Each dgvRow As DataGridViewRow In dgCart.Rows
If dgvRow.Cells("clmISBN").Value.ToString = txtISBNInfo.Text Then
IsFound = True
'at this point you can actually exit for because you have the info you need.
End If
Next
If IsFound Then
dgCart.Rows.Add(txtISBNInfo.Text, txtTitleInfo.Text)
Else
MsgBox("Already in list!")
End If
End Sub
I think you pretty much had it but you had the if statement at the end swapped
Private Sub btnAddToCart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddToCart.Click
''//Set a flag saying that we have not found the row yet
Dim IsFound As Boolean = False
''//Loop through each row
For Each dgvRow As DataGridViewRow In dgCart.Rows
''//Compare the cell to our inputed
If dgvRow.Cells("clmISBN").Value.ToString = txtISBNInfo.Text Then
''//Flag the we found the item
IsFound = True
''//No need to loop through the remaining rows, exit the loop
Exit For
End If
Next
''If the item was found in the datagrid
If IsFound Then
MsgBox("Already in list!")
Else ''//Otherwise
''//Add it
dgCart.Rows.Add(txtISBNInfo.Text, txtTitleInfo.Text)
End If
End Sub