System.InvalidCastException Error on Specific Database Column - vb.net

So I am currently trying to read values from an access database and write them to an array of labels in VB.NET. This is for a little quiz program I am making where the previous scores they got in the 14 categories are written to the screen. The issue I am having is when writing to Label7 (column 20 in the database) I get the error 'specified cast is not valid'. I have checked my txt file and database thoroughly to see what is wrong with this specific value and I cannot see a difference. It is still written as a 32 bit integer like all the others, for which the code has no issues.
Dim LabelArray() As Control = {Label1, Label2, Label3, Label4, Label5, Label6, Label7, Label8, Label9, Label10, Label11, Label12, Label13, Label14}
Dim x As Integer = 2
'starting at the the 3rd column in the database
Dim QArray(13) As String 'reading names of the columns from a txt file into the array
FileOpen(1, Application.StartupPath & "\sqlscores.txt", OpenMode.Input) 'load files
Dim j As Integer = 0
Do While Not EOF(1)
QArray(j) = LineInput(1) 'input into array
j = j + 1
Loop
FileClose(1)
Dim tbl As New DataTable
Dim conn1 = MyConnection2() 'connects to microsoft access database
Dim temp As String
For i = 0 To 13 'for each item in the array
Dim command = New OleDbCommand("Select * From Users Where Username='" & usernames & "' and " & QArray(i) & " >= 0", conn) 'look for that column in the database where their username and score is more than 0
Dim reader = command.ExecuteReader()
While reader.Read()
temp = (reader.GetInt32(x)).ToString 'read value and convert to string
LabelArray(i).Text = temp 'assign temp to label text
x = x + 3 'increment by 3 as correct column is in every third column
End While
Next i
Below is a screenshot of the database (the specific column) that is causing the issue.
The first field is the section that is playing up
As you can see, it has the same properties as a section that does work compared to a section that does
I have tried deleting the column and adding it again, which makes no difference. I have also checked the label (and re-added it) in VB to see if that was the issue, which it was not. It appears to think that the value in that column, which is just currently the 32 bit integer "4" cannot be converted to a string. I am only interested in the practice scores in the db which can be seen in the column names.
Am I missing something obvious?

Related

Search Through Specific Set of Lines and Output Data?

I've been struggling with this for a while now, and after extensive searching, I still have yet to find an answer.
In my Visual Basic class, I have a program where I have to get text from a text file (songs.txt), display the genres in a list box, and display corresponding songs in a combo box after a genre is displayed.
Currently, this is my code.
' Variables
Dim strFilePath As String = "E:\Advanced VB\DJPlayList\DJPlayList\songs.txt"
Dim strFileError As String = "File not found. Please try again."
Dim strFileErrorTitle As String = "File Error"
Dim objReader As IO.StreamReader
Dim intCount As Integer = 0
Dim strSongGenre(intCount) As String
Dim i As Integer = 0
' Finding the file
If IO.File.Exists(strFilePath) Then
' Opening the text file
objReader = IO.File.OpenText(strFilePath)
Do Until objReader.Peek = -1
ReDim Preserve strSongGenre(intCount)
strSongGenre(intCount) = objReader.ReadLine
cboMusicGenre.Items.Add(strSongGenre(intCount))
intCount += 1
Loop
Else
MsgBox(strFileError, , strFileErrorTitle)
Close()
End If
This adds all the information from the text file into the array and loads it to the listbox, but I'm stuck at how to output the genre's specifically and the corresponding songs with it.
The text file looks as follows:
All You Need is Love-Beatles 'Song Name
Rock 'Song Genre
4.25 'Song Time
What Hurts the Most-Rascal Flatts
Country
5.25
Touch it-Busta Rhymes
Rap
5.46
My Girl-Temptations
R&B
4.35
What you know?-T.I.
Rap
4.30
How do I specifically get the genre's and the song titles? Thank you for the help in advance
So what is actually happening is that your code is reading every line and storing them all in your ComboBox.
Probably the easiest thing to do at this level would be to create 2 extra temporary string variables and instead of reading 1 line for each iteration of the loop, read the three lines that are related to each other like this
tempName= objReader.ReadLine
strSongGenre(intCount) = objReader.ReadLine
tempDuration = objReader.ReadLine
If you don't want to use the Name and Duration of the song then do nothing with them and they'll be overwritten on the next iteration of the loop
So your final code should look like this
Do Until objReader.Peek = -1
Dim tempName,tempDuration as string
ReDim Preserve strSongGenre(intCount)
tempName= objReader.ReadLine
strSongGenre(intCount) = objReader.ReadLine
tempDuration = objReader.ReadLine
cboMusicGenre.Items.Add(strSongGenre(intCount))
intCount += 1
Loop

