Case Statement not working with String Literals - vb.net

Hi all I am trying to learn VB and am having trouble with some code I am using. I would like my program to output a specific number based on if a check box is checked using case statements but my code is not working.
Public Class frmBTPW
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
Dim dblhdr As Double
Dim dblfdr As Double
Dim dbltdr As Double
dblhdr = 24
dblfdr = 35
dbltdr = 50
Select Case "Power Wash Rental"
Case "Half Day Rental"
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
Case "Full Day Rental"
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If
End Select
End Sub
Private Function Button1_Click() As CheckBox
Throw New NotImplementedException
End Function
End Class
Help would be greatly appreciated.My code isn't outputting anything in the text-box.

Beyond case statements, respectfully I think you should read up on the distinction between a literal value and a variable. "Power Wash Rental" is nothing more than a series of characters, AKA a string: (In this case "P" followed by "o" etc.) Likewise, "Half Day Rental" is a series of characters, "H" followed by "a" etc.)
"Power Wash Rental" is a literal string. So is ""Half Day Rental" and of course they will never match.
Whereas:
Dim A as string
A = TextBox1.text
Now, A is a variable. It is a string which contains whatever series of characters (text) is typed into the textbox.

This is a simple way to do it.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
chkhd.tag = 24 ' store values in the check boxes
chkfd.tag = 35 ' using the tag property
chktd.tag = 50 ' and later add up the values
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
dim total as double = 0
total += IF(chkhd.checked, cdbl(chkhd.tag), 0)
total += IF(chkfd.checked, cdbl(chkfd.tag), 0)
total += IF(chktd.checked, cdbl(chktd.tag), 0)
msgbox(total)
End Sub
However, I think you might want radio buttons instead of checkboxes.
Checkboxes can all be checked. Radio buttons can only have one at a time.
This solution allows you to keep your price with the checkbox -- you could do this in the form designer instead of form load.

I would recommend reading up on Case Statements. Currently you will never get anywhere as your using a string to what, nothing. You also do not need a case for this... Also if the first condition is true and the last one is as well, the last one win's for setting the text, didn't know if you had this there for a reason or not?
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If

As others have stated your Case statement isn't working because you are using string literals to compare "Power Wash Rental" to "Half Day Rental" which will always be false. Plutonix was also correct in saying that a ComboBox for the rental duration should be used. The only reason not to be is if you were calculating cumulative rental days/amounts; however in that situation you should be using some sort of NumericUpDown for your multiplier against a time duration.
Here is an example that should help you get started. You could make the structure into a type of keyed collection or make it a wrapper class for a dictionary object which would make be easier to use in code. The following may not be exactly plug-and-play with your project, however it should help give you some ideas on how to handle the situation.
Option Strict On
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ComboBox1.Items.AddRange({PowerWashRentals.halfDayText, PowerWashRentals.FullDayText, PowerWashRentals.TwoDayText})
AddHandler ComboBox1.SelectedValueChanged, AddressOf Me.ComboBox1_SelectedChanged
End Sub
Private Sub ComboBox1_SelectedChanged(sender As Object, e As EventArgs)
Dim cBox As ComboBox = DirectCast(sender, ComboBox)
Select Case cBox.SelectedItem.ToString
Case PowerWashRentals.halfDayText
Label1.Text = PowerWashRentals.HalfDayPrice.ToString
Case PowerWashRentals.FullDayText
Label1.Text = PowerWashRentals.FullDayPrice.ToString
Case PowerWashRentals.TwoDayText
Label1.Text = PowerWashRentals.TwoDayPrice.ToString
End Select
End Sub
End Class
Public Structure PowerWashRentals
Public Const HalfDayPrice As Double = 24
Public Const FullDayPrice As Double = 35
Public Const TwoDayPrice As Double = 50
Public Const halfDayText As String = "Half Day Rental"
Public Const FullDayText As String = "Full Day Rental"
Public Const TwoDayText As String = "Two Day Rental"
End Structure

Related

Textbox only converter

