Dynamically generating labels in loop - arrays

I'm having a bit of a problem. Granted, I'm not the best with VB, but I can't figure out for the life of my why this isn't working.
I have an Access database that I pull data from. I'm trying to dynamically create labels so I can present the data as prettily as I want. However, when trying to execute it, I'm getting an exception "System.NullReferenceException: Object reference not set to an instance of an object" on the line arrayLabels(i).Text = "Howdy"
I'm almost certain it's something stupidly simple that I'm just missing... but here's my code:
Private Sub TabControl2_Click(sender As Object, e As EventArgs) Handles TabControl2.Click, btnRefresh1.Click, btnRefresh2.Click, btnRefresh3.Click, ddSelectTech.SelectedIndexChanged, ddSelectTech2.SelectedIndexChanged
If TabControl2.SelectedIndex = 0 Then
'use this to count the number of rows
Dim numRows As Integer
'here be database stuff
Dim da2 As OleDb.OleDbDataAdapter
Dim ds2 As New DataSet
Dim con2 As New OleDb.OleDbConnection
con2.ConnectionString = dbProvider & dbSource
sqlStatusOpen = "SELECT * FROM work_orders WHERE status = 'In Progress';"
da2 = New OleDb.OleDbDataAdapter(sqlStatusOpen, con2)
con2.Open()
da2.Fill(ds2, "installations2")
con2.Close()
numRows = ds2.Tables("installations2").Rows.Count()
'create an array label based on the number of rows in the table
Dim arrayLabels(numRows) As Label
'loop it to actually make the labels, position them, and such
For i = 0 To (numRows - 1) 'just looping the number of rows
Dim x As Integer = 100
Dim y As Integer = 1 + (i * 10)
Try
TabPage3.Controls.Add(arrayLabels(i))
arrayLabels(i).Text = "Howdy"
arrayLabels(i).Location = New Point(x, y)
Catch ex As Exception
MessageBox.Show(ex.ToString, "Looky there, Franky, another error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Next
ElseIf TabControl2.SelectedIndex = 1 Then
ElseIf TabControl2.SelectedIndex = 2 Then
Else
End If
End Sub
Of course, if you think there are better ways to handle this, I'm open to suggestions.

Your code:
Dim arrayLabels(numRows) As Label
Creates an array with the type Label. But every entry in this array is null.
Try to initialize every label in your loop:
Dim label As New Label
label.Text = "Howdy"
label.Location = New Point(x, y)
TabPage3.Controls.Add(label)
And you don't need to save the labels inside an array.

Related

All Listview data show in textbox using loop

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.

Reading Data from Access database and adding to a combox is very slow

So Ive been trying to read from a large access database and the table iam trying to read from contains nearly 20000 entries, all of which are needed in the combox. With some testing I have figured out that the program slows down the longer it runs. The first 5000 are added almost instantaneously, but the next 5000 increment increase exponentially. Over all it would take about 5 minutes to load the entire thing. Am i missing something that will make it more efficient? Ive attached the function iam using below. It is in Vb.net
Private Sub chkBoxPurchasedPart_CheckedChanged(sender As Object, e As EventArgs) Handles chkBoxPurchasedPart.CheckedChanged
If (chkBoxPurchasedPart.Checked) Then
chkBoxRawMaterial.Checked = False
chkBoxSkipMaterialSelection.Checked = False
MaterialButton.Enabled = True
comboxMaterial.Sorted = True
comboxMaterialHdn.Text = "AS SUPPLIED"
comboxMaterialHdn.Enabled = False
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Dim oConnect, oQuery As String
oConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Y:\eng\ENG_ACCESS_DATABASES\VisibPartAttributes.mdb"
oQuery = "SELECT * FROM VISIB_PARTMASTER_LOCAL WHERE PRODUCT_LINE LIKE '%PUR%' OR PRODUCT_LINE LIKE '%NOSTD%' AND PARTDESCR NOT LIKE '%OBSOLETE%'"
Try
cn.Open()
Catch ex As Exception
Finally
cn = New OleDbConnection(oConnect)
cn.Open()
End Try
cmd = New OleDbCommand(oQuery, cn)
dr = cmd.ExecuteReader
comboxMaterial.Items.Add("- - OTHER - -")
While dr.Read()
comboxMaterial.Items.Add(dr(0))
End While
dr.Close()
cn.Close()
Try
Dim s As Session = Session.GetSession()
Dim dispPart As Part = s.Parts.Display()
Dim c As NXOpen.Assemblies.Component = dispPart.ComponentAssembly.RootComponent
Dim children As NXOpen.Assemblies.Component() = c.GetChildren()
Dim childMaterial As String = Nothing
For Each child As NXOpen.Assemblies.Component In children
childMaterial = child.GetStringAttribute("STACKTECK_PARTN")
If (childMaterial.Length > 5 Or child.Name.StartsWith("PUR")) Then
comboxMaterial.Text = childMaterial
End If
Next
Catch ex As Exception
End Try
ElseIf (chkBoxPurchasedPart.Checked = False) Then
comboxMaterialHdn.Text = ""
comboxMaterialHdn.Enabled = True
txtBoxDiameter.Enabled = True
txtBoxRoundLength.Enabled = True
txtBoxInnerDiameter.Enabled = True
txtBoxLength.Enabled = True
txtBoxWidth.Enabled = True
txtBoxThickness.Enabled = True
MaterialButton.Enabled = False
txtBoxVisMaterial.Text = ""
txtBoxVisMaterialDescription.Text = ""
txtBoxEachQuantity.Text = ""
txtBoxTotalQuantity.Text = ""
txtBoxUnitOfMeasure.Text = ""
comboxMaterial.Sorted = False
comboxMaterial.Items.Clear()
comboxMaterial.Text = ""
End If
End Sub
For anyone in the future having a similar issue, the combobox wasnt the problem, the previous designer had the AutoCompleteMode set to suggest and append which slowed the entire process down. Disable it and your program should speed up.
I would only load the combo-box records after the first 3 or 4 characters have been entered. This should drastically reduce the number of records being returned, and a still allow the autocomplete to work.
This thread has code to assist you : get 65K records only listed in combo box from a table of 155K records

Passing a '2 dimensional array' local variable to a class level variable

I have a sub which reads an Excel file (X rows by 5 columns) and make a copy of its data into a String array called 'matrix' in VB.NET. I do need, however, to access of this array in some other subs as well. I was hoping to pass the array to a class level array variable and then retrieve info from that one instead. But I don't how to achieve this goal.
Public Sub ReadFromExcel()
Dim excel As Application = New Application
Try
Dim wrkbook As Workbook = excel.Workbooks.Open(IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location) & _
"EXCELFILE.xls")
Dim sheet As Worksheet = wrkbook.Sheets(1)
Dim cell As Range = sheet.UsedRange
Dim LastRow As Long = 0
sheet.Activate()
With sheet
LastRow = .Cells(.Rows.Count, 1).End(XlDirection.xlUp).Row
End With
Dim matrix(LastRow - 1, 4) As String
For i As Integer = 2 To LastRow
For j As Integer = 1 To 5
matrix(i - 1, j - 1) = cell(i, j).VALUE
Next
Next (i)
wrkbook.Close()
excel.Quit()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
You might try this:
Public Class Sample
Private xlsFileContents(0,0) as String
Public Sub ReadFromExel()
Dim excel As Application = New Application
Try
'all of your code here up to "excel.quit"
'now redim the class array to match your matrix array
'<array>.GetUpperBound gets the integer value of the highest index in that dimension of your array.
'It accepts a zero-bound integer to determine which dimension you are referring to.
ReDim xlsFileContents(matrix.GetUpperBound(0), matrix.GetUpperBound(1))
xlsFileContents = matrix
Catch
'your code here
End Try
End Class
I tried this in a simple console application where I manually entered data into the matrix array, and it worked for me.

