read from SQL to Button - vb.net

please help on this issue, i want to read ID from SQL to different button but still i cant able to do it. please help.
this is the code i tried.
this code read same ID in both button instead of different id in different button. see the screenshot for your reference.
Dim dt As New DataTable
Dim da As New SqlDataAdapter("select Locker_ID from Locker", colnnn)
da.Fill(dt)
For Each row As DataRow In dt.Rows
Button2.Text = row.Item("Locker_ID")
Button1.Text = row.Item("Locker_ID")
Next

You do not only have to loop the rows but also the buttons. If you have 2 locker rows, your loop executes the loop body twice. I.e., the first locker id is assigned to both buttons and then the second locker id is assigned to the same buttons again, overwriting the first value.
Dim dt As New DataTable
Dim da As New SqlDataAdapter("select Locker_ID from Locker", colnnn)
da.Fill(dt)
Dim i As Integer = 1
For Each row As DataRow In dt.Rows
Controls("Button" & i).Text = row.Item("Locker_ID")
i = i + 1
Next
This will assign the first Locker_ID to Button1, the second one to Button2, etc.
The Controls collection allows you to access the controls by name by using a string as index.
Note that you can change the name of the buttons. If you name the buttons where you want to have the locker id as btnLocker1, btnLocker2, btnLocker3 etc. then Controls("btnLocker" & i).Text = row.Item("Locker_ID") will automatically select the right buttons.
It is advisable to give your controls speaking names. Also, do this before creating event handlers. E.g., nobody knows what Sub Button17_Click is supposed to do; however, if you name the button btnPrint, the winforms designer will automatically create a Sub named btnPrint_Click when you double click the button.
See also: For Each Loops

Related

How do I make DataBindings update in runtime?