I am making a temperature converter in vb.net for my assignment. I know the conversion method and so on.. but the problem is, I need to only use two textboxes. One for Celsius and one for farenheit. Whenever I update the textbox for celsius, the changes on textbox should also happen, and when I change the value for farenheit, the celsius textbox should also change depending on the value for farenheit. What method should I do?
This is the current one im working on..
Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If TextBox1.Focus() Then
TextBox2.Clear()
TextBox2.Text = (TextBox1.Text - 32) / 1.8
ElseIf TextBox2.Focus() Then
TextBox1.Clear()
TextBox1.Text = (TextBox2.Text * 1.8) + 32
End If
End Sub
End Class
Thanks for posting some code. This is the way I'd do it (after wiring up TextChanged event handlers for both text boxes):
Private DegreesCChanging As Boolean = False
Private DegreesFChanging As Boolean = False
Private Sub DegreesF_TextChanged(sender As Object, e As EventArgs) Handles DegreesF.TextChanged
If Not DegreesFChanging Then
Dim Temperature As Double
DegreesCChanging = True
If Double.TryParse(DegreesF.Text, Temperature ) Then
DegreesC.Text = ((Temperature - 32.0) / 9.0 * 5.0).ToString("0.##")
Else
DegreesC.Text = String.Empty
End If
DegreesCChanging = False
End If
End Sub
Private Sub DegreesC_TextChanged(sender As Object, e As EventArgs) Handles DegreesC.TextChanged
If Not DegreesCChanging Then
Dim Temperature As Double
DegreesFChanging = True
If Double.TryParse(DegreesC.Text, Temperature ) Then
DegreesF.Text = (Temperature / 5.0 * 9.0 + 32.0).ToString("0.##")
Else
DegreesF.Text = String.Empty
End If
DegreesFChanging = False
End If
End Sub
There are a few things to note.
I'm using the TextChanged event - as soon as the user types
something into either text box, the world starts changing
I use double.TryParse to convert the number to a string. If I can't figure out what's going on (i.e., the TryParse call returns False), I stick an empty string in the other text box. It works quite well.
When the user types something into a text box, it causes a TextChanged event that forces new text into the other text box - which will result in a TextChanged event for that control. I use two Boolean flags to prevent this.
I use a custom numeric format string on my ToString calls to limit
the precision to two decimal places.

Visual basic empty text box throws exception

The code below is a program to calculate the BMI using text boxes. I am having an issue however that when I clear one of the text boxes it will throw an exception and freeze the program. I was wondering if anyone had an answer on how to prevent this. I already tried setting my variables to 0 and 1 to see if that was the issue but it does not appear to be.
Private Sub tboxWeight_TextChanged(sender As Object, e As EventArgs) Handles tboxWeight.TextChanged
Weight = 0
Weight = Convert.ToInt64(tboxWeight.Text)
End Sub
Private Sub tboxHFeet_TextChanged(sender As Object, e As EventArgs) Handles tboxHFeet.TextChanged
Height_feet = 0
Height_feet = Convert.ToInt64(tboxHFeet.Text)
Get_BMI(1)
End Sub
Private Sub tboxHInch_TextChanged(sender As Object, e As EventArgs) Handles tboxHInch.TextChanged
Height_Inches = 0
Height_Inches = Convert.ToInt64(tboxHInch.Text)
Get_BMI(1)
End Sub
Private Sub tboxAge_TextChanged(sender As Object, e As EventArgs) Handles tboxAge.TextChanged
Age = Convert.ToDouble(tboxAge.Text)
End Sub
Function Get_BMI(ByVal j As Integer) As Double
BMI = (Weight / (Height_Inches + (Height_feet * 12) ^ 2) * 703)
tboxBMI.Text = Convert.ToString(BMI)
Exit Function
End function
It is because you set a textbox into an integer field, so when the textbox is empty it will throw exception because the textbox doesn't contain a number.
Try using If else statement for each textboxes.
String.IsNullOrEmpty function will be sufficient.
Good/Best practice says, you need to validate the data before performing calculation i.e. Get_BMI(). Below code snippet will help you.
Dim textBoxValue As String
If Not String.IsNullOrEmpty(textBoxValue) Then
If IsNumeric(textBoxValue) Then
End If
End If