Connecting to Access from Excel, then create table from txt file

I am writing VBA code for an Excel workbook. I would like to be able to open a connection with an Access database, and then import a txt file (pipe delimited) and create a new table in the database from this txt file. I have searched everywhere but to no avail. I have only been able to find VBA code that will accomplish this from within Access itself, rather than from Excel. Please help! Thank you
Google "Open access database from excel VBA" and you'll find lots of resources. Here's the general idea though:
Dim db As Access.Application
Public Sub OpenDB()
Set db = New Access.Application
db.OpenCurrentDatabase "C:\My Documents\db2.mdb"
db.Application.Visible = True
End Sub
You can also use a data access technology like ODBC or ADODB. I'd look into those if you're planning more extensive functionality. Good luck!
I had to do this exact same problem. You have a large problem presented in a small question here, but here is my solution to the hardest hurdle. You first parse each line of the text file into an array:
Function ParseLineEntry(LineEntry As String) As Variant
'Take a text file string and parse it into individual elements in an array.
Dim NumFields As Integer, LastFieldStart As Integer
Dim LineFieldArray() As Variant
Dim i As Long, j As Long
'Determine how many delimitations there are. My data always had the format
'data1|data2|data3|...|dataN|, so there was always at least one field.
NumFields = 0
For I = 1 To Len(LineEntry)
If Mid(LineEntry, i, 1) = "|" Then NumFields = NumFields + 1
Next i
ReDim LineFieldArray(1 To NumFields)
'Parse out each element from the string and assign it into the appropriate array value
LastFieldStart = 1
For i = 1 to NumFields
For j = LastFieldStart To Len(LineEntry)
If Mid(LineEntry, j , 1) = "|" Then
LineFieldArray(i) = Mid(LineEntry, LastFieldStart, j - LastFieldStart)
LastFieldStart = j + 1
Exit For
End If
Next j
Next i
ParseLineEntry = LineFieldArray
End Function
You then use another routine to add the connection in (I am using ADODB). My format for entries was TableName|Field1Value|Field2Value|...|FieldNValue|:
Dim InsertDataCommand as String
'LineArray = array populated by ParseLineEntry
InsertDataCommand = "INSERT INTO " & LineArray(1) & " VALUES ("
For i = 2 To UBound(LineArray)
If i = UBound(LineArray) Then
InsertDataCommand = InsertDataCommand & "'" & LineArray(i) & "'" & ")"
Else
InsertDataCommand = InsertDataCommand & LineArray(i) & ", "
End If
Next i
Just keep in mind that you will have to build some case handling into this. For example, if you have an empty value (e.g. Val1|Val2||Val4) and it is a string, you can enter "" which will already be in the ParseLineEntry array. However, if you are entering this into a number column it will fail on you, you have to insert "Null" instead inside the string. Also, if you are adding any strings with an apostrophe, you will have to change it to a ''. In sum, I had to go through my lines character by character to find these issues, but the concept is demonstrated.
I built the table programmatically too using the same parsing function, but of this .csv format: TableName|Field1Name|Field1Type|Field1Size|...|.
Again, this is a big problem you are tackling, but I hope this answer helps you with the less straight forward parts.

consolidate items in datagridview visual basic.net 2008