Compare values in DGV column with database values and add value to new DGV column

So, Access database has two columns 1st is seller name (SELLER) and second is it's code (CODE). Access database is database with all SELLER CODEs.
DGV is populated from other source and consists of some of CODEs from Access database.
DGV has one column with codes.
I would like to create and populate new column (SELLERNAME) in DGV with SELLER names based on DGV codes and Access database CODEs.
I am going to give an example since it's hard for me to explain this better :
DGV : Column 0, 1st value = 0055, in Access database code 0055 corresponds to the name John
so I would like to put name "John" in DGV Column1, 1st value, nest to "0055" and so on
Here is my code so far :
DataGridView1.Columns.Add("SELLERNAME", "SELLERNAME") '1
Dim cn As OleDb.OleDbConnection
Dim cmd As OleDb.OleDbCommand
Dim odr As OleDb.OleDbDataReader
Dim strSQL As String
cn = New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=w:\SCodes.MDB")
strSQL = "SELECT SELLER, CODE FROM SCBASE"
cn.Open()
cmd = New OleDb.OleDbCommand(strSQL, cn)
odr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
Do While odr.Read
For i As Integer = 0 To DataGridView1.Rows.Count - 1
DataGridView1.Rows(i).Cells(1).Value = odr.GetValue(1).ToString()
Next
Loop
I don't know what to do next after line For i As Integer = 0 To DataGridView1.Rows.Count - 1.
EDIT :
I think I am close but I need help with one line of code :
Using sqlconn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=w:\SCodes.mdb")
Using sqlcmd = New OleDbCommand("Select SELLER, CODE From SCBASE Where CODE = #CODE ", sqlconn)
sqlcmd.Parameters.AddWithValue("#CODE ", DataGridView1.Rows(i).Cells(0).Value) 'HOW TO ADD THIS LINE IN LOOP BELOW
sqlconn.Open()
Dim result = sqlcmd.ExecuteReader()
Do While (result.Read())
For i As Integer = 0 To DataGridView1.Rows.Count - 1
DataGridView1.Rows(i).Cells(1).Value = (result("DOBAVLJAC"))
Next
Loop
End Using
End Using
I had no success with a trial and error. I am trying to put this line sqlcmd.Parameters.AddWithValue("#CODE ", DataGridView1.Rows(i).Cells(0).Value) in loop below but I am getting all sorts of error.
Yes, you are very close. You just need to .Add the Parameter outside the loop and then set its .Value inside the loop like this
Using sqlconn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=w:\SCodes.mdb")
sqlconn.Open()
Using sqlcmd = New OleDbCommand("Select SELLER, CODE From SCBASE Where CODE = ?", sqlconn)
sqlcmd.Parameters.Add("?", OleDbType.VarWChar, 255)
sqlcmd.Prepare()
For i As Integer = 0 To DataGridView1.Rows.Count - 1
sqlcmd.Parameters(0).Value = DataGridView1.Rows(i).Cells(0).Value
Using result = sqlcmd.ExecuteReader()
If result.Read() Then
DataGridView1.Rows(i).Cells(1).Value = result("SELLER")
End If
End Using
Next
End Using
End Using

