Error In VB.Net code - vb.net

I am getting the error "Format Exception was unhandled at "Do While objectReader.Peek <> -1
" and after. any help would be wonderful.
'Date: Class 03/20/2010
'Program Purpose: When code is executed data will be pulled from a text file
'that contains the named storms to find the average number of storms during the time
'period chosen by the user and to find the most active year. between the range of
'years 1990 and 2008
Option Strict On
Public Class frmHurricane
Private _intNumberOfHuricanes As Integer = 5
Public Shared _intSizeOfArray As Integer = 7
Public Shared _strHuricaneList(_intSizeOfArray) As String
Private _strID(_intSizeOfArray) As String
Private _decYears(_intSizeOfArray) As Decimal
Private _decFinal(_intSizeOfArray) As Decimal
Private _intNumber(_intSizeOfArray) As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'The frmHurricane load event reads the Hurricane text file and
'fill the combotBox object with the data.
'Initialize an instance of the StreamReader Object and declare variable page 675 on the book
Dim objectReader As IO.StreamReader
Dim strLocationAndNameOfFile As String = "C:\huricanes.txt"
Dim intCount As Integer = 0
Dim intFill As Integer
Dim strFileError As String = "The file is not available. Please restart application when available"
'This is where we code the file if it exist.
If IO.File.Exists(strLocationAndNameOfFile) Then
objectReader = IO.File.OpenText(strLocationAndNameOfFile)
'Read the file line by line until the file is complete
Do While objectReader.Peek <> -1
**_strHuricaneList(intCount) = objectReader.ReadLine()
_strID(intCount) = objectReader.ReadLine()
_decYears(intCount) = Convert.ToDecimal(objectReader.ReadLine())
_intNumber(intCount) = Convert.ToInt32(objectReader.ReadLine())
intCount += 1**
Loop
objectReader.Close()
'With any luck the data will go to the Data Box
For intFill = 0 To (_strID.Length - 1)
Me.cboByYear.Items.Add(_strID(intFill))
Next
Else
MsgBox(strFileError, , "Error")
Me.Close()
End If
End Sub

Put a break-point on these lines and step through your code:
_decYears(intCount) = Convert.ToDecimal(objectReader.ReadLine())
_intNumber(intCount) = Convert.ToInt32(objectReader.ReadLine())
Whatever is being returned by ReadLine isn't in the proper decimal or integer format when passed to the converters. You'll need to add some try/catch blocks around the do-while loop operations to handle it gracefully and make sure your data is formatted the way you expected since the wrong parts are being used in this scenario.
Also, each call to ReadLine is returning an entirely new line and the Peek check won't account for those. As long as you can trust your data that's fine.

Instead of using Convert.ToDecimal an Convert.ToInt32, try using Decimal.TryParse() and Int32.TryParse(). If they don't parse, you know your file isn't setup correctly. If they do parse, then you've loaded the value into a variable for your use.
EDIT:
Use it like this.
Dim myDecimal As Decimal
If Decimal.TryParse(objectReader.ReadLine(), myDecimal) Then
'your string successfully parsed. Use myDecimal however you want. It has the parsed value.
Else
'your string is not a decimal. Now that you know that, you can handle this situation here without having to catch an exception.
End If

Related

Error System.InvalidCastException: 'Conversion from string "" to type 'Integer' is not valid.'

