VB Seat booking file outputting incorrectly - vb.net

I am creating a seat booking program for coursework in which a user selects which row he/she wishes to book seats in, and then the number of seats they wish to book.
Public Class Form1
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rowNumber As Integer
Dim SeatsData As String(,) = {{"booked", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"}, {"booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked"}, {"C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10"}, {"D1", "booked", "booked", "D4", "D5", "D6", "D7", "D8", "D9", "D10"}, {"E1", "E2", "booked", "booked", "booked", "E6", "E7", "E8", "E9", "E10"}}
If ListBox2.Text = "A" Then
rowNumber = 0
ElseIf ListBox2.Text = "B" Then
rowNumber = 1
ElseIf ListBox2.Text = "C" Then
rowNumber = 2
ElseIf ListBox2.Text = "D" Then
rowNumber = 3
ElseIf ListBox2.Text = "E" Then
rowNumber = 4
End If
FindSeats(rowNumber, ListBox1.Text, SeatsData)
End Sub
Function FindSeats(ByVal RowNumber As Integer, ByVal NumSeats As Integer, SeatsData As Array) As String
Dim i As Integer = 0
Dim arrayPos As Integer = 0
Dim largestStreak As Integer = 0
Dim FirstSeat As String = 0
Dim LastSeat As String = 0
Dim foundSeats As Boolean = False
Dim returnMsg As String = ""
Do While foundSeats = False
Dim seatChar As String = SeatsData(RowNumber, arrayPos)
arrayPos = arrayPos + 1
If seatChar = "booked" Then
i = 0
Else
If i = 0 Then
FirstSeat = seatChar
End If
i = i + 1
If i > largestStreak Then
largestStreak = i
End If
End If
If i = NumSeats Then
LastSeat = seatChar
If FirstSeat = LastSeat Then
returnMsg = "Found seat: " + FirstSeat
Else
returnMsg = "Found seats: " + FirstSeat + " - " + LastSeat
End If
MsgBox(returnMsg)
Label3.Text = returnMsg
foundSeats = True
Exit Do
End If
If arrayPos = 10 Then
returnMsg = "Not enough available seats, maximum available seats: " + CStr(largestStreak)
MsgBox(returnMsg)
Label3.Text = returnMsg
Exit Do
End If
Loop
End Function
End Class
The issue I am having is that when a user selects the number of seats they want but not which row they want them for, the program automatically books seats in row A. How do I fix this? Also when A user selects a row but not a number of seats (or vice versa) the form goes to code and outputs the following error message: "An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Integer' is not valid."
How do I fix these errors? I am very new to VB so if any of this is obvious then I apologise!

You get the exception because you call FindSeats like this:
FindSeats(rowNumber, ListBox1.Text, SeatsData)
Note that the signature of FindSeats is actually
Function FindSeats(RowNumber As Integer, NumSeats As Integer, SeatsData As Array) As String
So you pass a string ListBox1.Text as NumSeats parameter, which is an Integer. Since you use Option Strict Off, VB.Net tries to implicitly cast the string in ListBox1.Text into an Integer.
This fails if ListBox1.Text is empty, and that's what the exception message it telling you:
Conversion from string "" to type 'Integer' is not valid.
First, turn Option Strict to On, then you'll see all those nifty implicit conversions that will bite you at runtime. Go on and replace them with safe explicit conversions that make sense.
Think about how you want to handle the case when the user clicks Button1 without selecting something in ListBox1 before.
Maybe you want to use Int32.TryParse to handle such cases, or maybe preselect a valid value in ListBox1

Related

Convert input of a textbox to the output of another textbox

I'm new to VB, been learning for about three months. I would like to take the input of a textbox, ex. “1234” and turn it into “one, two, three, four” in the second textbox (with commas). No buttons, just two textboxes. This is the code that I've been trying, it doesn't work. I get the error message:
Object reference not set to an instance of an object
If I could get a simple explanation that would be great, anything super complex will just blow my mind and make it more difficult for me to learn. You guys/gals are awesome and I'm ready to learn, thanks.
Dim boxOne = txtNumber.Text.Split(" "c)
Private Sub TxtNumber_TextChanged(sender As Object, e As EventArgs) Handles txtNumber.TextChanged
For Each i As Integer In boxOne
If txtNumber.Text = "1" Then
lblMessage.Text = "one"
End If
If txtNumber.Text = "2" Then
lblMessage.Text = "two"
End If
If txtNumber.Text = "3" Then
lblMessage.Text = "three"
End If
If txtNumber.Text = "4" Then
lblMessage.Text = "four"
End If
If txtNumber.Text = "5" Then
lblMessage.Text = "five"
End If
If txtNumber.Text = "6" Then
lblMessage.Text = "six"
End If
If txtNumber.Text = "7" Then
lblMessage.Text = "seven"
End If
If txtNumber.Text = "8" Then
lblMessage.Text = "eight"
End If
If txtNumber.Text = "9" Then
lblMessage.Text = "nine"
End If
If txtNumber.Text = "10" Then
lblMessage.Text = "ten"
End If
Next
lblMessage.Text = boxOne
End Sub
I suggest to create a mapper, a collection of items that can map/convert one value to another.
A Dictionary comes in handy for this task: given a Key, it returns the associated Value:
Private valueConverter As Dictionary(Of String, String) = New Dictionary(Of String, String) From {
{"0", "Zero"}, {"1", "One"}, {"2", "Two"}, {"3", "Three"}, {"4", "Four"},
{"5", "Five"}, {"6", "Six"}, {"7", "Seven"}, {"8", "Eight"}, {"9", "Nine"}}
A String is a collection of Chars: to parse it, you just need to loop the collection.
If you need to work with the collection of chars directly, you can use the String.ToCharArray() method (e.g., Dim charCollection = [TextBox].Text.ToCharArray()).
Check whether the current char represents a number (Char.IsNumber(char)) and map if it does:
Imports System.Text
Dim sb As New StringBuilder()
For Each part As Char In txtNumber.Text
If Not Char.IsNumber(part) Then Continue For
sb.Append(valueConverter(part) & ", ")
Next
lblMessage.Text = sb.ToString().TrimEnd({","c, " "c})
The StringBuilder class is often used when we need to cancatenate string. Since strings are immutable, each time you add a string to an existing one, you actually generate a new string each time, which needs to be garbage-collected.
For this reason, using a StringBuilder, the code performs way better.
Public Class Form1
Private Sub Str_TextChanged(sender As Object, e As EventArgs) Handles Str.TextChanged
Dim value As String = ""
For Each Str As String In Me.Str.Text
If Str = "1" Then
If value.Length = 0 Then
value = "One"
Else
value = value & ",One"
End If
ElseIf Str = "2" Then
If value.Length = 0 Then
value = "Two"
Else
value = value & ",Two"
End If
ElseIf Str = "3" Then
If value.Length = 0 Then
value = "Three"
Else
value = value & ",Three"
End If
ElseIf Str = "4" Then
If value.Length = 0 Then
value = "Four"
Else
value = value & ",Four"
End If
ElseIf Str = "5" Then
If value.Length = 0 Then
value = "Five"
Else
value = value & ",Five"
End If
ElseIf Str = "6" Then
If value.Length = 0 Then
value = "Six"
Else
value = value & ",Six"
End If
ElseIf Str = "7" Then
If value.Length = 0 Then
value = "Seven"
Else
value = value & ",Seven"
End If
ElseIf Str = "8" Then
If value.Length = 0 Then
value = "Eight"
Else
value = value & ",Eight"
End If
ElseIf Str = "9" Then
If value.Length = 0 Then
value = "Nine"
Else
value = value & ",Nine"
End If
End If
Next
'Your needed value is in variable 'value', use it to set it to another TextBox :)
End Sub
End Class
I don't think we use For Each on integer values to get individual ones. Try using For Each on string.
Here's a code:
Private Sub TxtNumber_TextChanged(sender As Object, e As EventArgs) Handles txtNumber.TextChanged
Dim value As String
For Each Str As String In TxtNumber.Text
If Str = "1" Then
If value.Length = 0 Then
value = "One"
Else
value = value & ",One"
End If
ElseIf Str = "2" Then
If value.Length = 0 Then
value = "Two"
Else
value = value & ",Two"
End If
ElseIf Str = "3" Then
If value.Length = 0 Then
value = "Three"
Else
value = value & ",Three"
End If
ElseIf Str = "4" Then
If value.Length = 0 Then
value = "Four"
Else
value = value & ",Four"
End If
ElseIf Str = "5" Then
If value.Length = 0 Then
value = "Five"
Else
value = value & ",Five"
End If
ElseIf Str = "6" Then
If value.Length = 0 Then
value = "Six"
Else
value = value & ",Six"
End If
ElseIf Str = "7" Then
If value.Length = 0 Then
value = "Seven"
Else
value = value & ",Seven"
End If
ElseIf Str = "8" Then
If value.Length = 0 Then
value = "Eight"
Else
value = value & ",Eight"
End If
ElseIf Str = "9" Then
If value.Length = 0 Then
value = "Nine"
Else
value = value & ",Nine"
End If
End If
Next
'Your needed value is in variable 'value', use it to set it to another TextBox :)
End Sub
And.... its done.

How to I add the total of a particular column in a list view and add it into a text box?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAdd.Click
If txtCode.Text = "" Or txtName.Text = "" Or txtUnit.Text = "" Or txtPrice.Text = "" Then
MsgBox("Please fill in all fields")
Else
Dim str(3) As String
Dim itm As ListViewItem
str(0) = LSet(txtName.Text, 8)
str(1) = LSet(txtCode.Text, 3)
str(2) = LSet(txtUnit.Text, 6)
str(3) = LSet(txtPrice.Text, 20)
itm = New ListViewItem(str)
ListView1.Items.Add(itm)
lblTotalItems.Text = ListView1.Items.Count
txtCode.Text = ""
txtName.Text = ""
txtUnit.Text = ""
txtPrice.Text = ""
End If
End Sub
I currently have this code for my list view, with more code in my global variables, I'm wanting to add up one column and place them in the Total text box, I know you have to loop through it and add them but i'm not sure how.
Here is the image for the form
Here is an example of the type of loop you could use.
Const col As Integer = 3 'this adds the price column
Dim total As Integer = 0
Dim lvsi As ListViewSubItem
For i As Integer = 0 To ListView1.Items.Count - 1
lvsi = ListView1.Items(i).SubItems(col)
total += Integer.Parse(lvsi.Text)
Next
A lot simple than a ListView use a DataGridView
Just initialize it on Form.Load() with:
DataGridView1.Columns.Add("Name", "Name")
DataGridView1.Columns.Add("Code", "Code")
DataGridView1.Columns.Add("Unit", "Unit")
DataGridView1.Columns.Add("Price", "Price")
DataGridView1.AllowUserToAddRows = False
Then on Add button:
If txtCode.Text = "" Or txtName.Text = "" Or txtUnit.Text = "" Or txtPrice.Text = "" Then
MsgBox("Please fill in all fields")
Else
DataGridView1.Rows.Add(txtName.Text, txtCode.Text, txtUnit.Value, Decimal.Parse(txtPrice.Text, System.Globalization.CultureInfo.InvariantCulture) * txtUnit.Value)
DataGridView1.Refresh()
End If
Here I did the Price column = the Unit times the price you entered.
I also handled decimals partly but you would need to check that price is 2.00 and not 2
Then for total button:
Dim MyTotal As Decimal = 0.00
'For each row in the gridd
For Each row As DataGridViewRow In DataGridView1.Rows
'invcrement total with column 3 equal to the price (index start = 0)
MyTotal = MyTotal + Decimal.Parse(row.Cells(3).Value, System.Globalization.CultureInfo.InvariantCulture)
Next
txtTotal.Text = MyTotal
I'll let you figure out the rest

VB confused by if path

I have VB program which user is to enter grades into using an InputBox. Regardless of user input, a message box (msgbox) stating "Please enter a number" appears. How do I change this to only show this message if a number is not entered?
Option Strict Off
Public Class Form1
Dim totalpointsaccumultator As Object
Private Sub exitButton_Click(sender As Object, e As EventArgs) Handles exitButton.Click
Me.Close()
End Sub
Public Sub assignButton_Click(sender As Object, e As EventArgs) Handles assignButton.Click
Dim inputProjectPoints, inputTestPoints As String
Dim grade, projectpoints, testpoints As String
Dim projectcounter As Integer = 1
Dim testcounter As Integer = 1
Dim isconverted As Boolean
Dim totalpointsaccumulator As Integer
Do While projectcounter < 5
inputProjectPoints = InputBox("Enter the points earned on project " & projectcounter, "Grade Calculator", "0")
inputProjectPoints = projectpoints
isconverted = Integer.TryParse(inputProjectPoints, CInt(projectpoints))
If isconverted Then
totalpointsaccumultator = totalpointsaccumulator + projectpoints
projectcounter = projectcounter + 1
Else
MessageBox.Show("Please enter a number.", "Grade Calculator", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Loop
Do While testcounter < 3
inputTestPoints = InputBox("Enter the points earned on test " & testcounter, "Grade Calculator", "0")
isconverted = Integer.TryParse(inputTestPoints, testpoints)
If isconverted Then
testcounter = testcounter + 1
totalpointsaccumulator = CInt(totalpointsaccumulator + testpoints)
Else
MessageBox.Show("Please enter a number.", "Grade calculator", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Loop
' assign grade
Select Case totalpointsaccumulator
Case Is >= 360
grade = "A"
Case Is >= 320
grade = "B"
Case Is >= 280
grade = "C"
Case Is >= 240
grade = "D"
Case Else
grade = "F"
End Select
totalpointsLabel.Text = Convert.ToString(totalpointsaccumulator)
gradeLabel.Text = grade
End Sub
End Class
isconverted = Integer.TryParse(inputProjectPoints, CInt(projectpoints))
should be:
isconverted = Integer.TryParse(inputProjectPoints, projectpoints)
as well as:
Dim grade, projectpoints, testpoints As String
Should be:
Dim grade as String
Dim projectpoints, testpoints As Integer
You can't pass a reference variable as a different type by trying to convert/cast it, that just returns the value in the type you requested (if possible, which is ironic considering you're use of Integer.TryParse()) it doesn't actually change the underlying type of the variable you declared.
Because of this issue, your Integer.TryParse() always fails, meaning isconverted is always false and you'll always get the message box.
Edit: Forgot to add, Plutonix is right. Set Option Strict ON!!

Separate message for condition in vb document

I am creating a seat booking system in visual basic for coursework and it has to allow users to book seats from rows A to E. For row B, I have set it so that there are no seats remaining, however the message simply tells the user that there are not enough seats and that the maximum available seats is 0. I need the code to tell users that there are no seats remaining. My code is as follows:
Public Class Form1
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rowNumber As Integer
Dim SeatsData As String(,) = {{"booked", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"},
{"booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked", "booked"},
{"C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10"},
{"D1", "booked", "booked", "D4", "D5", "D6", "D7", "D8", "D9", "D10"},
{"E1", "E2", "booked", "booked", "booked", "E6", "E7", "E8", "E9", "E10"}}
If ListBox2.Text = "A" Then
rowNumber = 0
ElseIf ListBox2.Text = "B" Then
rowNumber = 1
ElseIf ListBox2.Text = "C" Then
rowNumber = 2
ElseIf ListBox2.Text = "D" Then
rowNumber = 3
ElseIf ListBox2.Text = "E" Then
rowNumber = 4
End If
FindSeats(rowNumber, ListBox1.Text, SeatsData)
End Sub
Function FindSeats(ByVal RowNumber As Integer, ByVal NumSeats As Integer, SeatsData As Array) As String
Dim i As Integer = 0
Dim arrayPos As Integer = 0
Dim maxSeats As Integer = 0
Dim FirstSeat As String = 0
Dim LastSeat As String = 0
Dim Seatsfound As Boolean = False
Dim returnMsg As String = ""
Do While Seatsfound = False
Dim seatChar As String = SeatsData(RowNumber, arrayPos)
arrayPos = arrayPos + 1
If seatChar = "booked" Then
i = 0
Else
If i = 0 Then
FirstSeat = seatChar
End If
i = i + 1
If i > maxSeats Then
maxSeats = i
End If
End If
If i = NumSeats Then
LastSeat = seatChar
If FirstSeat = LastSeat Then
returnMsg = "Found seat: " + FirstSeat
Else
returnMsg = "Found seats: " + FirstSeat + " - " + LastSeat
End If
MsgBox(returnMsg)
Label3.Text = returnMsg
Seatsfound = True
Exit Do
End If
If arrayPos = 10 Then
returnMsg = "Not enough available seats, maximum available seats: " + CStr(maxSeats)
MsgBox(returnMsg)
Label3.Text = returnMsg
Exit Do
End If
Loop
End Function
End Class
How can I set my code so that it tells the user "there are no remaining seats in this row" or something?
Without using a custom class to design your problem domain, a simple approach is using a Dictionary
For example
Sub Main
Dim seats = new Dictionary(Of string, List(Of String))()
seats.Add("A", new List(Of String) FROM {"A1", "A2", "A3"})
seats.Add("B", new List(Of String) FROM {"booked", "booked", "booked"})
seats.Add("C", new List(Of String) FROM {"C1", "C2", "booked"})
seats.Add("D", new List(Of String) FROM {"booked", "booked", "D3"})
Dim result = FindSeat(seats, "D")
Console.WriteLine(result) ' Output = D3
result = FindSeat(seats, "B")
Console.WriteLine(result) ' Output = "No free seat on that line"
End Sub
Function FindSeat(seats as Dictionary(Of String, List(Of String)), line as String) As String
if seats.ContainsKey(line) Then
dim seatLine = seats(line)
Dim placeFree = seatLine.FirstOrDefault(Function (x) x <> "booked")
if placeFree Is Nothing then
return "No free seat on that line"
else
return placeFree
End If
Else
return "Not a valid line letter"
End If
End Function
In Main, I have statically declared a Dictionary that contains as Key the line letter while a List(Of String) is used as value to declare the seats names and their current state.
Now to find a free seat I get the List(Of String) corresponding to the Line letter and the apply a simple FirstOrDefault to get the first seat not booked

How to fix a function that isn't calling (No error alerts)

This is some code for my Computing coursework to create a seat booking system allowing a user to input a desired row and the number of adjacent seats required, and then the form outputs a message showing what seats are available or an alert if there is not enough seats in that row.
The main problem I am having is that I have no errors, but once the submit button is clicked nothing happens which would suggest the "seatsBlock" function is not calling, and I was wondering if anyone could give me a solution
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rowNumber As Integer
If ListBox2.Text = "A" Then
rowNumber = 1
ElseIf ListBox2.Text = "B" Then
rowNumber = 2
ElseIf ListBox2.Text = "C" Then
rowNumber = 3
ElseIf ListBox2.Text = "D" Then
rowNumber = 4
ElseIf ListBox2.Text = "E" Then
rowNumber = 5
End If
SearchSeats(rowNumber, ListBox1.Text)
End Sub
Function SearchSeats(ByVal RowNumber As Integer, ByVal NumSeats As Integer) As String
Dim CountSeat As Integer = 0 '
Dim FirstSeat As String = 0
Dim lastSeat As String = 0
Dim i As Integer = 0
FirstSeat = SeatsBlock(RowNumber, i, FirstSeat, lastSeat)
Do While NumSeats > CountSeat
If i > 9 Then
Return ("There are not enough seats available in this block")
Exit Do
End If
If SeatsBlock(RowNumber, i, FirstSeat, lastSeat) = "booked" Then
CountSeat = 0
FirstSeat = SeatsBlock(RowNumber, (i + 1), FirstSeat, lastSeat)
Else
lastSeat = SeatsBlock(RowNumber, i, FirstSeat, lastSeat)
CountSeat = i + 1
End If
i = i + 1
Loop
Return ("There are currently " & NumSeats & "seats available: " & FirstSeat & " - " & lastSeat)
End Function
Function SeatsBlock(ByVal RowNumber As Integer, ByVal NumSeats As Integer, ByVal FirstSeat As String, ByVal LastSeat As String) As String
Return ("Currently available are " & NumSeats & " seats available: " & FirstSeat & " - " & LastSeat)
End Function
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim SeatsBlock As String(,) = {{"A1", "A2", "booked", "A4", "A5", "A6", "A7", "A8", "booked", "A10"}, {"booked", "booked", "booked", "B4", "B5", "booked", "booked", "B8", "booked", "B10"}, {"C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10"}, {"D1", "booked", "booked", "D4", "D5", "D6", "D7", "D8", "D9", "D10"}, {"E1", "E2", "booked", "booked", "booked", "E6", "E7", "E8", "E9", "E10"}}
End Sub
Thanks
Change the following line:
SearchSeats(rowNumber, ListBox1.Text)
for this:
Msgbox(SearchSeats(rowNumber, ListBox1.Text))
That way you get a messagebox, else you will never see the error!