Noob programmer here, go easy on me if the answer was straight up obvious. Couldn't really find the right title but it's the closest one I got.
To get straight to the point, I have a textbox in my program, and whatever I type in the textbox should go straight to a table in my database, and then when I click a specific button, whatever I last put in the table should show up on the label beside the textbox via DataBindings (at least, that's how I want it to go).
It works for the most part. When I type something in and click my button, the text shows up on the label. But when I do it a second time , the label doesn't update to what I last typed (it only updates when I stop and start running the program again.)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
connection.Open()
Dim test1 As String = "SELECT TOP 1 Letters From NewTable ORDER BY Id DESC"
ExecuteQuery(test1)
Dim command As New SqlCommand(test1, connection)
Dim adapter As New SqlDataAdapter(test1, connection)
adapter.Fill(TestDatabaseAgainDataSet1, "NewTable")
randomlabel.DataBindings.Clear()
randomlabel.DataBindings.Add("Text", TestDatabaseAgainDataSet1.NewTable, "Letters")
command.ExecuteNonQuery()
connection.Close()
End Sub
I know there are some easier ways for user-generated text to show up on a label, but I kinda need it so the last thing I typed is still there when I click the button.
If I understand correctly, you only have problem on the second part of your project: whatever you last put in the table should show up on the label beside the textbox.
If you are on SQL Server you can use SqlDataReader class that provides a way of reading a forward-only stream of rows from a SQL Server database.
Dim cmdLastLetter As SqlCommand = conn.CreateCommand()
cmdLastLetter.CommandText = "SELECT TOP 1 Letters From NewTable ORDER BY Id DESC"
Dim drLastLetter As SqlDataReader = cmdLastLetter.ExecuteReader()
If drLastLetter.Read() Then
Me.Label1.Text = drLastLetter("Letter")
End If
drLastLetter.Close()
cmdLastLetter.Dispose()
If you are using another database consult this document: you have to use another class but the concept is the same.

vb.net listview display next record

I have a problem when displaying the records in ListView. The database I have right now have a 10k + of records (rows). When pulling the data to ListView, It takes a lot of time so I limit the displayed items to 50. I can successfully display the 50 items. But my problem is how do I display the next 51-100 record when the user click the "Next Page" button? I have no idea where to start. Please help me. Thanks.
da = New MySqlDataAdapter
Dim strSql As String = "SELECT * FROM tbl_questions"
ListView1.Items.Clear()
Call connect()
da.SelectCommand = New MySqlCommand(strSql)
da.SelectCommand.Connection = cn
da.Fill(ds)
Dim i As Integer
For i = 0 To ds.Tables(0).Rows.Count - 1
If i = 49 Then
Exit For
End If
Dim lv As ListViewItem = ListView1.Items.Add(ds.Tables(0).Rows(i)("function"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("subject"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("level"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("type"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("question"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("choice_a"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("choice_b"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("choice_c"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("choice_d"))
lv.SubItems.Add(ds.Tables(0).Rows(i)("correct_ans"))
Next
da.Dispose()
I am assuming you are using winforms. The ListView control does have a virtualization feature that you can try by using the ListView.VirtualMode Property and ListView.CacheVirtualItems Event. See if these MSDN links help you.
From above link:
Virtual mode can be useful under many circumstances. If a ListView object must be populated from a very large collection already in memory, creating a ListViewItem object for each entry can be wasteful. In virtual mode, only the items required are created. In other cases, the values of the ListViewItem objects may need to be recalculated frequently, and doing this for the whole collection would produce unacceptable performance. In virtual mode, only the required items are calculated.

Showing a single record in datagridview from access database vb.net

What I have is a small application that has a datagridview and an Access DB. There are 10 records in the database and they all show up in the datagridview when the app is launched. I need to be able to do two things:
I need to be able to enter an id number in a textbox and have JUST that record show in the DGV.
I need to be able to have it show all the records again (using a different click event of course).
I am able to choose the record with this:
Dim row As DataRow
row = ProductsDataSet.tblProducts.FindByItemNum(txtNumber.Text)
but I am unable to figure out how to show just that record in the DGV.
(Let me clarify...I THINK I am choosing the record simply because no exceptions are being thrown).
Any guidance here would be greatly appreciated. Thank you.
John
An option is to set the dataSource of your dataGridView to the data you'd like to display. Below is an implementation using dataTables.
Class MyForm
Dim dataTableAll, dataTableOneID, As DataTable
Sub show1ID_Click
Dim id As Integer = InputBox("Enter ID")
dataTable2 = dataTable1.Select("[ID] = id").CopyToTable
dataGridView.DataSource = dataTableOneID
End Sub
Sub showAll_Click
dataGridView.DataSource = dataTableAll
End Sub
End Class

How to run code in real time across multiple tabs, windows form, vb.net

I am currently programming in vb.net for a windows forms applications.
I have a windows form with multiple tabs and within each tab I have a DGV. Each DGV is connected to an sql server table, the same table across all tabs.
I want to use a check box to copy rows of data from the sql table to a specific tab. In this case I want to try and have this happen in real time, so without using a "refresh" button or something like that.
On each row in every tab I want the row of data to appear or disappear from the last tab depending on the status of the check box.
I have attached code and a picture. The code is used on the form load event to load the tables into the tabs. In the image you can see i want the rows to be loaded into the "ordered floors" tab after the check box has been checked.
Private Sub FormOrdered_Load(sender As Object, e As EventArgs) Handles Me.Load
'load line 2 tab
Try
Using conn1 As New SqlConnection(connstring)
conn1.Open()
Using comm1 As SqlCommand = New SqlCommand("Select LineNumber, ShearNumber, JobNumber, FloorNumber, OrderedBy, DateOrdered, Ordered FROM Production.dbo.tblFCordered where LineNumber = 2", conn1)
Dim da As New SqlDataAdapter
da.SelectCommand = comm1
da.Fill(Line2)
End Using
conn1.Close()
End Using
DataGridLine2.DataSource = Line2
Catch ex As Exception
MsgBox("Unable to make SQL Connection to load Line 2 Table, please contact an engineer!")
MsgBox(ex.ToString)
End Try
image
You could just clone the rows from the DGV when you check the checkbox and add them to the Ordered floors dgv.
Something like:
Private Sub CopyRows_CheckedChanged() Handles CopyRows.CheckedChanged
For each r as DataGridViewRow in MyDGV.Rows
dgvOrderedFloors.Rows.Add(r.Clone())
next
End Sub
You'll have to modify this to suit obviously, but I think something along these lines should do what you want.
Or you could clone the data tables you use for each datagridview, and add them to one master table which will be the datasource for your Ordered floors datagridview.
That would be better, but might be more work upfront.

How to Ommit DataGridViewRow from DataSource Based on Another Table's Data

I have a DataGridView filled with Bills from a DataTable (which is set as it's DataSource). These Bills are shown to my engineers so that they can build a Bill of Materials.
This is the SQL query which gets all my Bills:
SELECT *
FROM Bills
ORDER BY Case IsNumeric(JobNumber)
WHEN 1 THEN Replicate('0', 50 - Len(JobNumber)) + JobNumber ELSE JobNumber END
This sorts the bills by job number (some are numbers, some are strings and some are a mix of integers and characters).
Features
They can open the bill to view it (Read only) or to edit it.
Further explanation
If an engineer opens a Bill to edit it, it will be placed in a table named "OpenBills". I do this so that no other engineer can open the same bill and edit it while being worked on. The point of the OpenBills table is to determine which bill is opened. Once I know which bill is opened, I don't want it to be provided in their DataGridView when they go to edit a bill.
On the other hand, when the engineer searches for a bill to open as read-only, they should ALL be displayed (even the ones currently opened). The difference is I simply put a light blue color as the background of the row to notify the user that it is currently opened.
My current 'solution'
I am currently using a CellFormatting event on my DataGridview. In short, I verify if the current Bill being added is in my OpenBills table lst_OpenBills. If it is, then I verify if I am viewing the DataGridView as read-only or for editting mode. If it's in edit mode, I will hide the row. If it is in read-only, I will change it's back color.
Private Sub dgvBills_CellFormatting(sender As Object, e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgvBills.CellFormatting
Dim drv As DataRowView
If e.RowIndex >= 0 Then
If e.RowIndex <= dsBOM.Tables("dtBills").Rows.Count - 1 Then
drv = dsBOM.Tables("dtBills").DefaultView.Item(e.RowIndex)
Dim c As Color
If lst_OpenBills.ContainsKey(drv.Item("PK_Bill").ToString) Then
If int_EntryPoint = 0 Then
'Read Only
c = Color.LightBlue
e.CellStyle.BackColor = c
Else
'Edit mode
dgvBills.Rows(e.RowIndex).Visible = False
End If
End If
End If
End If
End Sub
Problem with current solution
I use AlternatingRowStyles to make it easier to read. As you can see in the following comparisons, the edit mode picture should not display the alternating row styles like that. How could I ommit the DataGridViewRow from the DataTable ? Should I just re-apply the AlternatingRowStyles?
Read Only results
Edit mode
Does anyone have any solutions? Perhaps my query to get all my bills isn't appropriate ... I use the same form for both situations (read-only & edit mode). I just differentiate them using an Enum enum_EntryPoint. Any helps or suggestions is appreciated.
You could iterate through the datatable and remove the one you have selected and redraw the datagridview. Not another SQL call just using the datatable you already have. You can reinsert the row if you want, when done, or just use that same beginning datatable to refresh the DGV.
For example if the open bill was id 1287:
Dim dtTemp As DataTable = dtOpenBills.Clone()
For Each dr As DataRow in dtOpenBills.Rows
If Cint(dr("OpenBillID")) <> 1287 Then
Dim drTemp As DataRow = dtTemp.NewRow()
drTemp = dr
dtTemp.Rows.Add(drTemp)
End If
Next
DataGridViewName.DataSource = dtTemp
DataGridViewName.Refresh() 'Might not be needed
You haven't touched the original datatable.