I have Option Strict On. The code below does not work when I it is on. I was able to isolate the issue to this line
Decimal.TryParse(lblAnnualMid.Text, decAnnualMid)
Because this line is not changing the value from text to decimal, the rest of my code does not work and my labels display $0.
How can I fix this. I am still feeling my way through VB.Net so if this seems obvious, please forgive me.
Here is the rest of my code:
Option Strict On
Option Explicit On
Public Class frmCustomRanges
'Variables for the MidPoint TextBoxes
Dim decAnnualMid As Decimal
Dim decHourlyMid As Decimal
Private Sub txtRangeSpread_TextChanged(sender As Object, e As EventArgs) Handles txtRangeSpread.TextChanged
'This event runs when the user enters a number in the
'txtRangeSpread text box. The amount is converted to a decimal
'it then calculates the min and max of the range for annual
'and hourly ranges. The ranges change as the user changes the range
'spread.
'Variables for the event
Dim decRangeSpreadResults As Decimal
'Verify entry is numeric
If IsNumeric(txtRangeSpread.Text) Then
'Convert entry to decimal
Dim decRangeSpread As Decimal = Convert.ToDecimal(txtRangeSpread.Text)
'convert the Mid point value to decimal
Decimal.TryParse(lblAnnualMid.Text, decAnnualMid)
'convert range spread value to percentage
decRangeSpreadResults = decRangeSpread / 100
'Display results in dollar string Annual salary
lblAnnualMin.Text = Convert.ToDecimal(decAnnualMid - (decRangeSpreadResults * decAnnualMid)).ToString("C")
lblAnnualMax.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid)).ToString("C")
''Display results in dollar string in Hourly rate
lblHourlyMin.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid) / 52 / 40).ToString("C")
lblHourlyMax.Text = Convert.ToDecimal(decAnnualMid + (decRangeSpreadResults * decAnnualMid) / 52 / 40).ToString("C")
Else
MsgBox("You have entered a non-numeric value. Please check value and enter again", vbCritical, "Input Error")
With txtRangeSpread
.Text = ""
.Focus()
End With
End If
End Sub
what you want in fact would be this
decimal.TryParse("$35,000",NumberStyles.Currency ,null , out test)
ex:
using System;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
decimal test;
Console.WriteLine(decimal.TryParse("$35,000",NumberStyles.Currency ,null , out test));
Console.WriteLine(test);
Console.Read();
}
}
}
more information about NumberStyles
I changed my line to:
Decimal.TryParse(lblAnnualMid.Text.Replace("$", ""), decAnnualMid)
this worked perfect.
thank you all.
Related
in Vb.net how to get the number after decimal places.
I tried below code.
Dim number As Decimal = 143.500
Dim wholePart As Integer = Decimal.Truncate(number)
Dim fractionPart As Decimal = number - wholePart
Dim secondPart3 As Integer
secondPart3 = Replace(fractionPart, "0.", "0")
then the result is coming 500, but when i tried 143.050 its giving 50 it should show 050
Thanks
Thanks everyone. i got it with sample below code
Dim numar As Double
If Double.TryParse(TextBox1.Text, numar) Then
Dim rmndr As Double
rmndr = numar Mod 1
If rmndr = 0 Then
Else
TextBox2.Text = Split(CStr(TextBox1.Text), ".")(1)
End If
End If
Your solution (here) is unnecessarily complex. You were on the right track in your original post, but conflated numeric values with formatted string values. Because while 050 are 50 are the same numeric value, when you implicitly call ToString on the value (or explicitly with the wrong formatting) then you would always get 50 because the prefixing 0 is unnecessary when working with numeric values.
What you should do is:
Get the integral digits of the decimal value
Convert the underlying decimal value to a String
(optionally) Format the String specifying the level of precision
Drop the integral digits off converted string
Here is an example:
Private Function GetFractionalDigits(value As Decimal) As String
Dim integralDigits = Decimal.Truncate(value)
Return value.ToString().Remove(0, integralDigits.ToString().Length + 1)
End Function
Private Function GetFractionalDigits(value As Decimal, precisionSpecifier As Integer) As String
If (precisionSpecifier < 0) Then
Throw New ArgumentOutOfRangeException("precisionSpecifier", "precisionSpecifier cannot be less than 0")
End If
Dim integralDigits = Decimal.Truncate(value)
Return value.ToString("N" & precisionSpecifier).Remove(0, integralDigits.ToString().Length + 1)
End Function
Fiddle: https://dotnetfiddle.net/SBOXG0
I have a program in VBA in which I'd like the user to only enter a number. I want to be able to catch when they they enter a string and have them try again. This is what I've tried:
Sub getInterest()
annualInterest = InputBox("Please enter your annual interest rate as a decimal. ")
If TypeOf annualInterest Is Double Then
'Continue with program
Else
Call getInterest()
End If
End Sub
But this doesn't work.
IsNumeric returns a boolean & doesn't tell you what the type of data user entered, only if it passed or failed numeric check. And while it may work in your case another option is VarType function.
VarType function returns an Integer indicating the subtype of a variable
Sub getInterest()
annualinterest = InputBox("Please enter your annual interest rate as a decimal. ")
If VarType(annualinterest) = vbDouble OR VarType(annualinterest)=vbSingle Then
'crunch interest
Else
getInterest
End If
End Sub
Try something like this...
Sub getInterest()
Dim annualInterest As Double
Do While annualInterest = 0
annualInterest = Application.InputBox("Please enter your annual interest rate as a decimal.", "Annual Interest Rate!", Type:=1)
Loop
MsgBox annualInterest
End Sub
Your syntax in second row is wrong. please try below code. Code will proceed only if user input is a valid number.
Sub getInterest()
annualinterest = InputBox("Please enter your annual interest rate as a decimal. ")
If IsNumeric(annualinterest) Then
'Continue with program
Else
Call getInterest
End If
End Sub
I think you can simply force a numeric entry in Excel VBA by using the existing parameters.
annualInterest = Application.InputBox("Please enter your annual interest rate as a decimal. ", , , , , , , 1)
It will ensure a valid numeric entry and can save the call.
I am taking a VBA class and am completely stuck on this problem. We CANNOT use the masked text box, which would solve this problem. Instead the professor actually wants me to learn the code, can you imagine?
All kidding aside, the user needs to enter a gas price into a text box, then hit calculate to receive the total cost of the trip. There is much more to the interface but will spare you the details. If a user enters anything else number than a positive number with one decimal place, it should return an error. I have figured out 0 or 0000 as well as a negative number such as -3.45. Now I have to get any text or special characters to give me an error as well as something like 34.56.12.45. You never know, a user may feel the need to type in their IP address. The key to the assignment is that I catch all probable user errors.
Here is what I've written for the calculation as well as catch the errors. I have tried the Try/Catch statements as well. Nothing worked but I got the first two parts of the IF statement to work yet always failing on the last IF part until it gets to the calculation.
Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click
Dim Mileage As Decimal
Dim Miles As Decimal
Dim GasPrice As Decimal
Dim Cost As Decimal
If CDec(txtbxGasPrice.Text) = 0 Then
MessageBox.Show("Please enter a positive dollar amount")
txtbxGasPrice.Text = String.Empty
End If
If CDec(txtbxGasPrice.Text) < 0 Then
MessageBox.Show("Please enter a positive dollar amount")
txtbxGasPrice.Text = String.Empty
End If
If Cost = CDec((Miles / Mileage) * GasPrice) Then
Miles = CDec(lblTMiles.Text)
Mileage = CDec(lblMileage.Text)
GasPrice = CDec(txtbxGasPrice.Text)
lblTotalCost.Text = Cost.ToString("C2")
End If
If CBool(txtbxGasPrice.Text = "") Then
MsgBox("You must enter a dollar amount")
End If
*If Not IsNumeric(txtbxGasPrice.Text) Then
MessageBox.Show("Please enter a positive dollar amount")
txtbxGasPrice.Text = String.Empty*
End If
End Sub
'I have placed this at the top, in the middle, at the bottom but no luck. What am I missing?
Appreciate your thoughts - Lauren
This one seems to meet your criteria and pass David's tests:
Function IsValid(txt As String) As Boolean
If Not IsNumeric(txt) Then
Exit Function
End If
If Len(txt) < 2 Then
Exit Function
End If
If Not Mid(txt, Len(txt) - 1, 1) = "." Then
Exit Function
End If
If Not txt > 0 Then
Exit Function
End If
IsValid = True
End Function
This seems like a perfect application of regular expressions, but could be out of scope for this problem, maybe even better though vb has a Decimal.TryParse(or parse) that will take a string and try to parse it to a decimal.
http://msdn.microsoft.com/en-us/library/system.decimal.tryparse.aspx
on a side not I'm not 100% sure how it acts with xx.xx.xx but I'm betting it will fail and help your problem
I'm going to expand on CSgoose's idea to use RegEx, it seems a lot more reliable. I am very, very green when it comes to using RegEx but I try to work on Q's here at SO, so this may not be the optimal pattern to match, but a function like this seems to do the trick when I test a few value.
0/0.0/0.00 = False
-1.5 = False
1.5 = True
5.45 = False
Steve = False
Steve.6 = False
Steve6.58 = False
6.574.2 = False
A value that evaluates to 0 will return false. Negative values return false. Value must have a decimal component, be comprised of any # of digits (this can be tweaked if you want to limit it, eg., to ##.# format, etc.). Matches full text only, so things like IP addresses won't return true, etc.
NOTE This is VBA, but should be easily adaptable for your purposes)
Sub YourSub()
If Not IsMatch(CStr(txtbxGasPrice.Text)) Then
MsgBox "Please ensure that the value you enter is a positive dollar amount, to 1 decimal place!", vbCritical, "Invalid Gas Price Value!"
End IF
End Sub
This function requires enabling reference to Microsoft VBScript Regular Expressions 5.5, or you could use late-binding.
Function IsMatch(str As String) As Boolean
'Tests for a positive numeric value, formatted 0.0 with a mandatory decimal component
' exact match only
Dim re As RegExp
Dim allMatches As MatchCollection
Dim retVal As Boolean
retVal = False 'by default
If Not IsNumeric(str) Then GoTo EarlyExit 'ignore any non-numeric value
Set re = New RegExp
re.Pattern = "\d*\.[0-9]"
Set allMatches = re.Execute(str)
If allMatches.Count = 1 Then
'If there are multiple matches, then I think safe to say it's not a match,
' make sure it's a full string match
If str > 0 Then
retVal = (allMatches(0) = str)
End If
End If
EarlyExit:
Set re = Nothing
IsMatch = retVal
End Function
Update to force, for example, ##.# format, you could do
re.Pattern = "[1-9]?\d\.\d"
When I try to run the program to calculate payment and total intrest I get "Conversion from string "" to type 'Double' is not valid."
What am I doing wrong?
Dim P As Double
Dim R As Double
Dim N As Double
Dim Payment As Double
Dim totalInterest As Double
Private Sub btnAnalyze_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnalyze.Click
P = CDbl(txtAmount.Text)
N = CDbl(txtDuration.Text)
R = CDbl(txtInterestRate.Text)
Payment = (P * R) / (1 - (1 + R) ^ (-N))
totalInterest = (N * Payment) - P
Payment = CDbl(txtPayment.Text)
totalInterest = CDbl(txtInterest.Text)
If P < 0 Then
MessageBox.Show("Please enter in loan amount")
End If
If R <= 0 Then
MessageBox.Show("Please enter in loan amount")
End If
If N <= 0 Then
MessageBox.Show("Please enter in loan amount")
End If
End Sub
End Class
One of your TextBox items has not been filled in.
As such, when you use CDbl, such as P = CDbl(txtAmount.Text), if the TextBox is empty, it will cause this error.
A better option would be to use Double.TryParse instead of CDbl, as it will allow you to raise a proper message:
Private Sub btnAnalyze_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnalyze.Click
If Not Double.TryParse(txtAmount.Text, P) Then
MessageBox.Show("Please correct the loan amount")
Exit Sub
End If
' Do the same for all other CDbl checks
I know this original question is old, but it's trending on Google.
Everyone has been right, to a degree, so far.. The CDbl function you were attempting doesn't handle blanks very well (it blows up). In some cases (mine specifically) TryParse isn't an option (see below for 'why' along with true solution)
IF, however, you are expecting numbers in the data, and receiving an error isn't possible (long story short, that is my context) then you HAVE to use CDbl, since there isn't another conversion method that can be used in a single expression (again, my context).
In my case, since i wasn't able to declare variables, i found an elegant solution this problem. I did it with a concatenator, in my case (I'm using vb.net ) it was CDbl("0" + txtAmount.Text) where P is the original data your testing for, and then R and N, etc.
This does what Val() used to do, by defaulting a leading zero, you have not changed any of the data within the variable, but have only solved blanks. There are more wholistic solutions, but I couldn't utilize those since I only had access to "one-liners" so-to-speak
I'd say it is simply because you want:
txtPayment.Text = CStr(Payment)
txtInterest.Text = CStr(totalInterest)
instead of
Payment = CDbl(txtPayment.Text)
totalInterest = CDbl(txtInterest.Text)
Instead of CDbl(),use Val() of function it converts the string into 0 default,if the text box is empty. Then runtime error may not come..
I want to display a number in a textbox within an excel form. report, however I only want to show any decimal points if they are present and the I only want to show 2 decimal places.
e.g. if the number is 12 then I want to show 12
If the number is 12.1 then I want to show 12.10
If the number is 12.126 then I want to show 12.13
At the moment i have the below code and it is not showing me decimal points:
Me.Amount.Value = Format(Me.Amount, "#,###")
You could write a function to conditionally return one of two format strings:
Function GetFormatString(varValue As Variant) As String
Dim dblValue As Double
If IsNumeric(varValue) Then
dblValue = CDbl(varValue)
If dblValue = Int(dblValue) Then
GetFormatString = "#,###"
Else
GetFormatString = "#,###.00"
End If
End If
End Function
Private Sub Amount_AfterUpdate()
Dim strFormat As String
strFormat = GetFormatString(Me.Amount.Value)
Me.Amount.Value = Format(Me.Amount.Value, strFormat)
End Sub