I'm trying to calculate discount based on a person's age category and amount of visits at a hair salon. It's just not working properly though. It doesn't calculate the proper discount until the second click and then it does some weird stuff if I keep pressing calculate. Just wondering where I am going wrong, thanks.
' Discount
If radAdult.Checked = True Then
discount = 0
ElseIf radChild.Checked = True Then
discount = totalPrice * 0.1
ElseIf radStudent.Checked = True Then
discount = totalPrice * 0.05
ElseIf radSenior.Checked = True Then
discount = totalPrice * 0.15
End If
' Additional discount
If txtClientVisits.Text >= 1 And txtClientVisits.Text <= 3 Then
additionalDiscount = 0
ElseIf txtClientVisits.Text >= 4 And txtClientVisits.Text <= 8 Then
additionalDiscount = totalPrice * 0.05
ElseIf txtClientVisits.Text >= 9 And txtClientVisits.Text <= 13 Then
additionalDiscount = totalPrice * 0.1
ElseIf txtClientVisits.Text >= 14 Then
additionalDiscount = totalPrice * 0.15
End If
totalPrice = baseRate + serviceRate - (discount + additionalDiscount)
The type of the txtClientVisits.Text property is a String. The comparison operators <, >, >=, and <= for strings perform a lexicographic comparison. VB will then convert 14 to the string "14" and so compare each digit one-by-one, which is not what you want.
(This is why I don't like VB.NET - because it performs these implicit conversions without warning you).
You will need to explicitly convert the number in the textbox to an actual number, then compare based on that:
Dim clientVisits As Integer = CInt( txtClientVisits.Text )
If clientVisits >= 1 AndAlso clientVisits < 4 Then
additionalDiscount = 0
ElseIf clientVisits >= 4 AndAlso clientVisits < 9 Then
additionalDiscount = totalPrice * 0.05
ElseIf clientVisits >= 9 AndAlso clientVisits < 14 Then
additionalDiscount = totalPrice * 0.1
ElseIf clientVisits >= 14 Then
additionalDiscount = totalPrice * 0.15
End If
I note you used inclusive boundary values. That works for integer values but will fail for continuous (floating-point) values. Note how I'm using >= and < instead of >= and <= to avoid that case.
Also, note I'm using the AndAlso operator which is short-circuiting (compared to And which is not). This isn't a functional change, it just means the program will run slightly faster.
Also, you don't need to do ElseIf radChild.Checked = True Then because the value of the .Checked property is already a boolean value, you can do this instead:
ElseIf radChild.Checked Then
Related
I'm designing a software that does basic payroll for a school project. I'm stuck on this one part where I have to figure out what the federal tax will be based on the employee salary. This is the chart that tells you the rate of the tax based on salary range.
I tried this code,
Dim federaltaxrate As Integer
Dim federaltax = (salary.Text * federaltaxrate)
If salary.Text >= 0 Then
If salary.Text <= 50 Then
federaltaxrate = 0
End If
ElseIf salary.text <= 500 Then
If salary.Text >= 50 Then
federaltaxrate = 0.1
End If
ElseIf salary.text <= 2500 Then
If salary.Text >= 500 Then
federaltaxrate = 45 + 0.15 * salary.Text - 500
End If
ElseIf salary.text <= 5000 Then
If salary.Text >= 2500 Then
federaltaxrate = 345 + 0.2 * salary.Text - 2500
End If
ElseIf salary.text >= 5000 Then
federaltaxrate = 845 + 0.25 * salary.Text - 5000
End If
Else
End If
I have a listbox that shows other information as well but this is what I used to show the calculated info in the listbox.
ListBox1.Items.Add("Federal Tax: $" + federaltax.ToString)
When I run this code and input in a random salary, the federal tax shows up as 0.
Do I need to convert the salary into weekly gross pay, if so how would I go on about writing the code that finds the federal tax rate based on the salary and it's range.
You might be having trouble with order of precedence of the arithmetic operations. I think a Select Case is cleaner.
Private Function GetFederalTax(GrossPay As Decimal) As Decimal
Dim FederalTax As Decimal
Select Case GrossPay
Case < 50
FederalTax = 0
Case < 500
FederalTax = CDec((GrossPay - 51) * 0.1)
Case < 2500
FederalTax = CDec(((GrossPay - 500) * 0.15) + 45)
Case < 5000
FederalTax = CDec(((GrossPay - 2500) * 0.2) + 345)
Case Else
FederalTax = CDec(((GrossPay - 5000) * 0.25) + 845)
End Select
Return FederalTax
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim grossPay As Decimal
If Decimal.TryParse(TextBox1.Text, grossPay) Then
Dim tax = GetFederalTax(grossPay)
Debug.Print($"Gross {grossPay} Tax {tax}")
ListBox1.Items.Add(String.Format("Federal Tax {0}, Gross Pay {1}", tax, grossPay)) '***EDIT***
Else
MessageBox.Show("Please enter a valid number.")
End If
End Sub
The sample test produced the following in the Immediate Window.
Gross 45 Tax 0
Gross 700 Tax 75
Gross 8000 Tax 1595
Gross 2501 Tax 345.2
Gross 2800 Tax 405
Firstly, your Boolean logic is all wrong. If the salary value was 51, you'd satisfy the first outer condition (>= 0) and then fail the first inner condition (<= 50). There would not be any further comparisons performed - which you would know if you'd debugged - so no tax calculation would ever be performed.
Secondly, your calculations are OK but you're misusing the results. Those calculation get the amount of tax to be paid, not the rate. The rates are 10%, 15%, 20% and 25%, which are already contained in your calculations. Get rid of that second variable and just assign the results of appropriate calculations to the one variable.
I would do it like this:
Dim salaryAmount = CDec(salary.Text)
Dim taxAmount As Decimal = Decimal.Zero
If salaryAmount > 5000D Then
taxAmount = 845D + 0.25D * (salaryAmount - 5000D)
ElseIf salaryAmount > 2500D Then
taxAmount = 345D + 0.2D * (salaryAmount - 2500D)
ElseIf salaryAmount > 500D Then
taxAmount = 45D + 0.15D * (salaryAmount - 500D)
ElseIf salaryAmount > 50D Then
taxAmount = 0.1D * (salaryAmount - 50D)
End If
'Use taxAmount here.
This uses appropriate data types throughout, i.e. it does not perform arithmetic on String values and it uses Decimal for currency values. The D suffix on the literals forces them to be type Decimal rather than Integer or Double.
It also works from biggest to smallest to simplify the Boolean expressions.
The Nested If should be combined like below as it is missing few cases
If salary.Text >= 0 And salary.Text <= 50 Then
federaltaxrate = 0
ElseIf salary.text <= 500 And salary.Text >= 50 Then
federaltaxrate = 0.1
ElseIf salary.text <= 2500 AND salary.Text >= 500 Then
federaltaxrate = 45 + 0.15 * salary.Text - 500
End If
I can't understand how I should fix my code. I keep getting this error.
InvalidCastException was unhandled
An unhandled exception of type 'System.InvalidCastException' occurred
in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Double' is
not valid.
I'm confused on how to fix this. I don't understand the error. It starts at the beginning of the If. Here is the code I am using:
Public class Income_Tax
Dim rate as Double
Dim difference as Double
Private Sub textboxqitni_TextChanged(sender As Object, e As EventArgs) Handles textboxqitni.TextChanged
If textboxqitni.Text >= 0 And textboxqitni.Text <= 10000 Then
textboxittd.Text = textboxqitni.Text * 0.05
ElseIf textboxqitni.Text >= 10000 And textboxqitni.Text <= 30000 Then
difference = textboxqitni.Text - 10000
rate = difference * 0.1
textboxittd.Text = rate + 500
ElseIf textboxqitni.Text >= 30000 And textboxqitni.Text <= 70000 Then
difference = textboxqitni.Text - 30000
rate = difference * 0.15
textboxittd.Text = rate + 2500
ElseIf textboxqitni.Text >= 70000 And textboxqitni.Text <= 140000 Then
difference = textboxqitni.Text - 70000
rate = difference * 0.2
textboxittd.Text = rate + 8500
ElseIf textboxqitni.Text >= 140000 And textboxqitni.Text <= 250000 Then
difference = textboxqitni.Text - 140000
rate = difference * 0.25
textboxittd.Text = rate + 22500
ElseIf textboxqitni.Text >= 250000 And textboxqitni.Text <= 500000 Then
difference = textboxqitni.Text - 250000
rate = difference * 0.3
textboxittd.Text = rate + 50000
ElseIf textboxqitni.Text >= 500000 And textboxqitni.Text <= 999999999999999 Then
difference = textboxqitni.Text - 500000
rate = difference * 0.32
textboxittd.Text = rate + 125000
End If
End Sub
The first thing I suggest is to use a decimal datatype for your calculations.
It seems that your mathematical operations involve monetary values and in this case you should always use a decimal datatype to avoid floating point errors well documented.
Next problem is caused by the fact you think that a string containing only digits can be used in mathematical expressions. This is not true and works (sometime) only if you set Option Strict Off in your program options.
This settings was left to Off to facilitate the porting of VB6 programs to VB.NET and you should set it to ON for new code to avoid the subtle bugs introduced by automatic conversion of values.
You should always convert that string to a numeric variable, do the math with the numeric variable and then, if you need to display the result, convert back the number to a string.
Public Class Income_Tax
Dim rate As Decimal
Dim difference As Decimal
Private Sub textboxqitni_TextChanged(sender As Object, e As EventArgs) Handles textboxqitni.TextChanged
' Use a decimal variable to extract the current value typed
Dim value As Decimal
' You don't want to continue if the input is not a valid number
if Not decimal.TryParse(textboxqitni.Text, value) Then
MessageBox.Show("Not a valid number")
return
End If
' Use AndAlso to express logical AND
If value >= 0 AndAlso value <= 10000 Then
value = value * 0.05
' <= 10000 is already takes, the elseif should be for > 10000
ElseIf value > 10000 AndAlso value <= 30000 Then
difference = value - 10000
rate = difference * 0.1
value = rate + 500
ElseIf value > 30000 AndAlso value <= 70000 Then
difference = value - 30000
rate = difference * 0.15
value = rate + 2500
ElseIf value > 70000 AndAlso value <= 140000 Then
difference = value - 70000
rate = difference * 0.2
value = rate + 8500
' ..............................
' Complete with other else if
' ..............................
End If
' Finally set the value back to textbox
textboxittd.Text = value.ToString()
End Sub
Try this
Try
Dim tbval As Integer = Integer.Parse(textboxqitni.Text)
If tbval >= 0 And tbval <= 10000 Then
textboxittd.Text = tbval * 0.05
ElseIf tbval >= 10000 And tbval <= 30000 Then
difference = tbval - 10000
rate = difference * 0.1
textboxittd.Text = rate + 500
ElseIf tbval >= 30000 And tbval <= 70000 Then
difference = tbval - 30000
rate = difference * 0.15
textboxittd.Text = rate + 2500
ElseIf tbval >= 70000 And tbval <= 140000 Then
difference = tbval - 70000
rate = difference * 0.2
textboxittd.Text = rate + 8500
ElseIf tbval >= 140000 And tbval <= 250000 Then
difference = tbval - 140000
rate = difference * 0.25
textboxittd.Text = rate + 22500
ElseIf tbval >= 250000 And tbval <= 500000 Then
difference = tbval - 250000
rate = difference * 0.3
textboxittd.Text = rate + 50000
ElseIf tbval >= 500000 And tbval <= 999999999999999 Then
difference = tbval - 500000
rate = difference * 0.32
textboxittd.Text = rate + 125000
End If
Catch ex As Exception
MsgBox("Error Occured" & vbCrLf & ex.Message)
End Try
I have a series of functions and procedures that I've used to set specific values. How do I form a calculation based on these functions and procedures? Thanks.
Function DetermineBasePrice(ByVal baseRate As Decimal) As Decimal
' This function will determine the hairdresser base price
If radJane.Checked Then
baseRate = 30.0
End If
If radPat.Checked Then
baseRate = 45.0
End If
If radRon.Checked Then
baseRate = 40.0
End If
If radSue.Checked Then
baseRate = 50.0
End If
If radLaura.Checked Then
baseRate = 55.0
End If
Return baseRate
End Function
Function DetermineServicePrice(ByVal baseRate As Decimal) As Decimal
' This function will add each selected service price onto the current Base Price variable
If chkCut.Checked Then
baseRate += 30.0
End If
If chkColour.Checked Then
baseRate += 40.0
End If
If chkExtensions.Checked Then
baseRate += 50.0
End If
If chkHighlights.Checked Then
baseRate += 200.0
End If
Return baseRate
End Function
Sub DetermineClientTypeDiscount(ByRef discount As Decimal)
' This procedure will determine the client type discount rate
Dim totalPrice As Decimal
If radAdult.Checked Then
discount = 0
ElseIf radChild.Checked Then
discount = totalPrice * 0.1
ElseIf radStudent.Checked Then
discount = totalPrice * 0.05
ElseIf radSenior.Checked Then
discount = totalPrice * 0.15
End If
End Sub
Sub DetermineVisitDiscount(ByRef additionalDiscount As Decimal, ByVal intClientVisits As Integer)
' This procedure will determine the visit discount rate
Dim clientVisits As Integer
If clientVisits >= 1 And clientVisits <= 3 Then
additionalDiscount = 0
ElseIf clientVisits >= 4 And clientVisits <= 8 Then
additionalDiscount = totalPrice * 0.05
ElseIf clientVisits >= 9 And clientVisits <= 13 Then
additionalDiscount = totalPrice * 0.1
ElseIf clientVisits >= 14 Then
additionalDiscount = totalPrice * 0.15
End If
End Sub
Function DetermineBasePrice() As Decimal
If radJane.Checked Then
return 30.0
End If
If radPat.Checked Then
return 45.0
End If
If radRon.Checked Then
return 40.0
End If
If radSue.Checked Then
return 50.0
End If
If radLaura.Checked Then
return 55.0
End If
Return 0
End Function
Function DetermineServicePrice(ByVal baseRate As Decimal) As Decimal
If chkCut.Checked Then
baseRate += 30.0
End If
If chkColour.Checked Then
baseRate += 40.0
End If
If chkExtensions.Checked Then
baseRate += 50.0
End If
If chkHighlights.Checked Then
baseRate += 200.0
End If
Return baseRate
End Function
Function DetermineClientTypeDiscount(ByVal baseRate As Decimal) as Decimal
If radAdult.Checked Then
return = 0
ElseIf radChild.Checked Then
return baseRate * 0.1
ElseIf radStudent.Checked Then
return baseRate * 0.05
ElseIf radSenior.Checked Then
return baseRate * 0.15
End If
End Function
Function DetermineVisitDiscount(ByVal totalPrice As Decimal, ByVal intClientVisits As Integer) as Decimal
If intclientVisits >= 1 And intclientVisits <= 3 Then
return 0
ElseIf intclientVisits >= 4 And intclientVisits <= 8 Then
return totalPrice * 0.05
ElseIf intclientVisits >= 9 And intclientVisits <= 13 Then
return totalPrice * 0.1
ElseIf intclientVisits >= 14 Then
return totalPrice * 0.15
End If
End Function
Ok, so after rewriting all your functions/subs we come out with these new ones. And here is how you would access them now
Dim totalPrice As Decimal = DetermineServicePrice(DetermineBasePrice())
Dim discount As Decimal = DetermineClientTypeDiscount(totalPrice)
Dim CustomerVisits As Integer = 1 'fill with where you are getting the visit count for the customer
Dim AdditionalDiscount As Decimal = DetermineVisitDiscount(totalPrice, CustomerVisits)
Dim FinalPrice as Decimal = totalPrice - discount - AdditionalDiscount
The only reason I broke it down into discount and AdditionalDiscount was just in case you were wanting to display these totals somewhere. Also I was not sure if you were wanting to apply the discounts in a certain order or apply them all at the end as I did. But here is a possible solution to your problem. Hope it helps. Next time please explain your question a little better and if you can't code it then try to write it in more detail exactly what you are trying to do.
I am trying to write some code that says if textbox1 is equal to 0 between 10 then HandDecimal = 1. Else if textbox1 is equal to 10.1 through 100, then HandDecimal = 3. Else if textbox1 is equal to 100.1 and greater than HandDecimal = 5.
Here is my code, but it does not seem to work for me.
If WeightDecimal = 0 <= 10 Then
HandDecimal = 1
ElseIf WeightTextBox.Text = 10 <= 100 Then
HandDecimal = 3
ElseIf WeightTextBox.Text >= 100.1 Then
HandDecimal = 5
End If
How do I have to change the code to make it work?
Dim weight as Decimal = Decimal.Parse(WeightTextBox.Text)
If weight >= 0 AndAlso weight <= 10 Then
HandDecimal = 1
ElseIf weight > 10 AndAlso weight <= 100 Then
HandDecimal = 3
ElseIf weight > 100 Then
HandDecimal = 5
End If
Select Case statement with To operator
Select Case WeightDecimal
Case 0 To 10
HandDecimal = 1
Case 10.1 To 100
HandDecimal = 3
Case Else
HandDecimal = 5
End Select
I'm working on an assignment where the program needs to calculate and display the total cost for shipping a package, based on weight and whether it is being shipped to Continental U.S., Alaska, or Hawaii. When I click the Calculate button, though, the label that is supposed to display the total is left blank. I've looked through this and tried placing the calculation in different parts/at the end of the "If" statements. Here's what I have thus far, any help would be appreciated:
Dim decWeight As Decimal
Dim decTotalCost As Decimal
Dim decDestination As Decimal
Dim decRate As Decimal
If IsNumeric(txtWeight.Text) Then
decWeight = Convert.ToDecimal(txtWeight.Text)
If decWeight <= 30 > 0 Then
If radContinental.Checked Then
decDestination = 1
ElseIf radHawaii.Checked Then
decDestination = 1.2
ElseIf radAlaska.Checked Then
decDestination = 1.26
End If
If decWeight <= 2 Then
decRate = 3.69
ElseIf decWeight <= 4 > 2 Then
decRate = 4.86
ElseIf decWeight <= 6 > 4 Then
decRate = 5.63
ElseIf decWeight <= 8 > 6 Then
decRate = 5.98
ElseIf decWeight <= 10 > 8 Then
decRate = 6.28
ElseIf decWeight <= 30 > 10 Then
decRate = 15.72
End If
decTotalCost = decRate * decDestination
lblTotalCost.Text = decTotalCost.ToString("C")
ElseIf decWeight <= 0 Then
MsgBox("Please Enter a Positive Weight.", , "Input Error")
ElseIf decWeight > 30 Then
MsgBox("You Have Entered " & decWeight.ToString() & ". Please Enter a Weight Under 30 Pounds", , "Input Error")
End If
ElseIf txtWeight.Text = "" Then
MsgBox("Please Enter the Weight", , "Input Error")
Else : MsgBox("Please Enter a Number", , "Input Error")
End If
You should try this if statement: If decWeight <= 30 and decWeight > 0 Then
This will check if the decWeight is less than or equal to 30 and make sure that it is 'non-zero' Hope this helps :-)