Dim X As String
Dim V, Q, Y As Double
DGV.ColumnCount = 3
con.Open()
cmd = New SqlCommand("select Name,Price from Items where Name ='" & ListItems.SelectedItem & "'", con)
DR = cmd.ExecuteReader
While DR.Read()
' Q = Val(Qty.Text)
X = (DR("Name").ToString())
Y = Val((DR("Price").ToString()))
V = Q * Y
Dim row As String() = New String() {Q, X, V}
DGV.Rows.Add(row)
i am using visual basic.net and if i have similar items in datagridview as below
for example
1 hot dog 5 $
2 hot dog 10 $
5 hot dog 20 $
how can we consolidate them in one line as
8 hot dog 40 $
So you have columns "Name" and "Price". From your text under your code I see that name is going to be "5 hotdog" and Price to be "20$". I don't know if they are formatted that way, but I am going to assume so.
So what you want to do first is calculate the values you want in your "total" row. Since you have "hot dog" or a string after your initial number, we want to just get that number for each value. We'll loop through, evaluate that number, and sum it up. We'll do the same with the price column, but instead we'll remove the "$" in the string. Again, I'm doing a lot of assuming here.
Dim nameTotal As Integer = 0
Dim priceTotal As Integer = 0
'loop through each row of the DGV
For Each row As DataRow In DGV.Rows
'evaluate value in current row
Dim str_nameValue As String = row.Item("Name").ToString()
str_nameValue = str_nameValue.Remove(" hot dog")
'or if there are other string attached, remove those from the str_nameValue here to get an integer
'processing stringcode here...
'add to name total
nameTotal += CInt(str_nameValue)
'do the same for the other column
Dim str_priceValue As String = row.Item("Price").ToString()
str_priceValue = str_priceValue.Remove("$")
'sum
priceTotal += CInt(str_priceValue)
Next
'for loop is finished, add a new row with the values
'add row to table with a parameter of total values, and an empty one for the second column
DGV.Rows.Add(nameTotal & " hot dog " & priceTotal & "$", " ")
You should be in charge of formatting your strings to meet your needs.

Deleting items in listview if data already exists

i'am populating my listview and when i click the command button the data will be saved to database but if a data already exists in the database the data will be removed from my listview. my problem is that when the data already exists yes it removes the data but it always leave 1 data in my listview. for example i populate my list with 10 data that already exist in database and when i press the command button since its already in the database it will delete the 10 data in my listview what happens is it leaves the last data in the listview
Dim ListOfExistingItem As List(Of Integer) = New List(Of Integer)
Try
locconn.Open()
For x = 0 To ListView2.Items.Count - 1
Dim a As String = ListView2.Items.Item(x).Text
a = ListView2.Items.Item(x).Text
Dim command As New SqlCommand
Dim TMP_SQL_VAL As String = "select count([Check-Out]) from tbl_list1 where barcode = '" + a + "'"
command = New SqlCommand(TMP_SQL_VAL, locconn)
Dim READER As SqlDataReader
READER = command.ExecuteReader()
READER.Read()
If READER(0) = 0 Then
MsgBox("Barcode: " & a & "is still Inside", MsgBoxStyle.Exclamation)
TextBox4.Text = Nothing
ListOfExistingItem.Add(x)
READER.Close()
End If
READER.Close()
Next
If Not IsNothing(ListOfExistingItem) Then
For Each x As Integer In ListOfExistingItem
If Not x >= ListView2.Items.Count - 1 Then
ListView2.Items.RemoveAt(x)
End If
Next
End If
I think your problem is a little more complex than an off-by-1 error.
When you loop through ListOfExistingItem, which should contains the indexes of items to be removed, you are removing items from ListView2.
The problem with this is that by removing an item from the list, you are changing the position of all items after it.
For example, take the list { a, b, c }. The index of 'a' is 0, 'b' is 1, and 'c' is 2.
Now, if you were to say list.RemoveAt(1) then it would remove 'b'. This will then cause the index of 'c' to change to 1 instead of two. Then when you go and try to remove 'c', it wont be in the same place.
For an quick fix, try adding 'ListOfExistingItem.Reverse' before the last 'for' loop:
Call ListOfExistingItem.Reverse()
For Each x As Integer In ListOfExistingItem
If Not x >= ListView2.Items.Count - 1 Then
ListView2.Items.RemoveAt(x)
End If
Next
This way, you will start with the last item in the list and work your way backwards, which should avoid the problem.

Adding two column values to listbox in vb.net