I'm trying to open a file that I already add to my TreeView control by clicking it twice, it should appears in a DataGridView control, when a I do it, it shows me the next error:
System.InvalidCastException: 'Conversion from string "Book1.csv" to type 'Integer' is not valid.'
At the Direccion variable, I'm not pretty sure, what it happening. Does any one could orient me? Please.
Public Sub TV_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As
TreeNodeMouseClickEventArgs) Handles TV.NodeMouseDoubleClick
Dim NombreNodo As String = TV.SelectedNode.Text
Dim parseCSV As String
Dim tstSeq() As String
Dim Direccion As String = My.Computer.FileSystem.CurrentDirectory(NombreNodo)
'Dim x As String = Path.GetFullPath(NombreNodo)
'MessageBox.Show(Direccion)
tstSeqDataGrid.Rows.Clear()
Using FileSystem As FileStream = File.Open(Direccion, FileMode.Open, FileAccess.Read)
Dim TestReader As New System.IO.StreamReader(FileSystem)
Do While TestReader.Peek <> -1
parseCSV = TestReader.ReadLine()
tstSeq = parseCSV.Split(",")
tstSeqDataGrid.Rows.Add(tstSeq)
TstSequenceLoaded = True
Loop
TestReader.Close()
FileSystem.Close()
End Using
End Sub
I am assuming that the TreeView is loaded with file names and those files are located in the directory where the code is running. You can see the value of Direccion in the Immediate Window. Using Debug.Print instead of a message box saves you from the embarrassment of forgetting to remove the message box in the production code. The Debug.Print will just be removed.
I returned an array of lines in the file with ReadAllLines. Then loop through the lines as you did.
With Option Strict On (as it should be) you need to add the lower case c following "," so the compiler knows you intend it as a Char not a String.
Public Sub TV_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TV.NodeMouseDoubleClick
Dim Direccion = My.Computer.FileSystem.CurrentDirectory & TV.SelectedNode.Text
Debug.Print(Direccion)
tstSeqDataGrid.Rows.Clear()
Dim lines = File.ReadAllLines(Direccion)
For Each line In lines
Dim tstSeq = line.Split(","c)
tstSeqDataGrid.Rows.Add(tstSeq)
Next
TstSequenceLoaded = True
End Sub

calling a method from another class in vb.net