Alternative Process

I have 2 buttons and a DataGridView with 2 Columns (0 & 1).
The 1st button transfers a randomized cell from the Column(1) to a TextBox. Then, it stores that Cell in variable (a), plus the cell that opposites it in variable (b).
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim rnd As New Random
Dim x As Integer = rnd.Next(0, Form1.DataGridView1.Rows.Count)
Dim y As Integer = 1
Dim a As String = Form1.DataGridView1.Rows(x).Cells(y).Value
Dim b As String = Form1.DataGridView1.Rows(x).Cells(y - 1).Value
TextBox3.Text = a
End Sub
The 2nd button, however, is supposed to compare if another TextBox's text has the same string variable (b) has as Strings. Now, if so, then it has to display a certain message and so on...
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If TextBox4.Text = b Then '<<< ISSUE HERE!
MsgBox("Correct! ^_^")
ElseIf TextBox4.Text = "" Then
MsgBox("You have to enter something first! O_o")
Else
MsgBox("Wrong! >,<")
End If
End Sub
The problem is that the variable (b) is surely not shared across the two "private" subs. And so, there is NOTHING to compare to in the 2nd button's sub! I presume that the solution here is to split the "randomization process" into a separate function, then execute it directly when the 1st button gets activated. Furthermore, that function's variables have to be SHARED somehow, and I certainly don't know how!
Thanks for Mr. Olivier, the code has been improved significantly! Yet, I still encounter a "wrong" comparison issue, somehow!
Dim RND As New Random
Dim x As Integer
Private Function GetCell(ByVal rowIndex As Integer, ByVal cellIndex As Integer) As String
Return Form1.DataGridView1.Rows(rowIndex).Cells(cellIndex).Value
End Function
Private Sub btnRoll_Click(sender As Object, e As EventArgs) Handles btnRoll.Click
x = RND.Next(0, Form1.DataGridView1.Rows.Count)
tbxRoll.Text = GetCell(x, 1)
End Sub
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
If tbxSubmit.Text = GetCell(x, 0) Then
MsgBox("Correct! ^_^")
ElseIf tbxSubmit.Text = "" Then
MsgBox("You have to enter something first! O_o")
Else
MsgBox("Wrong! >,<")
End If
End Sub</code>
Well, unbelievably, I read a guide about "comparison operations" in VB.net and tried out the first yet the most primal method to compare equality - which was to use .Equals() command - and worked like a charm! Thank God, everything works just fine now. ^_^
If tbxSubmit.Text.Equals(GetCell(x, 0)) Then
Alright now... This is going to sound weird! But, following Mr. Olivier's advise to investigate "debug" the code, I rapped the string I'm trying to compare with brackets and realized that it's been outputted after a break-line space! So, I used the following function to remove the "white-space" from both of the comparison strings! And it bloody worked! This time for sure, though. ^_^
Function RemoveWhitespace(fullString As String) As String
Return New String(fullString.Where(Function(x) Not Char.IsWhiteSpace(x)).ToArray())
End Function
If RemoveWhitespace(tbxSubmit.Text) = RemoveWhitespace(GetCell(x, 0)) Then
Turn the local variables into class fields.
Dim rnd As New Random
Dim x As Integer
Dim y As Integer
Dim a As String
Dim b As String
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
x = rnd.Next(0, Form1.DataGridView1.Rows.Count)
y = 1
a = Form1.DataGridView1.Rows(x).Cells(y).Value
b = Form1.DataGridView1.Rows(x).Cells(y - 1).Value
TextBox3.Text = a
End Sub
These fields can now be accessed from every Sub, Function and Property.
Of course Button3_Click must be called before Button2_Click because the fields are initialized in the first method. If this is not the case then you should consider another approach.
Create a function for the Cell access
Private Function GetCell(ByVal rowIndex As Integer, ByVal cellIndex As Integer) _
As String
Return Form1.DataGridView1.Rows(rowIndex).Cells(cellIndex).Value
End Function
And then compare
If TextBox4.Text = GetCell(x, y - 1) Then
...
And don't store the values in a and b anymore. If y is always 1 then use the numbers directly.
If TextBox4.Text = GetCell(x, 0) Then
...
One more thing: give speaking names to your buttons in the properties grid before creating the Click event handlers (like e.g. btnRandomize). Then you will get speaking names for those routines as well (e.g. btnRandomize_Click).
See:
- VB.NET Class Examples
- Visual Basic .NET/Classes: Fields