I have a table named users which has the following columns in it
User_id,user_name,user_pwd,First_Name,Middle_Name,Last_Name and user_type.
I have dataset named dst and created a table called user in the dataset. Now I want to populate listbox with user_Name, First_Name, Last_name of each and every row in the table user.
I am able to add one column value at a time but not getting how to add multiple column values of each row to listbox
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(row("User_Name"))
Next
Above code works perfectly but I also want to add First_name as well as last_name to the list box at the same time.
Use same approach as you have, but put all values you want in one string.
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
Dim sItemTemp as String
sItemTemp = String.Format("{0},{1},{2}", row("User_Name"), row("First_Name"), row("Last_Name"))
lstUsers.Items.Add(sItemTemp)
Next
String.Format() function will call .ToString() on all parameters.
In this case if row(ColumnName) is NULL value then .ToString() return just empty string
You have 2 choices:
Using the ListBox:
To use the ListBox, set the font to one that is fixed width like courier new (so that the columns line up), and add the items like this:
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(RPAD(row("User_Name"),16) & RPAD(row("First_Name"),16) & RPAD(row("Last_Name"),16))
Next
The RPAD function is defined like this:
Function RPAD(a As Object, LENGTH As Object) As String
Dim X As Object
X = Len(a)
If (X >= LENGTH) Then
RPAD = a : Exit Function
End If
RPAD = a & Space(LENGTH - X)
End Function
Adjust the LENGTH argument as desired in your case. Add one more for at least one space. This solution is less than ideal because you have to hard-code the column widths.
Use a DataGridView control instead of a ListBox. This is really the best option, and if you need, you can even have it behave like a ListBox by setting the option to select the full row and setting CellBorderStyle to SingleHorizontal. Define the columns in the designer, but no need to set the widths - the columns can auto-size, and I set that option in the code below. if you still prefer to set the widths, comment out the AutoSizeColumnsMode line.
The code to set up the grid and add the rows goes like this:
g.Rows.Clear() ' some of the below options are also cleared, so we set them again
g.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.AllCells
g.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal
g.SelectionMode = DataGridViewSelectionMode.FullRowSelect
g.AllowUserToAddRows = False
g.AllowUserToDeleteRows = False
g.AllowUserToOrderColumns = True
For Each row As DataRow In dt.Rows
g.Rows.Add(row("User_Name"), row("First_Name"), row("Last_Name"))
Next
You might solved your problem by now but other users like me might have issue with it.
Above answers given worked for me even but I found a same answer in a simple way according to what I want..
cmd = New SqlCommand("select User_Name, First_Name, Last_Name from User")
Dim dr As SqlDataReader = cmd.ExecuteReader(YourConnectionString)
If dr.HasRows Then
Do While dr.Read
lst.Items.Add(dr.Item(0).ToString & " " & dr.Item(1).ToString & " " & dr.Item(2).ToString)
Loop
End If
This worked for me, maybe wrong way but I found it simple :)
May I suggest you use a ListView control instead of Listbox?
If you make the switch, here's a sample subroutine you could use to fill it up with the data you said you want. Adapt it the way you like; there's much room for improvement but you get the general idea:
Public Sub FillUserListView(lstUsers As ListView, Dst As DataSet)
Dim columnsWanted As List(Of String) = New List(Of String)({"User_Name", "First_Name", "Last_Name"})
Dim dt As DataTable = Dst.Tables("user")
Dim columns As Integer = 0
Dim totalColumns = 0
Dim rows As Integer = dt.Rows.Count
'Set the column titles
For Each column As DataColumn In dt.Columns
If columnsWanted.Contains(column.ColumnName) Then
lstUsers.Columns.Add(column.ColumnName)
columns = columns + 1
End If
totalColumns = totalColumns + 1
Next
Dim rowObjects(columns - 1) As ListViewItem
Dim actualColumn As Integer = 0
'Load up the rows of actual data into the ListView
For row = 0 To rows - 1
For column = 0 To totalColumns - 1
If columnsWanted.Contains(dt.Columns(column).ColumnName) Then
If actualColumn = 0 Then
rowObjects(row) = New ListViewItem()
rowObjects(row).SubItems(actualColumn).Text = dt.Rows(row).Item(actualColumn)
Else
rowObjects(row).SubItems.Add(dt.Rows(row).Item(actualColumn))
End If
lstUsers.Columns.Item(actualColumn).Width = -2 'Set auto-width
actualColumn = actualColumn + 1
End If
Next
lstUsers.Items.Add(rowObjects(row))
Next
lstUsers.View = View.Details 'Causes each item to appear on a separate line arranged in columns
End Sub