i have an external class(colorCode.vb) in same project as my main form.vb.
My objective is to send a value as argument as i call a method in the colorCode.vb class, and use the value returned by the method. I don't know if its logically possible . Here i tried this but failed.
in my colorCode.vb Class i have this codes:
Public Sub getValue(ByVal itemCode As Integer)
Dim codeVal() As Integer = {9999, 3034, 3040, 3035}
Dim colorVal As String
For counter As Integer = 0 To codeVal.Count Step 1
If (itemCode = codeVal(counter)) Then
Select Case codeVal(counter)
Case 9999
colorVal = "BRILLIANT WHITE EMULSION"
Case 3034
colorVal = "OFF-WHITE EMULSION"
End Select
End If
Next
End Sub
and in my main form.vb i did this
Private Sub descTextBox_TextChanged(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles descTextBox.TextChanged
Dim colorDesc As colorCode = New colorCode()
Dim itemCode As Integer = Integer.Parse(itemCodeTextBox.Text)
descTextBox.Text = colorDesc.getValue(itemCode)'this line triggers an error.
End Sub
please i need some help here. already running nuts
Please turn on Option Strict. This is a 2 part process. First for the current project - In Solution Explorer double click My Project. Choose Compile on the left. In the Option Strict drop-down select ON. Second for future projects - Go to the Tools Menu -> Options -> Projects and Solutions -> VB Defaults. In the Option Strict drop-down select ON. This will save you from bugs at runtime.
Subs in vb.net do not return values. You need a Function. Instead of looping through the array you can just check if the array contains itemCode and if it does proceed with the Select Case.
Do not put your code in the text changed. It will run every time a character is entered before your user has a chance to enter the entire code. Create a button and use that. Use .TryParse to validate the input. It will return True if valid and fill in the second parameter with the number.
Public Class colorCode
Public Function getValue(ByVal itemCode As Integer) As String
Dim codeVal() As Integer = {9999, 3034, 3040, 3035}
Dim colorVal As String = ""
If codeVal.Contains(itemCode) Then
Select Case itemCode
Case 9999
colorVal = "BRILLIANT WHITE EMULSION"
Case 3034
colorVal = "OFF-WHITE EMULSION"
Case 3040
colorVal = "Blue"
Case 3035
colorVal = "Green"
End Select
Else
colorVal = "No matching color"
End If
Return colorVal
End Function
End Class
And in the form...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim itemCode As Integer
If Integer.TryParse(TextBox1.Text, itemCode) Then
Dim colorDesc As colorCode = New colorCode()
TextBox2.Text = colorDesc.getValue(itemCode)
Else
MessageBox.Show("Please enter a valid number")
End If
End Sub
Add the return statement. You should also check the value of itemCodeTextBox.Text to make sure it's a numeric value before you call colorDesc.getValue otherwise your program may crash if a non-numeric value is entered into the textbox
You are missing the "return" part of your method.
Public Function getValue(ByVal itemCode As Integer) As String
That's what it'll take to declare you're returning a string value, and then you actually return your vale at the end of the method.
Next
return colorVal
End Sub
There are other ways to do this as well as better ways to deal with your "getValue" code, but this should get you running for now. The rest of the improvements are likely a different Question, or even series of Questions. Or you could go to the Code Review stack and get more help there.

Read from text file, store data into corresponding structure every 6 element, and then form an array

The text file contains the following: inside the [], anything inside () was not in the text file, just for clarification
[1(ID)
Jimmy(First name)
Paul (Last name)
78 (marks1)
80 (marks2)
92 (marks3)
2
Ben
James
67
82
73
]
I created a structure that holds student details including their name, id, marks in each subject.
Private Structure StudInfo
Public FName As String
Public LName As String
Public StudentId As Integer
Public ScMark As Integer
Public EnMark As Integer
Public MaMark As Integer
The program needs to read the first six elements in a row, storing each element into the corresponding structure type, then let it become the first element of an array"students()", and then next six elements, let it become the second element of that array. I have no idea how to use loops to do that.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
'create an array that hold student details
Dim Students() As StudInfo
' read from text file
Dim FileNum As Integer = FreeFile()
Dim TempS As String = ""
Dim TempL As String
FileOpen(FileNum, "some.text", OpenMode.Input)
Do Until EOF(FileNum)
TempL = LineInput(FileNum)
TempS = TempL + vbCrLf
Loop
End Sub
Thank you.
You have to use a BinaryReader (which takes a IO.Stream as it's constructor), then you can read the data type you want, into the variable you want.
The problem you will have is the data will not be searchable (ie. you cannot read the 30th record, unless you physically read the first 29, because the strings are of variable length, and therefore the record is variable length), this also applies to modifying a record (you cant make it bigger, because it will overwrite the next record).
The answer is to work with fixed length records, or field offsets or fixed length strings. Then you will have a records of predictable size, and you can determine the amount of records by dividing the file length by the record size.
Hope this helps.
You could try something like this:
Public Class Form1
Private Students As New List(Of StudInfo)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Students.Clear()
Dim fileName = "c:\some folder\directory\someFile.txt"
Using sr As New System.IO.StreamReader(fileName)
Dim value As Integer
Dim strValue As String
While Not sr.EndOfStream
Try
Dim student As New StudInfo
strValue = sr.ReadLine().Trim("[]")
If Integer.TryParse(strValue, value) Then
student.StudentId = value
Else
MessageBox.Show("Error Converting StudentID to Integer")
Exit Sub
End If
student.FName = sr.ReadLine().Trim("[]")
student.LName = sr.ReadLine().Trim("[]")
strValue = sr.ReadLine().Trim("[]")
If Integer.TryParse(strValue, value) Then
student.ScMark = value
Else
MessageBox.Show("Error Converting ScMark to Integer")
Exit Sub
End If
strValue = sr.ReadLine().Trim("[]")
If Integer.TryParse(strValue, value) Then
student.EnMark = value
Else
MessageBox.Show("Error Converting EnMark to Integer")
Exit Sub
End If
strValue = sr.ReadLine().Trim("[]")
If Integer.TryParse(strValue, value) Then
student.MaMark = value
Else
MessageBox.Show("Error Converting MaMark to Integer")
Exit Sub
End If
Students.Add(student)
Catch ex As Exception
MessageBox.Show("Error reading file. All records may not have been created.")
End Try
End While
MessageBox.Show("Done!")
End Using
End Sub
Private Class StudInfo
Public FName As String
Public LName As String
Public StudentId As Integer
Public ScMark As Integer
Public EnMark As Integer
Public MaMark As Integer
End Class
End Class
It depends a bit on the exact format of your text file.
If the file only contains the data for the two students (no brackets or blank lines), then all you need to do is to open the file and read 6 lines, add the data to your structure. and read the next 6 lines. If you have an undetermined number of students in the text file, then you would be better using a List. Other wise you're goiing to have to use extra processing time to Redim the array each time you want to add a student and keep track of the array size an all sorts of messing around.
However. Lets go with the most straightforward answer and assume your data has no brackets or blank lines and that there are only two students.
This code should work just fine. If you have a different definite number of students, then you will need to change the size of the Students array.
I'm also assuming that the data is correctly formatted and there are no non-numeric characters are in the lines where there shouldn't be.
Private Sub ReadStudentInfo()
'create an array that hold student details
Dim Students(2) As StudInfo
Dim index As Integer = 0
' read from text file
Dim datafile As New StreamReader("some.text")
Do Until datafile.EndOfStream
Dim tempStudent As StudInfo
With tempStudent
Integer.TryParse(datafile.ReadLine, .StudentId)
.FName = datafile.ReadLine
.LName = datafile.ReadLine
Integer.TryParse(datafile.ReadLine, .ScMark)
Integer.TryParse(datafile.ReadLine, .EnMark)
Integer.TryParse(datafile.ReadLine, .MaMark)
End With
Students(index) = tempStudent
index = index + 1
Loop
End Sub
If your text file does contain blank lines, just insert
datafile.ReadLine()
between each line of data - like this
Integer.TryParse(datafile.ReadLine, .ScMark)
datafile.ReadLine()
Integer.TryParse(datafile.ReadLine, .EnMark)
If you have the brackets in your text file, then you'll need to add extra code to remove them.

check for uniqueness of employee id number

Cant seem to figure out how to check for a unique Employee id Number. I know the validation has to go in the form load, just not sure how to go about it.
Public Class Form1
Dim filename As String
Dim dataFile As System.IO.File
Dim dataWrite As System.IO.StreamWriter
''LOADING AND WRITE TO TEXT DOCUMENT
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'asks user for file name
filename = InputBox("Enter output file name")
If IO.File.Exists(filename) Then
dataWrite = IO.File.AppendText(filename)
Else
MessageBox.Show("filename does not exist")
filename = InputBox("Enter output file name")
dataWrite = IO.File.CreateText(filename)
End If
cboDepart.Items.Add("Accounting")
cboDepart.Items.Add("Administration")
cboDepart.Items.Add("Marketing")
cboDepart.Items.Add("MIS")
cboDepart.Items.Add("Sales")
End Sub
'------
Public EMPLOYEEIDS As String
Dim employeeID1 As ServerData()
Dim employeeID2 As ServerData()
Dim reader As String = My.Computer.FileSystem.ReadAllText("servers.lst")
Dim s() As String
Dim Totalemployeeids As String = CStr(reader.Length)
Dim x As Integer = 0
Dim myArray As String() = reader.Split("|"c)
For x = 1 To Totalemployeeids
employeeID1(x).ServerName = myArray(0)
employeeID2(x).IDname = myarray(0)
Form1_load.ListBox1.Items.Add(Servers(x).ServerName)
x += 1
Next
Structure ServerData
End Structure
End Class
You usually do not insert a unique ID from the client side. Instead, it is inserted automatically by the database server. There is a way to retrieve an inserted ID back, if you need it for display (can also act as a confirmation that a record was successfully inserted):
SELECT SCOPE_IDENTITY()
An example is shown in this answer:
How to get last inserted id? (C#)
On the client side, you need to implement insertion of everything but the ID, in this case you don't need to check for uniqueness. There may be other validation issues upon commit though (unique key violation, data type mismatch) - make sure you catch exceptions and display them to the user as appropriate.

Convert.ToInt16 vb.net

I am using the following code as a learning progress for myself:
Public Class Form1
Private Sub BtnAntwoord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAntwoord.Click
Dim testNummer As Integer
Dim uitkomst As Single
Dim waarde1 As Integer = Convert.ToInt16(txtNummers1)
Dim waarde2 As Integer = Convert.ToInt16(txtNummers2)
uitkomst = (waarde1 * waarde2)
testNummer = Convert.ToString(uitkomst)
MsgBox(testNummer)
End Sub
End Class
What I am trying to accomplish is a small window with 2 textfields and a button wich, when pressed, presents the answer to the question "waarde 1 * waarde2" in a popup window.
When I execute this code, the following error is presented:
InvalidCastException was unhandled
and the line "waarde1 As Integer = Convert.ToInt16(txtNummers1)" is highlited
I am not looking for an answer per se, just the understanding as to why this does not work, seeing as I am extremely new to vb.net and I am trying to expand my knowledge of the language.
if txtNummers1 and txtNummers2 are textboxes then you should write
Dim waarde1 As Short = Convert.ToInt16(txtNummers1.Text)
Dim waarde2 As Short = Convert.ToInt16(txtNummers2.Text)
You can't convert a TextBox type to an Integer type. You convert the Text (a string type) property of a TextBox to an Integer supposing that this property contains in effect a number.
Also, why convert to a 16bit numeric type and then assign the result to a 32bit type?
A better approach is the following
Dim waarde1 As Short
Dim testNum as String = txtNummers1.Text
if Int16.TryParse(testNum, waarde1) Then
Console.WriteLine("It is a 16 bit number " + waarde1.ToString)
else
Console.WriteLine("Not a 16 bit number " + waarde1.ToString)
Here MSDN on TryParse