Search values in datagrid without using data set vb.net

I am inserting values in datagrid from MS-SQL server. I got a text box from which i wanted to perform search operation , but the thing is i haven't used data set.
the question is How do i search for values in datagrid without using data set in vb.net.
Here is my code fr filling up data grid view.
dim i as integer = 0
con.ConnectionString = "Data Source=MY_CONNECTION_STRING "
Dim cmd As New SqlCommand("selct ID, Name From tbl_name where 1=1 Order by Name ASC", con)
con.Open()
' Execute Query
Dim reader As SqlDataReader = cmd.ExecuteReader()
' Try
While reader.Read()
DataGridView10.Rows.Insert(i, New String() {reader(0), reader(1).ToString})
i = i + 1
End While
You can put this in a click event per say...
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
Dim intIndex As Integer = SearchGrid(TextBox1.Text, 0) 'Change the 0 to what column you want to search for
DataGridView1.Rows(intIndex).Selected = True 'This will select the row...'
DataGridView1.CurrentCell = DataGridView1.Rows(intIndex).Cells(0) 'This ensures that the arrow will move if you have row headers visible. In order to select the cell change the zero to the column your searching to match up top
End Sub
Here's the function...
Private Function SearchGrid(ByVal strItem As String, ByVal intColumn As Integer) As Integer
Dim intIndex As Integer = 0
For i As Integer = 0 To DataGridView1.Rows.Count - 1
If DataGridView1.Rows(i).Cells(intColumn).Value.ToString.Contains(strItem) Then 'Or change "Contains" to "Equals"
intIndex = i
Exit For
End If
Next
Return intIndex
End Function
This will work great for you and a great start, happy coding!
P.S. Make sure to change the datagridview name to reflect yours...

Resources