Datagridview in vb.net [duplicate] - vb.net

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
DataGridView - Validating for Cell
hi...i have a requirement. i dont know how to get the data from the datagrid after the user entered data in textboxcolumn. i also want to validate the entered text in datagrid cell.

This may answer your question:
Suppose there are:
2 textboxes named "txt_X_Values" (gets the values for column "x") and "txt_Y_Values" (that gets the user input for column Y);
a button named "btnAdd_2_Table" (click to add data from textboxes to table);
a datagridview control named "dgv_RawData"; and
(of course) a form that will contain the controls/components mentioned above..
With the following codes, when the button is clicked, the button will store the data input from the textboxes to their respective arrays. In here, i have declared an array named "Column_X" that stores values from txt_X_Values.text and Column_Y for txt_Y_Values.text.
After the values are stored, i may now put/display them in the datagridview cells (codes are shown below..with the comment " ' add columns/rows to datagridview"). With such process, you can add filters/validators or whatever you would call it. You may declare a new sub or function for that.
Here are the codes:
Private Sub btnAdd_2_Table_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd_2_Table.Click
If Blank_Input(txt_X_Values.Text, txt_Y_Values.Text) Then
MessageBox.Show("You cannot have a blank data. Please provide numeric values to both columns.", _
"ERROR ON INPUT", MessageBoxButtons.OK, MessageBoxIcon.Error)
If txt_X_Values.Text = "" Or txt_X_Values.Text = " " Then
txt_X_Values.Focus()
Else
txt_Y_Values.Focus()
End If
Else
Data_InputProc()
Display_Table_Proc()
' add columns to datagridview
If rowCounter - 1 = 0 Then
dgv_RawData.Columns.Add("Column_X", x_Title)
dgv_RawData.Columns.Add("Column_Y", y_Title)
End If
' add rows to datagridview
dgv_RawData.Rows.Add(x_Column(rowCounter - 1), y_Column(rowCounter - 1))
' enable reset
btnReset.Enabled = True
' reset dot counters
dotCountX = 0
dotCountY = 0
End If
btnSave_Data.Enabled = True
End Sub
Here are the codes for the functions that I have made:
*Note that I am only filtering/validating numeric values with these codes.
(function to store data from textbox to arrays)
Public Sub Data_InputProc()
' resize array
ReDim Preserve x_Column(total_Rows), y_Column(total_Rows)
' engine
x_Column(rowCounter) = CDbl(txt_X_Values.Text)
y_Column(rowCounter) = CDbl(txt_Y_Values.Text)
'' next row
rowCounter += 1
total_Rows = rowCounter
' ready value textbox for another input from user
txt_X_Values.Clear()
txt_Y_Values.Clear()
txt_X_Values.Focus()
End Sub
(function/sub to validate numeric values...actually this code only allows the use of 1 dot per numeric entry)
' keypress handler
Public Sub NumericOnly(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles _
txt_X_Values.KeyPress, txt_Y_Values.KeyPress
' do not allow non-numeric characters but allow backspace and dot
If Not e.KeyChar Like "[0-9.]" And Asc(e.KeyChar) <> 8 Then
e.KeyChar = Nothing
ToolTip_Universal.Show("Only NUMERIC values are valid.", grpDataEntry, 300, 100, 1500)
' do not allow multiple dots
ElseIf sender Is txt_X_Values And e.KeyChar Like "." Then
dotCountX += 1
If dotCountX > 1 And e.KeyChar Like "." Then _
e.KeyChar = Nothing
ToolTip_Universal.Show("Only ONE DOT is allowed.", txt_X_Values, 130, 20, 1500)
ElseIf sender Is txt_Y_Values And e.KeyChar Like "." Then
dotCountY += 1
If dotCountY > 1 And e.KeyChar Like "." Then _
e.KeyChar = Nothing
ToolTip_Universal.Show("Only ONE DOT is allowed.", txt_X_Values, 130, 20, 1500)
End If
End Sub

I hope this one helps you out with your problem:
I built a simple program that lets the user put values to the datagridview control. After that, a button is pressed to get the values from that table and store it to a 2D array. The array may then be used to manipulate data as you wish.
Code:
' declare array for storage of all values
Dim array_of_all_values(,) As Object
' number of columns and rows from the datagridview control
Dim Num_of_Columns, Num_of_Rows As Integer
' this block of code asks the user to how many columns does he want to add to the DGV
Private Sub btnNo_of_Columns_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNo_of_Columns.Click
Num_of_Columns = txtCol_Num.Text
For columnCount = 1 To Num_of_Columns
dgv_Test.Columns.Add("Column_" & columnCount, InputBox("What is the header of Column " & columnCount & "?" & vbCrLf, "Column Header", "no header"))
Next
btnNo_of_Columns.Enabled = False
txtCol_Num.Clear()
dgv_Test.Focus()
End Sub
Private Sub btnGetSpecific_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetSpecific.Click
' this code gets the specific value of the cell that is selected by the user (selection by mouse <left> click)
rtb_TestResult.Text = dgv_Test.Item(dgv_Test.CurrentCellAddress.X, dgv_Test.CurrentCellAddress.Y).Value
' you may now insert the value of the cell into a variable
' you may code for the specific validation that you require/desire
End Sub
Private Sub btnGetAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetAll.Click
Dim rowValue As String
' this code will get values of all cells and record it to an array
Num_of_Rows = dgv_Test.RowCount - 1
ReDim Preserve array_of_all_values(Num_of_Rows, Num_of_Columns)
For dgvColumnIndex = 0 To Num_of_Columns - 1
For dgvRowIndex = 0 To Num_of_Rows - 1
array_of_all_values(dgvRowIndex, dgvColumnIndex) = dgv_Test.Item(dgvColumnIndex, dgvRowIndex).Value
Next
Next
' you may now manipulate the inputs using the 2d array
' you may now construct validation codes
' this code displays the array values in table form
' this is useful in checking arrays
For arr_X_index = 0 To UBound(array_of_all_values, 1)
For arr_Y_index = 0 To UBound(array_of_all_values, 2)
rowValue &= array_of_all_values(arr_X_index, arr_Y_index) & vbTab
Next
rtb_TestResult.Text &= rowValue & vbCrLf
rowValue = ""
Next
End Sub
Sample of how the program worked:
Hope that answers your problem.. please be specific next time. :D

Related

Split string into Sub String

I Am Using Vb.net. My idea is when I paste (ctrl+v) for example this character :
AHAKAPATARAE
I Have 6 textboxes.
it would automatically paste them in textboxes one by one in order!
so
txtBox1 will contain : AH
txtBox2 : AK
txtBox3 : AP
txtBox4 : AT
texbox5 : AR
texbox6 : AE
The automation of inserting Licence Keys will ease so much
so that user will not work so hard to cut & paste each two digits!
so any suggestion of doing auto-fill inside textboxes..?
Thanks.
This will allow the paste into the first textbox, as well as move forward correctly if the user types the whole thing manually starting in the first box:
Private Sub txtBox1_TextChanged(sender As Object, e As EventArgs) Handles txtBox6.TextChanged, txtBox5.TextChanged, txtBox4.TextChanged, txtBox3.TextChanged, txtBox2.TextChanged, txtBox1.TextChanged
Dim TB As TextBox = DirectCast(sender, TextBox)
Dim value As String = TB.Text
If value.Length > 2 Then
TB.Text = value.Substring(0, 2)
Dim TBs() As TextBox = {txtBox1, txtBox2, txtBox3, txtBox4, txtBox5, txtBox6}
Dim index As Integer = Array.IndexOf(TBs, TB)
If index > -1 AndAlso index < (TBs.Length - 1) Then
index = index + 1
TBs(index).Text = value.Substring(2)
TBs(index).Focus()
TBs(index).SelectionStart = TBs(index).TextLength
End If
End If
End Sub
There are definitely many more ways this could be accomplished...
Handle the key down event on textbox 1
Private Sub txtBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtBox1.KeyDown
If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.V Then
' Get Clipboard Text
Dim cpText as String = My.Computer.Clipboard.GetText()
' Assign
txtBox1.Text = cpText.Substring(0, 2)
txtBox2.Text = cpText.Substring(2, 2)
txtBox3.Text = cpText.Substring(4, 2)
txtBox4.Text = cpText.Substring(6, 2)
txtBox5.Text = cpText.Substring(8, 2)
txtBox6.Text = cpText.Substring(10, 2)
'the event has been handled manually
e.Handled = True
End If
End Sub
Another option is to have one masked textbox event. Might be easier

Add calculated value to DatagridView from getting value from another datagridview in vb.net

I have an vb.net windows application that has some values which i entered through textbox.
And two datagridviews, in that in first datagridview ,when i enter values in all columns, i have a formula which takes value from Textboxes and DatagridView1 column values. These calculated value should display in second datagridview columns.
For this i tried two ways but both showing problem.
First try:
//First Datagridview -LogCalcEnter , Second Datagrid - LogCalValue
Private Sub LogCalcEnter_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles LogCalcEnter.CellValueChanged
LogCalValue.Rows(intRow).Cells(0).Value = LogCalcEnter.Rows(iRow).Cells(0).Value * fPorCutoff.Text
LogCalValue.Rows(intRow).Cells(1).Value = LogCalcEnter.Rows(iRow).Cells(1).Value * fSWCutoff.Text
End Sub
When executing the application,before showing the form below error occurs at
Me.MainForm = Global.LogCalculation.Form1 in OnCreateMainForm().
Additional information: An error occurred creating the form. See
Exception.InnerException for details. The error is: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index
So i tried another option i have button in form, when i press button,then depends on number of rows in first grid view i will set the values for second datagrid.
But it works if i have one row in Datagridview1. If more than one row, it shows error at second row.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim oLog As New Log
oLog.sWellName = tWellname.Text
oLog.fPoroCutoff = fPorCutoff.Text
oLog.fSWCutOff = fSWCutoff.Text
oLog.fN = fN.Text
oLog.fM = fM.Text
oLog.fA = fA.Text
oLog.fRW = fRW.Text
For iRow = 0 To LogCalcEnter.Rows.Count - 1
If (Trim(LogCalcEnter.Rows(iRow).Cells(0).Value) <> "" And Trim(LogCalcEnter.Rows(iRow).Cells(1).Value) <> "" And Trim(LogCalcEnter.Rows(iRow).Cells(2).Value) <> "") Then
LogCalValue.Rows(iRow).Cells(0).Value = LogCalcEnter.Rows(iRow).Cells(0).Value * oLog.fPoroCutoff
LogCalValue.Rows(iRow).Cells(1).Value = LogCalcEnter.Rows(iRow).Cells(1).Value * oLog.fSWCutOff
LogCalValue.Rows(iRow).Cells(2).Value = LogCalcEnter.Rows(iRow).Cells(2).Value * oLog.fN
End If
Next iRow
End Sub
Actually i want the first option only. But here these two cases get failed.
In the first event, your intRow & iRow may not be defined.
Try this instead,
LogCalValue.Item(0, e.RowIndex).Value = LogCalcEnter.Item(0, e.RowIndex).Value * fPorCutoff.Text
LogCalValue.Item(1, e.RowIndex).Value = LogCalcEnter.Item(1, e.RowIndex).Value * fSWCutoff.Text

Datagridview not displaying tab character

I use a visual basic program to get information from another program, which we'll call ProgramX.
ProgramX has built in functionality to generate tab-delimited tables, which many users copy over to Excel. My goal(which I've acheived) is to generate and collect upwards of 1,000 of these tables and have the results ready for the user to copy/paste into Excel all at once instead of one at a time. My Dataset keeps the tab-delimited records just as I would like them.
The issue is that when I display my dataset/datatable in my datagridview, all tab characters are removed. When the results are copied/pasted into Excel they take up one column instead of automatically breaking out. I have been using datagridview to preview results/copy to clipboard; Is there any way to retain the tabs in this view?
Expected Result: Result 1 [tab] Result 2 [tab] Result 3
Result in datatable: Result 1 [tab] Result 2 [tab] Result 3
Result in datagridview: Result 1Result 2Result 3
If the only way to achieve this is to copy directly from my datatable, I have seen a few posts on how to accomplish that. Thanks!
You have numerous options available, but in most cases you'll need to perform some looping one way or another - however even with 1000+ records it's performance hardly takes a hit.
So for the first couple of options let's assume I have the following setup - keeping with your one DataGridViewColumn idea:
Me.table = New DataTable()
Me.table.Columns.Add("Data", GetType(String))
For i As Integer = 0 To 999
Dim x As Integer = i * 4
Dim data As String = String.Format("Result {0}" & vbTab & "Result {1}" & vbTab & "Result {2}" & vbTab & "Result {3}", x + 1, x + 2, x + 3, x + 4)
Me.table.Rows.Add(data)
Next
Me.dataGridView1.AllowUserToAddRows = False
Me.dataGridView1.DataSource = Me.table
Possible Solutions
Loop through the DataTable, concatenate the data, and set the clipboard text:
Private Sub button1_Click(sender As Object, e As System.EventArgs) Handles button1.Click
Dim content As String = String.Empty
For Each row As DataRow In Me.table.Rows
content = String.Format("{0}" & vbLf & "{1}", content, row.ItemArray(0).ToString())
Next
content = content.TrimStart(ControlChars.Lf)
Clipboard.SetText(content)
End Sub
Loop through the DataGridView.Rows, concatenate the data, and set the clipboard text:
Private Sub button1_Click(sender As Object, e As System.EventArgs) Handles button1.Click
Dim content As String = String.Empty
For Each row As DataGridViewRow In Me.dataGridView1.Rows
content = String.Format("{0}" & vbLf & "{1}", content, row.Cells(0).Value.ToString())
Next
content = content.TrimStart(ControlChars.Lf)
Clipboard.SetText(content)
End Sub
And to make the grid look a little better for both option 1 and 2, since the display seems to ignore tabs:
Private Sub dataGridView1_CellFormatting(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs) _
Handles dataGridView1.CellFormatting
Dim value As String = e.Value.ToString().Replace(vbTab, " ")
e.Value = value
End Sub
With that your grid might look like:
In addition to the original setup and instead of binding to the original DataTable, split the table's data by the tabs and display them in separate columns:
Dim splitTable As New DataTable()
For Each row As DataRow In Me.table.Rows
Dim splitItems = row.ItemArray(0).ToString().Split(ControlChars.Tab)
For i As Integer = splitTable.Columns.Count To splitItems.Length - 1
splitTable.Columns.Add(String.Empty, GetType(String))
Next
splitTable.Rows.Add(splitItems)
Next
Me.dataGridView1.AllowUserToAddRows = False
Me.dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText
Me.dataGridView1.DataSource = splitTable
Then you can use the built-in clipboard method for the DataGridView:
Private Sub button1_Click(sender As Object, e As System.EventArgs) Handles button1.Click
Me.dataGridView1.SelectAll()
Clipboard.SetDataObject(Me.dataGridView1.GetClipboardContent())
End Sub
With that your grid might look like:
For all three options, clicking button1 to copy the data and hitting Ctrl+V in Excel will produce:
Note that Wrap Text will be on by default.
Pros:
Options 1 and 2 leave the user-selected cells intact. Option 3 looks better with separated DataGridView columns.
Cons:
Options 1 and 2 can look less clean pending the data. Option 3 selects all cells, losing the user's previous selected cells.

Pass values from Numeric control into corresponding cells in DataGridView control with a button

I want to move the values from each of four Numeric Up/Down controls into the DataGridView columns/rows with a button. For instance, the operator sets the values in the up/down numeric controls and then clicks the button. The program should then add a new row to the DataGridView and pass whatever values that are in the Numeric Up/Down controls into the new cells of the new row. As of now, I have the adding new rows part of it working as well as the delete button working (delete last row of the DataGridView). Now, how to pass the Numeric control values into the cell of the new row of the DataGridView with the button? Each new row created of the DatGridView has four cells to correspond to the four Numeric up/down controls. Thank you.
Private Sub addStep_btn_Click(sender As Object, e As EventArgs) Handles addStep_btn.Click
LftMtr_Data_Grid.ColumnCount = 4
LftMtr_Data_Grid.RowCount = LftMtr_Data_Grid.RowCount + 1
LftMtr_Data_Grid.Columns(0).HeaderText = " Spindle Speed (rpm)"
LftMtr_Data_Grid.Columns(1).HeaderText = " Accel Rate (rpm/S)"
LftMtr_Data_Grid.Columns(2).HeaderText = " Decel Rate (rpm/S)"
LftMtr_Data_Grid.Columns(3).HeaderText = " Time (S)"
For Each c As DataGridViewColumn In LftMtr_Data_Grid.Columns
c.Width = 120
Next
Dim rowNumber As Integer = 1
For Each row As DataGridViewRow In LftMtr_Data_Grid.Rows
If row.IsNewRow Then Continue For
row.HeaderCell.Value = "Step " & rowNumber
rowNumber = rowNumber + 1
Next
LftMtr_Data_Grid.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
rowCount1 = LftMtr_Data_Grid.RowCount
txtBox1.Text = rowCount1
End Sub
Try something like below. Note that you don't need to setup the column headers everytime, just once in the Load() event would do!
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LftMtr_Data_Grid.ColumnCount = 4
LftMtr_Data_Grid.Columns(0).HeaderText = " Spindle Speed (rpm)"
LftMtr_Data_Grid.Columns(1).HeaderText = " Accel Rate (rpm/S)"
LftMtr_Data_Grid.Columns(2).HeaderText = " Decel Rate (rpm/S)"
LftMtr_Data_Grid.Columns(3).HeaderText = " Time (S)"
For Each c As DataGridViewColumn In LftMtr_Data_Grid.Columns
c.Width = 120
Next
LftMtr_Data_Grid.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
End Sub
Private Sub addStep_btn_Click(sender As Object, e As EventArgs) Handles addStep_btn.Click
Dim values() As Object = {NumericUpDown1.Value, NumericUpDown2.Value, NumericUpDown3.Value, NumericUpDown4.Value}
Dim index As Integer = LftMtr_Data_Grid.Rows.Add(values)
LftMtr_Data_Grid.Rows(index).HeaderCell.Value = "Step " & (index + 1)
LftMtr_Data_Grid.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
End Sub
Private Sub delStep_btn_Click(sender As Object, e As EventArgs) Handles delStep_btn.Click
If LftMtr_Data_Grid.Rows.Count > 0 Then
LftMtr_Data_Grid.Rows.RemoveAt(LftMtr_Data_Grid.Rows.Count - 1)
End If
End Sub
End Class
I figured it out on my own. Here is what I came up with:
Dim rowNumber As Integer = 1
For Each row As DataGridViewRow In LftMtr_Data_Grid.Rows
If row.IsNewRow Then Continue For
row.HeaderCell.Value = "Step " & rowNumber
LftMtr_Data_Grid.CurrentCell = LftMtr_Data_Grid.Rows(LftMtr_Data_Grid.RowCount - 1).Cells(0)
LftMtr_Data_Grid.CurrentRow.Cells(0).Value = LftMtr_Speed_Incr.Value
LftMtr_Data_Grid.CurrentRow.Cells(1).Value = LftMtr_Accel_Incr.Value
LftMtr_Data_Grid.CurrentRow.Cells(2).Value = LftMtr_Decel_Incr.Value
LftMtr_Data_Grid.CurrentRow.Cells(3).Value = test_Time_Incr1.Value
rowNumber = rowNumber + 1
Next
This application works with an empty or partially filled dataGridView. When the user clicks the button, the code creates a new row in the dataGridView, makes the new row the selected row, and then finally populates each of the cells in the new row with the values that are in the four Numeric Up/down controls (could be a text box too depending on your application). This is code copied directly from my specific application. Yours may differ slightly with variable names, label text, etc.

Binary Search or Insertion Sort with list view [Visual Basic .net]

Recently when creating a program for my client as part of my computing project in visual basic .net I've came across a problem, which looks like following; In order to receive additional marks for my program I must take an advantage of either Binary Search or Insertion Sort subroutine declared recursively, so far the only place I can use it on is my View form which displays all reports generated by program but the problem with this is since I'm using MS Access to store my data all of the data is downloaded and placed in listview in load part of form. So the only way I can use it is by running it on listview which is a major problem for me due to the fact that I'm not very experienced in vb.
For binary search I have tried downloading all of the items in specified by user column into an array but that's the bit I was struggling on the most because I'm unable to download all items from only one column into an array. Also instead of searching every single column user specifies in my form in which column item is located (For example "19/02/2013" In Column "Date"), In my opinion if I manage to download every single entry in specified column into an array it should allow me to run binary search later on therefore completing the algorithm. Here's what I've got so far.
Sub BinarySearch(ByVal Key As String, ByVal lowindex As String, ByVal highindex As String, ByVal temp() As String)
Dim midpoint As Integer
If lowindex > highindex Then
MsgBox("Search Failed")
Else
midpoint = (highindex + lowindex) / 2
If temp(midpoint) = Key Then
MsgBox("found at location " & midpoint)
ElseIf Key < temp(midpoint) Then
Call BinarySearch(Key, lowindex, midpoint, temp)
ElseIf Key > temp(midpoint) Then
Call BinarySearch(Key, midpoint, highindex, temp)
End If
End If
End Sub
Private Sub btnSearch_Click(sender As System.Object, e As System.EventArgs) Handles btnSearch.Click
Dim Key As String = txtSearch.Text
Dim TargetColumn As String = Me.lstOutput.Columns(cmbColumns.Text).Index
Dim lowindex As Integer = 0
Dim highindex As Integer = lstOutput.Items.Count - 1
'Somehow all of the items in Target column must be placed in temp array
Dim temp(Me.lstOutput.Items.Count - 1) As String
' BinarySearch(Key, lowindex, highindex, temp)
End Sub
For Insertion sort i don't even have a clue how to start, and the thing is that I have to use my own subroutine instead of calling system libraries which will do it for me.
Code which I have to use looks like following:
Private Sub InsertionSort()
Dim First As Integer = 1
Dim Last As Integer = Me.lstOutput.
Dim CurrentPtr, CurrentValue, Ptr As Integer
For CurrentPtr = First + 1 To Last
CurrentValue = A(CurrentPtr)
Ptr = CurrentPtr - 1
While A(Ptr) > CurrentValue And Ptr > 0
A(Ptr + 1) = A(Ptr)
Ptr -= 1
End While
A(Ptr + 1) = CurrentValue
Next
Timer1.Enabled = False
lblTime.Text = tick.ToString
End Sub
Any ideas on how to implement this code will be very appreciated, and please keep in my mind that I'm not very experienced in this language
Perhaps this might give you a place to begin. If you already have a ListView with "stuff" in it you could add a button to the form with the following code to copy the Text property for each item into an array:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myArray(Me.ListView1.Items.Count - 1) As String
Dim i As Integer
' load array
For i = 0 To Me.ListView1.Items.Count - 1
myArray(i) = Me.ListView1.Items(i).Text
Next
' show the results
Dim s As String = ""
For i = 0 To UBound(myArray)
s &= String.Format("myArray({0}): {1}", i, myArray(i)) & vbCrLf
Next
MsgBox(s, MsgBoxStyle.Information, "myArray Contents")
' now go ahead and manipulate the array as needed
' ...
End Sub