I need help, I don't know why the array for the quantity in my input file strArr(1) having an error that says that the input string was not in a correct format.
Dim objReader As IO.StreamReader
Dim objWriter As New IO.StreamWriter("C:\Users\user\Desktop\StationeryFolder\output.txt")
Dim strLine As String
Dim strName As String
Dim intQuantity As Integer
Dim intTotal As Integer
Dim strArr() As String
If IO.File.Exists("C:\Users\user\Desktop\StationeryFolder\input.txt") = True Then
objReader = IO.File.OpenText("C:\Users\user\Desktop\StationeryFolder\input.txt")
Else
MsgBox("File is not exist")
Close()
End If
Do While objReader.Peek <> -1
strLine = objReader.ReadLine()
strArr = strLine.Split(" ")
strName = strArr(0)
intQuantity = Convert.ToInt32(strArr(1)) //this is where the error occurs
intTotal = intTotal + intQuantity
lstDisplay.Items.Add(strName & " " & intQuantity.ToString())
objWriter.WriteLine(strName & " " & intQuantity.ToString())
Loop
lstDisplay.Items.Add("Total Quantity of Stationeries are: " & intTotal.ToString())
objWriter.WriteLine("Total Quantity of Stationeries are: " & intTotal.ToString())
objReader.Close()
objWriter.Close()
Inside the input file:
Markers
15
Pens
25
I used the .net File class instead of streams. ReadAllLine returns an array of the lines in the file. I used a StringBuilder which is mutable (changeable) unlike a String. Saves the code from creating and throwing away several strings. I have used interpolated strings indicated by the $ before the quotes. This allows inserting variables directly into the string surrounded by braces.
Private Sub OPCode()
Dim inputPath = "C:\Users\user\Desktop\StationeryFolder\input.txt"
If Not IO.File.Exists(inputPath) Then
MsgBox("File does not exist")
Close()
End If
Dim lines = File.ReadAllLines(inputPath)
Dim total As Integer
Dim sb As New StringBuilder
For i = 0 To lines.Length - 2 Step 2
lstDisplay.Items.Add($"{lines(i)} {lines(i + 1)}")
sb.AppendLine($"{lines(i)} {lines(i + 1)}")
total += CInt(lines(i + 1))
Next
lstDisplay.Items.Add($"Total Quantity of Stationeries are: {total}")
sb.AppendLine($"Total Quantity of Stationeries are: {total}")
File.WriteAllText("C:\Users\user\Desktop\StationeryFolder\output.txt", sb.ToString)
End Sub
So I get this error when trying to run my code "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'" I am not exactly sure what the issue is. The user should be able to enter 3 assignment grades and then see the averages
I marked the line where I get the error with 'THIS IS THE ERROR'
Public Class GradeBook
Dim grade(9, 2) As Integer 'Store 10 student grades on 3 tests'
Dim studentCount As Integer = 0 'Number of students entered'
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
End Sub
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
grade(studentCount, 0) = Convert.ToInt32(Assignment1TextBox.Text)
grade(studentCount, 1) = Convert.ToInt32(Assignment2TextBox.Text)
grade(studentCount, 2) = Convert.ToInt32(Assignment3TextBox.Text)
Dim output As String = "Student " & studentCount & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(studentCount, column))
Else
output &= vbTab & grade(studentCount, column)
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
End Select
Return output
End Function
Function CalculateStudentAverage(ByVal row As Integer) As String
Dim gradeTotal As Integer = 0
For column = 0 To grade.GetUpperBound(1)
gradeTotal += grade(row, column) 'THIS IS THE ERROR'
Next
Dim studentAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
studentAverage = LetterGrade(gradeTotal / (grade.GetUpperBound(1) + 1))
Else
studentAverage = String.Format("{0:F}", (gradeTotal / grade.GetUpperBound(1) + 1))
End If
Return studentAverage
End Function
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For row = 0 To studentCount - 1
For column = 0 To grade.GetUpperBound(1)
classTotal += grade(row, column)
Next
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = LetterGrade(classTotal / (studentCount * (grade.GetUpperBound(1) + 1)))
Else
classAverage = String.Format("{0:F}", (classTotal / (studentCount * (grade.GetUpperBound(1) + 1))))
End If
Return classAverage
End Function
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For row = 0 To studentCount - 1
Dim output As String = "Student " & row & vbTab
For column = 0 To grade.GetUpperBound(1)
If LetterRadioButton.Checked = True Then
output &= vbTab & LetterGrade(grade(row, column))
Else
output &= vbTab & (grade(row, column))
End If
Next
output &= vbTab & CalculateStudentAverage(studentCount)
GradeListBox.Items.Add(output)
studentCount += 1
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
If studentCount = grade.GetUpperBound(0) + 1 Then
InputGradeGroupBox.Enabled = False
End If
Next
End Sub
End Class
To be honest, I suspect you're going about it in a way not suited to OOP. Using arrays for multiple peices of data is prone to error and harder to maintain later.
Lets have a think about how you want to represent your data. You have a bunch of students. In a more complete example each student would have a name, personal details such as address, a list of the courses they're taking and for each course, a list of assignments and scores for each assignment which can also be represented as a grade.
So in essence you have a class called Student and the various bits of information are properties of that student.
Finally you have a list of these students
In your code, you simply have a student number and three assignment scores.
Your basic student class should have the properties of Number, Test1Score, Test2Score and Test3Score. You would also want to be able to get the grade from each score, the average of all the scores and the average of all the grades.
The code below defines the Student class with that information in mind
Friend Class Student
Public Property Number As Integer
Public Property Test1Score As Integer
Public Property Test2Score As Integer
Public Property Test3Score As Integer
Public Function Test1Grade() As String
Return LetterGrade(Test1Score)
End Function
Public Function Test2Grade() As String
Return LetterGrade(Test2Score)
End Function
Public Function Test3Grade() As String
Return LetterGrade(Test3Score)
End Function
Friend Shared Function LetterGrade(ByVal grade As Double) As String
Dim output As String = ""
Select Case grade
Case Is >= 90
output = "A"
Case Is >= 80
output = "B"
Case Is >= 70
output = "C"
Case Is >= 60
output = "D"
Case Is >= 50
output = "E"
Case Else
output = "F"
End Select
Return output
End Function
Friend Function AverageScore() As Double
Return (Test1Score + Test2Score + Test3Score) / 3
End Function
Friend Function AverageGrade() As String
Dim avgscore As Double = AverageScore()
Return LetterGrade(avgscore)
End Function
End Class
The function LetterGrade is Shared so that it can be used in your main form to calculate the average grade for the entire class.
OK Next think about how you want your program to work. You'll need a list of students, so at the beginning of your form class , you'll need this..
Public Class Form1
Private Students As New List(Of Student)
This way, instead of trying to keep track of your variable studentCount you can just use the .Count property of the List e.g Students.Count. You wont need to any adding to it as the Students list keeps track of it automatically.
Next, you'll want the function that calculates the average score/grade of the class..
Function CalculateClassAverage() As String
Dim classTotal As Integer = 0
For Each tmpStudent As Student In Students
With tmpStudent
classTotal += .Test1Score + .Test2Score + .Test3Score
End With
Next
Dim classAverage As String = String.Empty
If LetterRadioButton.Checked = True Then
classAverage = Student.LetterGrade((classTotal / Students.Count) / 3)
Else
classAverage = String.Format("{0:F}", (classTotal / (Students.Count)) / 3)
End If
Return classAverage
End Function
As you can see, there are a number of differences here because of the way your data is stored, but you should be able to follow it. One difference is the With statement, this allows you to save on typing. inside the With.. End With block, instead of typing tmpstudent.Test1Score etc, you can just type .Test1Score
The other thing of note is this line ..
classAverage = Student.LetterGrade( ... etc
You may think that there has been no declaration of a variable called Student. There IS a class, but not a variable. What this is actually doing is calling the LetterGrade function that is shared in the Student class definition.. Have a look at shared functions.
Next is the code to display the information in the ListBox. I haven't changed the name even though it is misleading btw.
Sub displayBarChart()
GradeListBox.Items.Clear()
GradeListBox.Items.Add(vbTab & vbTab & "Test 1" & vbTab & "Test 2" & vbTab & "Test 3" & vbTab & "Average")
For Each tmpstudent As Student In Students
Dim output As String = "Student " & tmpstudent.Number & vbTab
With tmpstudent
If LetterRadioButton.Checked = True Then
output &= .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade & vbTab & .AverageGrade
Else
output &= .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score & vbTab & .AverageScore
End If
End With
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
Next
If Students.Count = 10 Then
InputGradeGroupBox.Enabled = False
End If
End Sub
More use of the With..End With statements again, but the rest should be straighforward to follow.
A little extra bit of code.. When you click on the LetterRadioButton, the data in the listBox and ClassAveragelabel are refreshed with the appropriate letters/grades
Private Sub LetterRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles LetterRadioButton.CheckedChanged
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
End Sub
Finally, to bring it all together, you have the code for the button click..
Private Sub SubmitButton_Click(sender As Object, e As EventArgs) Handles SubmitButton.Click
Dim tmpStudent As New Student With {.Number = Students.Count + 1,
.Test1Score = Convert.ToDouble(Assignment1TextBox.Text),
.Test2Score = Convert.ToDouble(Assignment2TextBox.Text),
.Test3Score = Convert.ToDouble(Assignment3TextBox.Text)}
Dim output As String = "Student " & tmpStudent.Number & vbTab
With tmpStudent
If LetterRadioButton.Checked = True Then
output &= vbTab & .Test1Grade & vbTab & .Test2Grade & vbTab & .Test3Grade
Else
output &= vbTab & .Test1Score & vbTab & .Test2Score & vbTab & .Test3Score
End If
End With
Students.Add(tmpStudent)
If LetterRadioButton.Checked Then
output &= vbTab & tmpStudent.AverageGrade
Else
output &= vbTab & tmpStudent.AverageScore
End If
GradeListBox.Items.Add(output)
AverageLabel.Text = CalculateClassAverage()
displayBarChart()
Assignment1TextBox.Clear()
Assignment2TextBox.Clear()
Assignment3TextBox.Clear()
End Sub
Hopefully in addition to my comment to your question, this provides a slightly better insight of OOP.
I have problem with this - I try to send broadcast SMS using AT Commands in my system. After that the SMS content will be stored in my database. My store content SMS function works well. I can store all my SMS content that I send, but the send function just sends message to my first data on my datagridview.
Please help me to deal with this - I posted my code below
Private Sub ButtonKirim_Click(sender As Object, e As EventArgs) Handles ButtonKirim.Click
Dim noPel As String
Dim isiPesan As String = ""
Dim tgl As Date = Now.Date
Dim strReplace(2) As String
Dim strIsi(2) As String
Dim tagBulan As String = "<bulan>"
Dim tagtagihan As String = "<tagihan>"
Dim tagLokasi As String = "<lokasi>"
Dim pesanKirim As String = ""
My.Settings.SettingPesan = RichTextBoxPesan.Text
My.Settings.Save()
'Label4.Text = isiPesan
For pelanggan As Integer = 0 To DataGridViewKirimPesan.RowCount - 1
'mengirim pesan/send message
noPel = DataGridViewKirimPesan.Rows(pelanggan).Cells(3).Value()
strReplace(0) = tagBulan
strReplace(1) = tagtagihan
strReplace(2) = tagLokasi
strIsi(0) = DataGridViewKirimPesan.Rows(pelanggan).Cells(4).Value
strIsi(1) = DataGridViewKirimPesan.Rows(pelanggan).Cells(5).Value
strIsi(2) = DataGridViewKirimPesan.Rows(pelanggan).Cells(6).Value
isiPesan = RichTextBoxPesan.Text
For i As Integer = LBound(strReplace) To UBound(strReplace)
isiPesan = isiPesan.Replace(strReplace(i), strIsi(i))
Next
SendMessage(noPel, isiPesan)
''menyimpan pesan keluar ke sms_terkirim/this query store my content SMS to table
Dim sqlSmsKeluar As String = "INSERT INTO sms_terkirim (`tgl_sms`,`id_pelanggan`, `isi_sms`) VALUES ( NOW()," & DataGridViewKirimPesan.Rows(pelanggan).Cells(0).Value & " , '" & isiPesan & "');"
cudMethod(sqlSmsKeluar)
MsgBox(sqlSmsKeluar)
'ProgressBarKirimPesan.Increment(1)
Next
'MsgBox("Pesan Sukses Terkirim")
' Catch ex As Exception
' MsgBox("Pesan Gagal Terkirim" + ex.Message)
'End Try
' End If
End Sub
and this code is AT Command to send message
Public Sub SendMessage(ByVal NomorPelanggan As String, ByVal IsiPesan As String)
If SerialModem.IsOpen() Then
With SerialModem
.Write("AT" & vbCrLf)
Threading.Thread.Sleep(100)
.Write("AT+CMGF=1" & vbCrLf)
Threading.Thread.Sleep(100)
.Write("AT+CMGS=" & Chr(34) & NomorPelanggan & Chr(34) & vbCrLf)
Threading.Thread.Sleep(100)
.Write(IsiPesan & vbCrLf & Chr(26))
Threading.Thread.Sleep(100)
End With
Else
MsgBox("Modem Belum Tersambung")
End If
End Sub
I'm new at Visual Basic, doing an assignment right now. This is the code I have
Sub Main()
Console.Write("Please let me know your nickname: ")
Dim name As String = Console.ReadLine()
Console.WriteLine("Thank you " + name + "!")
Console.WriteLine()
Console.Write("How many litres " + name + "<only whole litres please>? ")
Dim litres As Integer = Console.ReadLine()
Console.Write("Premium quality? <y/n>: ")
Dim ans As Char = Console.ReadLine()
Dim prem As Boolean
If ans = "y" Then
prem = True
ElseIf ans = "n" Then
prem = False
End If
Console.WriteLine()
Console.WriteLine("WELCOME TO APU'S GAS STATION")
Console.Write("Quality: ")
If prem = True Then
Console.Write("Premium")
Else : Console.Write("Regular")
End If
Dim price As Double = 12.44
Console.WriteLine("Quantity <l>: " + litres)
Console.WriteLine("Price per l: " + price)
Console.WriteLine("Sum to pay: " + litres * price)
Console.ReadLine()
End Sub
At runtime I can input all data no problem, but then I get an error that I can roughly translate to "invalid cast of the string "Quantity : " to type 'Double'.
I'm not so sure what is going on, would appreciate pointers.
to avoid this problem you can use
Console.WriteLine("Quantity <l>: " + litres.ToString)
Or you can use
Console.WriteLine("Quantity <l>: " + CStr(price))
I fixed your code, this should work :
Sub Main()
Console.Write("Please let me know your nickname: ")
Dim name As String = Console.ReadLine()
Console.WriteLine("Thank you " & name & "!")
Console.WriteLine()
Console.Write("How many litres " & name & "<only whole litres please>? ")
Dim litres As Integer = Console.ReadLine()
Console.Write("Premium quality? <y/n>: ")
Dim ans As Char = Console.ReadLine()
Dim prem As Boolean
If ans = "y" Then
prem = True
ElseIf ans = "n" Then
prem = False
End If
Console.WriteLine()
Console.WriteLine("WELCOME TO APU'S GAS STATION")
Console.Write("Quality: ")
If prem = True Then
Console.Write("Premium")
Else : Console.Write("Regular")
End If
Dim price As Double = 12.44
Console.WriteLine("Quantity <l>: " & litres)
Console.WriteLine("Price per l: " & price)
Console.WriteLine("Sum to pay: " & (litres * price))
Console.ReadLine()
End Sub
I have a list of 14 fields in a infopath data source and I am trying to loop through them to check for whitespaces. This what I have put together but it does not like the Field after the UserInput I'll put what is should look like also:
Need it to work this way:
Private Sub ClearSpaces()
For i As Integer = 1 To 14
Dim DayString As String = System.Convert.ToString(i)
Dim Field As String = "Reason" & DayString
If String.IsNullOrEmpty(UserInput.Field.Trim()) Then
MessageBox.Show("Day " & DayString, "OK", MessageBoxButtons.OK)
End If
Next
End Sub
This works for just Reason1:
Private Sub ClearSpaces()
For i As Integer = 1 To 14
Dim DayString As String = System.Convert.ToString(i)
Dim Field As String = "Reason" & DayString
If String.IsNullOrEmpty(UserInput.Reason1.Trim()) Then
MessageBox.Show("Day " & DayString, "OK", MessageBoxButtons.OK)
End If
Next
End Sub