I have the code for the next button. The data in the database show up normally.
The problem is when I click next button, the data will be repeated again as --> data1 > data2 > data3 > data1 > data2...
I've to been told that I should count the maximum rows but I didn't know how to do it; I've search for the coding as well, but nothing that I understand came out.
Please help me~~~ (I am not very good with English, sorry)
Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnNext.Click
btnBack.Enabled = True
da.Fill(dt)
If position >= 0 Then
position = position + 1
Me.lblID.Text = dt.Rows(position).Item("RefNo")
Me.txtboxName.Text = dt.Rows(position).Item("Name")
Me.rtxtboxAddress.Text = dt.Rows(position).Item("Address")
Me.txtboxContactNo.Text = dt.Rows(position).Item("ContNo")
Me.txtboxFaxNo.Text = dt.Rows(position).Item("FaxNo")
Me.txtboxBrand.Text = dt.Rows(position).Item("Brand")
Me.txtboxModel.Text = dt.Rows(position).Item("Model")
Me.txtboxSN.Text = dt.Rows(position).Item("SN")
Me.rtxtboxProblems.Text = dt.Rows(position).Item("Problems")
Me.rtxtboxTechRemark.Text = dt.Rows(position).Item("TechRemark")
Me.rtxtboxServChange.Text = dt.Rows(position).Item("ServiceChange")
Me.rtxtboxPartChange.Text = dt.Rows(position).Item("PartsChange")
Me.txtboxTotal.Text = dt.Rows(position).Item("TotalPrice")
End If
End Sub
I don't know if this is also need to be told, but... there is two different class
1) database.vb - sql coding
2) forms.vb - coding for my visual basic form
Please help me!!
THANKS EVERYONE WHO HELO ME WITH THE ANSWERS!! I HAVE FOUND THE SOLUTION OF THE QUESTION AFTER RE-FIGURED THE CODING.
I didn't figure out the position value and the row value is same. My value of position = 0 and dt.Rows.Count = 4, since I have 4 data; so when the position = 0, the row = 1. I get confused about that; I thought both value is starting with 0.
A bit more code... this is bad code... don't rely on it for production since I'm sure there are plenty of corner cases it doesn't handle, but I wanted to give you a picture of how you could handle it and at least a glimpse of stuff you might need to worry about (e.g. 0 rows in the data table). Please work through this and try to understand the code... don't simply copy/paste.
Private Sub btnNext_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnNext.Click
If position >= dt.Rows.Count Then
// No more rows to show after this one, so disable the next button
btnNext.Enabled = False
End If
// Put check for zero in btnBack.Click to make sure it doesn't go below 0
// I'm assuming position starts off at 0, and that you're showing the very
// first row by default
position += 1
// This is to handle a condition like having 0 rows in the data table,
// in which case don't want to do the next part...
If position > dt.Rows.Count Then Exit Sub
// Only necessary once really, but we'll do it each time anyway...
btnBack.Enabled = True
da.Fill(dt)
position += 1
// Update various textboxes and labels...
End Sub
dt.Rows.Count is the number of rows in the Rows collection. Anytime you want to check the whether you've reached the maximum number of rows compare the row count to dt.Rows.Count
da, dt, and position should be declared outside your sub above. The Fill statement should also be executed outside the sub.
In the sub:
If position >= 0 and position < dr.rows.count then
do stuff above
else
Beep ' out of range
end if
Related
Thank you for looking at my problem. ^^
I have a small project with a "Copy to Clipboard" button which doesn't work as intended.
I want to copy all 11 Columns and all 10 Rows but it always adds a 12th empty Column, when I subtract a Column from dgvRandom.ColumnCount than the last Column which is supposed to have content is empty. (Picture to clarify - Green is my intention - Red is the actual state) https://i.stack.imgur.com/zvqpr.png
The code I'm referring to is this:
Private Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
Dim sb As New StringBuilder
For row As Integer = 0 To dgvRandom.RowCount - 1
For col As Integer = 0 To dgvRandom.ColumnCount - 1
sb.Append(dgvRandom(col, row).Value?.ToString)
sb.Append(ControlChars.Tab)
Next
sb.Append(ControlChars.NewLine)
Next
Clipboard.SetDataObject(New DataObject(sb.ToString.Trim))
MsgBox("Copied to Clipboard", MsgBoxStyle.OkOnly)
End Sub
I think it's the final TAB before your line break. To remove it, try changing
sb.Append(ControlChars.Tab)
to
If col<dgvRandom.ColumnCount - 1 then sb.Append(ControlChars.Tab)
or even
If col<dgvRandom.ColumnCount - 1 then
sb.Append(ControlChars.Tab)
else
sb.Append(ControlChars.NewLine)
end if
and then delete the sb.Append(ControlChars.NewLine) after the loop
i am a beginner in vb. i have a datagridview which the data extract from excel file. My data look like this
. I want to create a column chart where x-axis is Department and y-axis is total of status ticket that is open and close.Below is my code which i have stuck and i know i get errors but this is the idea.
i want the result like this
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.Chart1.Series("Open").Points.AddXY("Finance", value)
Me.Chart1.Series("Open").Points.AddXY("ITMS", value)
Me.Chart1.Series("Open").Points.AddXY("RV", value)
Me.Chart1.Series("Open").Points.AddXY("Security", value)
Me.Chart1.Series("Close").Points.AddXY("Finance", value)
Me.Chart1.Series("Close").Points.AddXY("ITMS", value)
Me.Chart1.Series("Close").Points.AddXY("RV", value)
Me.Chart1.Series("Close").Points.AddXY("Security", value)
For Count As Integer = 0 To DataGridView1.Rows.Count - 2
Chart1.Series("Open").Points.AddXY(DataGridView1.Item(1, Count).Value, DataGridView1.Item(1, Count).Value)
Chart1.Series("Close").Points.AddXY(DataGridView1.Item(1, Count).Value, DataGridView1.Item(1, Count).Value)
Next
End Sub
End Class
From what I can decipher from the pictures of the data and the chart… you want the number of “open-close” tickets from “Finance” for the first two data points in the chart. The other points are ITMS, RV and Security “departments.” The problem with the posted code is that the current loop is not “adding” the “open” tickets or “closed” tickets for each department. The code is simply “adding” another point to the chart instead of “adding 1” to the existing point.
Tracing the posted for loop using the picture of the grid data, this will add a total of nine (9) points in the chart, the “SAME” nine points are in both the Open/Close” series. However, since departments like “Finance” have three (3) points with the same value, this will display in the chart as three (3) separate “Finance” “departments” … it is here that you need to “add” 1 to the value of the existing “Finance-open/close” point and not simply add “another” “Finance-open/close” point.
The code will need to loop through the grids rows and accumulate the total number of rows that have “Finance” AND “Open”, “Finance” AND “Close”, “ITMS” AND “Open” … etc. This will give you the charts “y” values for each department-open/close. Given this, one possible solution is to write a method that takes two string parameters (department, status) and returns an integer that contains the numbers of rows that match “both” the department and status. These would become the data points for the chart. In this example, you would only be adding eight (8) data points, One for “Finance” “Open” another for “Finance” “Close” … etc... I hope that makes sense.
Below is a simple loop through the grids rows that accumulates the eight points. The method described above is not necessarily the best approach if the data set is large. The described method would loop through the grid a total of eight (8) times. Once for “Finance” and “Open”, another loop through the grid to get “Finance” “Close” … etc. The code below loops through the grid only “once”, however this approach requires the addition of the 8 variables. Pick your poison… hope this helps.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' 8 variables to hold the totals
Dim FinanceOpenCount = 0
Dim FinanceCloseCount = 0
Dim ITMSOpenCount = 0
Dim ITMSCloseCount = 0
Dim RVOpenCount = 0
Dim RVCloseCount = 0
Dim SecurityOpenCount = 0
Dim SecurityCloseCount = 0
' loop through each row and "ADD" 1 to the proper variables
For Each row As DataGridViewRow In DataGridView1.Rows
Select Case row.Cells("Department").Value
Case "Finance"
If (row.Cells("Status").Value = "Open") Then
FinanceOpenCount += 1
Else
FinanceCloseCount += 1
End If
Case "ITMS"
If (row.Cells("Status").Value = "Open") Then
ITMSOpenCount += 1
Else
ITMSCloseCount += 1
End If
Case "RV"
If (row.Cells("Status").Value = "Open") Then
RVOpenCount += 1
Else
RVCloseCount += 1
End If
Case "Security"
If (row.Cells("Status").Value = "Open") Then
SecurityOpenCount += 1
Else
SecurityCloseCount += 1
End If
End Select
Next
' add the points to the chart
Chart1.Series("Open").Points.Clear()
Chart1.Series("Close").Points.Clear()
Chart1.Series("Open").Points.AddXY("Finance", FinanceOpenCount)
Chart1.Series("Close").Points.AddXY("Finance", FinanceCloseCount)
Chart1.Series("Open").Points.AddXY("ITMS", ITMSOpenCount)
Chart1.Series("Close").Points.AddXY("ITMS", ITMSCloseCount)
Chart1.Series("Open").Points.AddXY("RV", RVOpenCount)
Chart1.Series("Close").Points.AddXY("RV", RVCloseCount)
Chart1.Series("Open").Points.AddXY("Security", SecurityOpenCount)
Chart1.Series("Close").Points.AddXY("Security", SecurityCloseCount)
End Sub
Multiple looping method described above.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Chart2.Series("Open").Points.Clear()
Chart2.Series("Close").Points.Clear()
Chart2.Series("Open").Points.AddXY("Finance", GetDeptStatusCount("Finance", "Open"))
Chart2.Series("Open").Points.AddXY("ITMS", GetDeptStatusCount("ITMS", "Open"))
Chart2.Series("Open").Points.AddXY("RV", GetDeptStatusCount("RV", "Open"))
Chart2.Series("Open").Points.AddXY("Security", GetDeptStatusCount("Security", "Open"))
Chart2.Series("Close").Points.AddXY("Finance", GetDeptStatusCount("Finance", "Close"))
Chart2.Series("Close").Points.AddXY("ITMS", GetDeptStatusCount("ITMS", "Close"))
Chart2.Series("Close").Points.AddXY("RV", GetDeptStatusCount("RV", "Close"))
Chart2.Series("Close").Points.AddXY("Security", GetDeptStatusCount("Security", "Close"))
End Sub
Private Function GetDeptStatusCount(department As String, status As String) As Int32
Dim count = 0
For Each row As DataGridViewRow In DataGridView1.Rows
If (row.Cells("Department").Value = department And row.Cells("Status").Value = status) Then
count += 1
End If
Next
Return count
End Function
I have a strange problem. I have a form with on it 2 unbounded datagridviews and 2 buttons. With the buttons I switch the rows from 1 datagrid to the other.
In the beginning the left datagrid is filled with a number of rows and the right datagrid is empty. So when I click on the button "Add" the selected row from the left datagrid is removed and added to the right datagrid. With the button "Delete" the selected row of the right datagrid is added back to the left datagrid.
When there is only one row in the right datagrid, and I select it to "delete" it, the row is removed from the right datagrid and added to the left without an exception. Now I have a situation where there is only one row in the left datagrid and when I click "Add" to move it to the right datagrid I get an ArgumentOutOfRangeException (index is out of bounds...)
Below is the code which throws the exception
For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
Next
So I store the row index in a variable. The first time I used the RemoveAt function and the exception is thrown. To resolve this I added the If-structure and tried the Remove function. But again the exception is thrown.
I don't understand why the exception is thrown. I use the same code for the "delete" button and there it doesn't happen. Also when I store the RowIndex in a variable the index is known, but not when I try to Remove the row.
Can someone help me with this strange problem?
Since the posted for loop is “broken”, I feel it is unnecessary to question what you are trying to accomplish here. However, given what you described where there are two grids and two buttons (Add/Delete) on a form. When the “Add” button is clicked, it moves the “selected rows” from the “left” grid to the “right” grid, and then deletes the “selected rows” rows from the “left” grid. If the “Delete” button is clicked, then the opposite process happens moving the “selected rows” from the right grid to the left grid, then delete the selected rows from the right grid.
If this is correct, then it appears you are making this more complicated than it has to be. This would be much easier if you used a data source of some form. However, to break the above problem down, it appears that two methods may come in handy for what you want to do. The first one could simply add the selected rows from one given grid to another given grid. The next method would simply delete the selected rows from a given grid. With these two methods implemented, the “add” button would be…
AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)
The delete button would be…
AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)
Before I explain the code below, it should be noted that your current posted code is making a huge programming “no-no” and without question is a problem for you. As Mary and others have pointed out, “changing the value of the counter variable in a loop or (as the code does) changing the collection it is looping through is rarely if ever done.”
Try the code below it may make things easier,
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddColumns(dgvLeft)
AddColumns(dgvRight)
FillGrid(dgvLeft)
End Sub
Private Sub FillGrid(dgv As DataGridView)
For i = 0 To 15
dgv.Rows.Add("C0R" + i.ToString(), "C1R" + i.ToString(), "C2R" + i.ToString())
Next
End Sub
Private Sub AddColumns(dgv As DataGridView)
Dim txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col0"
txtCol.HeaderText = "Col 0"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col1"
txtCol.HeaderText = "Col 1"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col2"
txtCol.HeaderText = "Col 2"
dgv.Columns.Add(txtCol)
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)
End Sub
Private Sub RemoveSelectedRows(dgv As DataGridView)
Dim totalRowsToDelete = dgv.SelectedRows.Count
Dim selectedRow As DataGridViewRow
For i = totalRowsToDelete - 1 To 0 Step -1
selectedRow = dgv.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
dgv.Rows.RemoveAt(dgv.SelectedRows(i).Index)
End If
Next
End Sub
Private Sub AddSelectedRows(sourceDGV As DataGridView, destinationDGV As DataGridView)
Dim selectedRowCount = sourceDGV.Rows.GetRowCount(DataGridViewElementStates.Selected)
If (selectedRowCount > 0) Then
Dim selectedRow As DataGridViewRow
For i = 0 To selectedRowCount - 1
selectedRow = sourceDGV.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
destinationDGV.Rows.Add(selectedRow.Cells(0).Value.ToString(),
selectedRow.Cells(1).Value.ToString(),
selectedRow.Cells(2).Value.ToString())
End If
Next
End If
End Sub
You are changing the value of DgvLeft.SelectedRows.Count in your For loop.
Try...
Dim RowCount As Integer = DgvLeft.SelectedRows.Count
For i As Integer = RowCount - 1 To 0 Step -1
I want to thank Mary for her answer, because that made me think about my code. I looked at the code of the "delete" button, where I use the same for loop, and that code doesn't throw an exception. So there must be a difference between the code of my two buttons.
This is an expanded piece of my code in the "add" button:
For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
'fill the array with the row values
For j As Integer = 0 To DgvLeft.Columns.Count - 1
fields(j) = DgvLeft.SelectedRows(i).Cells(DgvLeft.Columns(j).Name).Value
Next
'delete the row in datagrid Left
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
'add the row in datagrid Right
DgvRight.Rows.Add(fields)
Next
In the code snippet above I attempt to remove a row BEFORE I add the array of values from this row to the other datagrid. When I looked at the code of the "delete" button I attempt to remove the row AFTER I add the array of values to the other datagrid.
So I moved this piece of code below the code of adding the array of values and it worked. Probably the index exception is thrown by the array rather than the datagridview.
My application contains a Datagridview, the user has the possibility to enter values like: Day, Time, how many hours did he work etc. The problem is that my second application calculates with this data. It has to be in a certain format.
Like time should be "09:15", but i noticed that some users are using "09,15" instead. Can you help me guys, I need a code that can check if a Range in Datagridview contains some " blacklisted char" and if yes, replaces it with the right one.
Thanks for all.
Do not save values as a string.
Validate input string straight in the needed type.
Then validated values pass to the second application.
In this case you don't need "blacklisted chars"
Private Sub DataGridView_CellValidating(sender As Object,
e As DataGridViewCellValidatingEventArgs)
If e.RowIndex < 0 Then Exit sub
Dim dgv As DataGridView = DirectCast(sender, DataGridView)
Dim columnIndexWithInteger As Integer = 2
Dim columnIndexWithDate As Integer = 3
Select Case e.ColumnIndex
Case columnIndexWithInteger
Dim temp As Integer
If Integer.TryParse(e.FormattedValue, temp) = False Then
e.Cancel = True
End If
Case columnIndexWithDate
Dim temp As Date
If Date.TryParse(e.FormattedValue, temp) = False Then
e.Cancel = True
End If
End Select
End Sub
In DataGridView, you have one handle that allows you to check the validity of an edited cell : CellValueValidating. It is called before the user change is taken into account (CellValueChanged event).
You can find example and explanation here :
- https://msdn.microsoft.com/en-us/library/ykdxa0bc(v=vs.110).aspx
- https://msdn.microsoft.com/en-us/library/7ehy30d4(v=vs.110).aspx
You can also have a look at CellValueChanged, CellValueValidated and CellEndEdit events.
I created a custom GridView (actually a RadGrid) which does roughly the following.
Initialize GridView formatting
Setup Columns (depending on type of data to be displayed)
Populate the rows
When Instantiating this GridView, and adding it to my page, I want the first column to contain a "rowspan" attribute on the first row of repeated, but similar data. The "rowspan" value should be equal to the number of similar rows following it. In this way I hope to make the final view cleaner.
The logic for this, I figure, should take place while populating the rows. Initially I add rows to a DataTable and then bind it to the GridView as the final step.
Here's the general logic I was attempting, but it didn't work for me. What am I doing wrong?
Dim dt As New DataTable() 'Has three default columns
For Each d In Documents 'MAIN ITEM (First Column Data)
Dim rowspan As Integer
rowspan = 0
For Each f In Files
If rowspan = 0 Then
Me.dt.Rows.Add(New Object() {d.Title, f.Language, f.FileSize})
'THIS DOESN'T WORK!
Me.dt.Columns(0).ExtendedProperties.Item("rowspan") = rowspan.ToString()
Else
Me.dt.Rows.Add(New Object() {Nothing, f.Language, f.FileSize})
End If
rowspan += 1
Next
Next
Also keep in mind that the this is dumped into a DataView which is sorted by the first column, so I would imagine it must actually be sorted first, then somehow count the rows for each "like" first column, then set the "rowspan" value for the first row of that column equal to the number of rows belonging to it.
Does this make sense? Here is an ideal example of what I would like to accomplish in the layout:
Try this.
Protected Sub DemoGrid_PreRender(sender As Object, e As System.EventArgs) Handles DemoGrid.PreRender
MergeRowsWithSameContent(sender)
End Sub
Public Sub MergeRowsWithSameContent(gvw As GridView)
For rowIndex As Integer = gvw.Rows.Count - 2 To 0 Step -1
Dim row As GridViewRow = gvw.Rows(rowIndex)
Dim previousRow As GridViewRow = gvw.Rows(rowIndex + 1)
For i As Integer = 0 To row.Cells.Count - 1
If row.Cells(i).Text = previousRow.Cells(i).Text Then
row.Cells(i).RowSpan = If(previousRow.Cells(i).RowSpan < 2, 2, previousRow.Cells(i).RowSpan + 1)
previousRow.Cells(i).Visible = False
End If
Next
Next
End Sub
P.S: Shameless port of this wonderful code I have been using for years.