Dim Mysqlconn = New SqlConnection
Mysqlconn.ConnectionString = "Data Source=DESKTOP-D32ONKB;Initial Catalog=Attendance;Integrated Security=True"
Dim dt As DataTable = New DataTable("studentdata")
Mysqlconn.Open()
Dim query As String
query = "select ID from studentdata where Class='" & ComboBox1.Text & "'"
Dim Command = New SqlCommand(query, Mysqlconn)
Dim dr = Command.ExecuteReader(CommandBehavior.CloseConnection)
ListView1.Items.Clear()
Dim x As ListViewItem
Do While dr.Read = True
x = New ListViewItem(dr("ID").ToString)
ListView1.Items.Add(x)
Loop
For i = 0 To ListView1.Items.Count - 1
TextBox1.Text = ListView1.Items(i).SubItems(0).Text
Next
In this code, Textbox1 is showing the last row from Listview1. My requirement is all the Listview1 data show in textbox1 one after one from Listview1. Is this possible to show in textbox1 read all data from Listview1 using loop. Thank you...
A textbox only holds one string at a time. If it's set to allow multiline strings (not clear in the question) you can separate each item with a linebreak. Otherwise you can separate the strings using a delimiter like a comma.
Dim query As String = "select ID from studentdata where Class= #class"
Using conn As New SqlConnection("Data Source=DESKTOP-D32ONKB;Initial Catalog=Attendance;Integrated Security=True"), _
cmd As New SqlCommand(query, conn)
cmd.Parameters.Add("#class", SqlDbType.NVarChar, 20).Value = ComboBox1.Text
conn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader()
While dr.Read()
ListView1.Items.Add(New ListViewItems(dr("ID").ToString()))
End While
End Using
End Using
TextBox1.Text = String.Join(",", ListView1.Items.Select(Function(i) i.SubItems(0).Text))
Also note how I used a query parameter to include the combobox value in the SQL command. That's a big deal; anything else will give you trouble, usually sooner than later.
Using as loop, the proper way would be like so:
Dim lines As New List(Of String)
For i = 0 To ListView1.Items.Count - 1
lines.Add(ListView1.Items(i).Text)
Next
TextBox1.Lines = lines.ToArray()
You can't keep setting the Text property to a new value and expect the old value to hang around for no reason. You could append to the Text each time, but that is inefficient. The proper way is to create a list of the values, convert that to a String array and then assign that to the Lines property.
Note that there is no point getting the Text of the first subitem because that is the same as the Text of the item.
Related
I am attempting to pull values from an SQL Server table from VB.NET.
On VB Form 1, the number from NoTable, Row 1, is pulled successfully, and Label1 is updated with the value.
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(0)
End If
datareader.Close()
On VB Form 2 I am attempting to pull the value from the second row, using:
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(1)
End If
datareader.Close()
However, this does not work, and the label is not updated with the value from the second row.
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
Additional information: Index was outside the bounds of the array."
How would I go about fixing this, so that on Form 2, the value from Row 2 is pulled, and so forth?
Thank you.
Firstly, you only get one column back from the reader, but you are indexing the columns with that 0 or 1. So you should always pass 0 to GetValue.
To index the row instead, try this. Assign a form number to each form (first line in my example) and use that to determine which record to assign to the Label. There is probably a more efficient way to do this (not returning all the records before it) but this solution should fit in your environment.
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Dim index = 0
While index < formNumber
If datareader.Read() AndAlso index = formNumber Then
Label1.Text = datareader.GetValue(0)
End If
index += 1
End While
datareader.Close()
See https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getvalue(v=vs.110).aspx
And another similar question in c# Access a specific row in DataReader
Another way is to just return the row you need in the first place, without iterating over the records on the client side. Assuming there is another column with an index which is in the same order as the row you want to return, called "ID"
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String =
"SELECT Number FROM " & _
" (SELECT Number, Row_Number() OVER (ORDER BY ID) AS RowNumber " & _
" FROM NoTable) AS Results " & _
" WHERE Results.RowNumber = " & formNumber.ToString()
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Label1.Text = datareader.GetValue(0)
datareader.Close()
See https://msdn.microsoft.com/en-us/library/ms186734.aspx
GetValue(1) does not exist, as this would refer to a second column in the select statement. You are only asking for [Number] which would be datareader.GetValue(0)
I am currently working in VB.NET express for desktop, 2013. I am having a hard time binding SQL data to some datagridviews on a loop with an array. I am receiving an object null error and its because on the direct cast line its not pulling the datagridview. I have multiple datagridviews on a tab control tool, one datagridview per tab. Here is my code:
try
Dim array() As Integer = {"2", "3", "4", "7", "8", "10", "11", "12"}
For Each value As Integer In array
Dim RelativeDGV = DirectCast(Me.Controls("DataGridLine" & value), DataGridView)
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As New SqlCommand("SELECT LineNumber FROM tableA where LineNumber = #LineNumber", conn1)
comm1.Parameters.AddWithValue("#LineNumber", value)
Dim dt As New DataTable
Dim sql As New SqlDataAdapter(comm1)
sql.Fill(dt)
RelativeDGV.DataSource = dt
End Using
conn1.Close()
End Using
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
The error is on line
Dim RelativeDGV = DirectCast(Me.Controls("DataGridLine" & value), DataGridView)
But the null error dosen't trigger until
RelativeDGV.DataSource = dt
Try to use list of DataGridView like this :
Try
Dim array() As DataGridView = {DataGridLine2, DataGridLine3, DataGridLine4, DataGridLine7, DataGridLine8, DataGridLine10, DataGridLine11, DataGridLine12}
For Each RelativeDGV As DataGridView In array
Dim value As Integer = Regex.Replace(RelativeDGV.Name, "[^0-9]+", String.Empty)
'or like this
'Dim value As Integer = RelativeDGV.Name.Substring(12, RelativeDGV.Name.Length - 12)
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As New SqlCommand("SELECT LineNumber FROM tableA where LineNumber = #LineNumber", conn1)
comm1.Parameters.AddWithValue("#LineNumber", value)
Dim dt As New DataTable
Dim sql As New SqlDataAdapter(comm1)
sql.Fill(dt)
RelativeDGV.DataSource = dt
End Using
conn1.Close()
End Using
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
If the various DGV controls are on other tabs, they wont be in Me.Controls. Rather than fish them out and cast them, you can iterate an array of them since you know the name. You also do not need to create a new connection for each nor duplicate datatables for each:
Dim dgvCtrls As DataGridView() = {DataGridLine2, DataGridLine3, DataGridLine4}
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As New SqlCommand("SELECT LineNumber FROM...", conn1)
' ...
dt.Load(comm1.ExecuteReader())
End Using
conn1.Close()
End Using
For Each dgv In dgvCtrls
dgv.DataSource = dt
Next
You'd only need 8 identical DataTables if you dont want each grid to automatically reflect changes made in the others. For that, use a dataset on the same connection to create the tables:
Dim SQL = "..."
Dim dgvCtrls As DataGridView() = {dgv5, dgv2, dgv3,...}
Dim ds = New DataSet
Using dbcon As New SqlConnection(SQLConnStr)
Using cmd As New SqlCommand(SQL, dbcon)
dbcon.Open()
For n As Int32 = 0 To dgvCtrls.Count - 1
ds.Load(cmd.ExecuteReader, LoadOption.OverwriteChanges, dgvCtrls(n).Name)
Next
End Using
End Using
For Each dgv In dgvCtrls
dgv.DataSource = ds.Tables(dgv.Name)
Next
I'm looking for a way to set the next value of a row into a label
without using a Binding Navigator. ex: when I click the next button the next username in the username column should appear on the label and keep rolling the names.
Actually planing to make a quiz so I want to 'roll' the question.
What I've tried
I have bound data(ex: usernames) to a label using its property (Data Bindings). Now how can I display them in the label and with each button press have the next one appear?
OK, this is what did to achieve that on alternative way:
but this not working
I'm getting this error >> Syntax error in string in query expression 'tagno='2'. # line dr = Command.ExecuteReader
The objective is to on button click the count integer will increment and then the query will use count value to find question from database
for example if the increment value is 2 then the reader should return question from row where tagno two is.
the database table (quest) has following columns, Question Correct_Answer, tagno
Dim count As Integer
Private Sub btncontinue_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btncontinue.Click
Dim conn As New OleDb.OleDbConnection
Dim olequery As New OleDb.OleDbCommand
Dim connString As String
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\" & Application.StartupPath & "\game.accdb"
conn.ConnectionString = connString
olequery.Connection = conn
count += 1
Dim dr As OleDbDataReader
'quest is the table name.
Dim query As String = "select question from quest where tagno='" & count & ""
cnnOLEDB.Open()
Dim command As New OleDbCommand(query, cnnOLEDB)
dr = Command.ExecuteReader
dr.Read()
lblquestion.Text = dr(0)
cnnOLEDB.Close()
End Sub
Fist column of listview is populated from database (database column name KONTO - only values that starts with 2020-), second column of the listview should be populate from corresponding items to KONTO from same database column NAZIV into second column of the listview.
Description is in column NAZIV in databsase
I've been experimenting with this all day and didn't have any success.
Here is the code I have so far :
ListView1.View = System.Windows.Forms.View.Details
ListView1.Columns.Add("COL1", 100, HorizontalAlignment.Left) 'KONTO
ListView1.Columns.Add("COL2", 160, HorizontalAlignment.Left) 'NAZIV
Dim FilePath As String = "W:\GLAVNI\KOR14\"
Dim DBF_File As String = "MATIKGL"
Dim ColName As String = "KONTO"
'Dim naz As String
Using con As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FilePath & _
" ;Extended Properties=dBASE IV")
con.Open()
Using cmd As New OleDbCommand("SELECT * FROM MATIKGL ORDER BY KONTO, NAZIV", con)
Using reader As OleDbDataReader = cmd.ExecuteReader()
If reader.HasRows Then
While (reader.Read())
Me.ListView1.Items.Add(reader("KONTO"))
'LOOP BELOW SELECTS ALL ITEMS THAT STARTS WITH 2020-
For i = 0 To ListView1.Items.Count - 1
If ListView1.Items(i).ToString.Contains("2020-") Then
Else
ListView1.Items.Remove(ListView1.Items(i))
End If
Next
End While
Else
End If
End Using
End Using
con.Close()
End Using
Thanks.
UPDATE
To be more clear, here is the screen from database.
Only items starting with 2020- (1) should populate first column of listview, and second column should be populated with "2020-" description from column NAZIV (2).
Each LV Item has a collection of SubItems associated with it. The subItems show as columns in the Details view:
Dim lvi As ListViewItem ' scratch var for adding items
Dim tmp As String
Using cmd As New OleDbCommand("SELECT * FROM MATIKGL ORDER BY KONTO, NAZIV", con)
Using reader As OleDbDataReader = cmd.ExecuteReader()
If reader.HasRows Then
While (reader.Read())
' Db rdr returns Object, cast to string
tmp = reader.Item("KONTO").ToString
' no need to loop - just use the scratch vars
' only adding if it contains 2020
If tmp.Contains("2020-") Then
lvi = New ListViewItem
lvi.Text = tmp
' add the sub item
lvi.SubItems.Add(reader("NAZIV").toString)
ListView1.Items.Add(lvi)
End If
End While
End If
End Using
you can get rid of the tmp var using reader.Item("KONTO").ToString.Contains("2020")...the above is for clarity
I have created a screen for editing database records. After user selects the table, I have dynamically added Labels and TextBox inside the TableLayoutPanel1. I want to know how to access the value present in the TextBox which is inside TableLayoutPanel1
I code which i used:
Dim strSQL, strSQL1 As String
Dim ln As Integer
Dim reader As OleDbDataReader
Dim connection As OleDbConnection
Dim ds As New DataSet
connection = New OleDbConnection(CONNECT_STRING)
connection.Open()
ln = 0
strSQL = " select * from syscat.columns where TABSCHEMA like 'QA1MM%' and TABNAME like 'SKU_STR_LIST' with ur "
RichTextBox1.Text = RichTextBox1.Text + strSQL
Dim selectCMD As OleDbCommand = New OleDbCommand(strSQL, connection)
reader = selectCMD.ExecuteReader
MessageBox.Show("Column: " & reader(0) & " ")
While reader.Read()
If String.IsNullOrEmpty(reader(0)) Then
Else
TableLayoutPanel1.ColumnCount = 2
TableLayoutPanel1.RowCount = 20
Dim aLabel As New System.Windows.Forms.Label
Dim aTextBox As New System.Windows.Forms.TextBox
aLabel.Name = "New Label"
aLabel.Text = reader(0).Text
TableLayoutPanel1.Controls.Add(aLabel, 0, ln)
TableLayoutPanel1.Controls.Add(aTextBox, 1, ln)
ln = ln + 1
End If
End While
How can i access the value present in the aTextBox which i added dynamically inside the TableLayoutPanel1?
First off you need to set a name on the TextBox. Basically aTextbox.Name = "TextBox1". Then you should be able to find the control by using:
Control c = TableLayoutPanel1.Controls.Find("TextBox1",true)
Keep in mind however that this will give you a control, not a textbox. So typecast it in whatever way you find suitable.
Ctype(c,TextBox)
DirectCast(c,TextBox)
As WozzeC says you need to give the text box a name that is unique, probably something like
aTextBox.Name = "TextBox" & ln
Then you could find it this way
Dim words = TableLayoutPanel1.Controls("Textbox1").Text
or if its in the same loop
Dim words = TableLayoutPanel1.Controls("Textbox" & ln).Text