Visual Basic Avg. Temp Calculator

Ok, so I am super new to visual basic and was not planning on taking it as a class either until they made it a requirement for me to get my technicians certificate at my community college. Literally understand the chapters I have read so far to a T, and then first homework assignment comes up and for the past few days I have been scratching my head as to why on earth it is not working. Here is what the Prof is asking.
Write a program that calculates average daily temperatures and summary statistics. The user will be prompted to enter a Fahrenheit temperature as a value with one decimal place and to select the name of the technician entering the temperature. The user will have the option to see the Celsius equivalent of the entered Fahrenheit temperature. The program will display the average temperature of all entered temperatures. The results are displayed when the user hits ENTER, uses the access key or clicks the Calculate button. The user will be given the opportunity to enter another temperature when the user hits ESC (Clear is the Cancel Button), uses the access key or clicks the Clear button. The user will exit the program by clicking the Exit button or using its access key. The Exit button will also display the summary statistics: 1) the number of temperatures entered by each technician and 2) the average temperature of all entered temperatures. Calculations should only be done if a numeric value between 32.0 and 80.0 (inclusive) degrees for temperature is entered and a technician has been selected.
The graphical side is a breeze with dragging and dropping, then naming the labels, radio buttons, etc... But now that I have assembled my code. Nothing is working. I'm frustrated, confused, and let down. I had no idea this class would be this hard. Here is what I came up with so far code wise. No error messages at all, just not getting any output pretty much.
Option Strict On
Option Strict On
Public Class Form1
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
'Clear App
txtTemp.Clear()
lblAverageTemp.Text = String.Empty
lblCelsius.Text = String.Empty
radDave.Checked = False
radJoe.Checked = False
chkCelsiusTemp.Checked = False
'New Temp Focus
txtTemp.Focus()
End Sub
Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
'End app with display
MessageBox.Show("Dave entered intEntriesDave entries." & ControlChars.CrLf & "Joe entered intEntriesJoe entries." & _
ControlChars.CrLf & "The average temperature is _.", "Status")
Me.Close()
End Sub
Public Sub chkCelsiusTemp_CheckedChanged(sender As Object, e As EventArgs) Handles chkCelsiusTemp.CheckedChanged
'Convert entered Fahrenheit temp to Celsius
Dim dblCelsius As Double
dblCelsius = (CDbl(txtTemp.Text) - 32) * 5 / 9
lblCelsius.Text = CStr(dblCelsius)
End Sub
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim intEntriesDave As Integer = 0
Dim intEntriesJoe As Integer = 0
If radDave.Checked = True Then
intEntriesDave = +1
End If
If radJoe.Checked = True Then
intEntriesJoe = +1
End If
Dim dblAvg As Double
dblAvg = CDbl(txtTemp.Text) / intEntriesDave + intEntriesJoe
lblAverageTemp.Text = CStr(dblAvg)
End Sub
End Class
Hope I figure this out or I can get some help with it. I procrastinated of course, like the idiot I am, and it is due in 11 hours :\
Thanks in advance!
I would use a dictionary to store names along with temperatures.
Place a numericupdown control on your form for the temperature input (numTemp) and a textbox for names tbName and a label lblCelsius for output:
Public Class Form1
Dim temps As New Dictionary(Of String, List(Of Double))
Private Sub btnEnter_Click(sender As Object, e As EventArgs) Handles btnEnter.Click
If numTemp.Value < 32 OrElse numTemp.Value > 80 OrElse tbName.Text = "" Then Exit Sub 'Invalid input
If temps.ContainsKey(tbName.Text) = False Then 'Name is new, create a new list entry
temps.Add(tbName.Text, New List(Of Double))
End If
temps(tbName.Text).Add(numTemp.Value) 'Append the entered temperature
lblCelsius.Text = "In celsius: " & CStr(numTemp.Value - 32) * 5 / 9 'Output the Celsius value
End Sub
Private Sub btnStats_Click(sender As Object, e As EventArgs) Handles btnStats.Click
Dim sb As New System.Text.StringBuilder 'Create the output
For Each k As String In temps.Keys
sb.AppendLine(k & ": " & temps(k).Average)
Next
lblCelsius.Text = sb.ToString
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
temps.Clear() 'Clear the database
End Sub
End Class
Basically everytime you click btnEnter you check your dictionary if the name already entered a value. If not a new entry is created with a new list and the new temperature is just added to the list.
Creating the output is then straightforward with the .Average method of the list.

Passing arguments to methods in VB

I'm hoping you guys can help with a problem that should be simple to solve, I've just had issues finding a solution. In the program that I'm writing some of the textbox's have to be numeric between 1 and 10, and others just have to be numeric. Instead of coding each textbox to verify these parameters I decided to write methods for each of them. I'm having problems passing the arguments and getting it to function correctly. Included is some of my code that shows what I'm trying to accomplish.
Public Shared Sub checkforonetoten(ByVal onetoten As Double)
If (onetoten > 1 & onetoten < 10) Then
Else
MessageBox.Show("Please enter a Number between 1-10", "Error")
End If
End Sub
Public Shared Sub checkfornumber(numCheck As Double)
Dim numericCheck As Boolean
numericCheck = IsNumeric(numCheck)
If (numericCheck = False) Then
MessageBox.Show("Please enter a number", "Error")
End If
End Sub
Private Sub textboxS_TextChanged(sender As Object, e As EventArgs) Handles textboxS.TextChanged
Dim S As Double
S = textboxS.Text
checkfornumber(S)
checkforonetoten(S)
End Sub
One of your main problems is you're converting your text without validating it. You're also programming without the Options On to warn you of bad conversion techniques like you're using in the event handler.
The TryParse method would come in handy here:
Private Sub textboxS_TextChanged(sender As Object, e As EventArgs) Handles textboxS.TextChanged
Dim S As Double
If Double.TryParse(textboxS.Text, S) Then
checkforonetoten(S)
End If
End Sub
Since the TryParse method validates your text and sets the value to 'S', you only need to check the range.
Of course using NumericUpDown controls would make all this moot, since the values will always only be numbers and you can set the range on each one.
one way to structure it is to have one event procedure process the similar TB types:
Private Sub textboxS_TextChanged(sender As Object, e As EventArgs) _
Handles textbox1.TextChanged, textbox12.TextChanged, _
Handles textbox16.TextChanged
Dim S As Double
If Double.TryParse(Ctype(sender, TextBox).Text, S) Then
' or place the Check code here for all the TextBoxes listed above
checkforonetoten(S)
End If
End Sub
The plain numeric kind:
Private Sub textboxQ_TextChanged(sender As Object, e As EventArgs) _
Handles textbox2.TextChanged, textbox6.TextChanged
Dim S As Double
If Double.TryParse(Ctype(sender, TextBox).Text, S) = False Then
MessageBox.Show("Please enter a number", "Error")
End If
End Sub
Rather than calling a function and passing the current TextBox from events (which is fine), have 2 or 3 events process them all. The point is adding/moving the Handles clause to a common event procedure (be sure to delete the old ones).
If you do decide to call a common function, dont do anything in the events (you still have one per TB) and do it all in the common proc:
Private Sub textboxS_TextChanged(sender As Object, e As EventArgs) _
Handles textboxS.TextChanged
checkforonetoten(Sender)
End Sub
private Sub checkforonetoten(tb As Textbox)
Dim S As Double
If Double.TryParse(tb.Text, S) Then
' your check for 1 - 10 on var S
else
' error: not a valid number
End If
end sub
Also:
If (onetoten > 1 & onetoten < 10) Then
should be:
If (onetoten > 1) AndAlso (onetoten < 10) Then