[2008] simple question with my if statement.
hey
I have made an if statement for when i error check for fields which are supposed to have numbers in it. Atm, my statement says that if either of the text boxes are blank display error and if they have 2 numbers work out the answer. I was wondering how i can get the code to display an error message (msgbox) when both the fields are text. I know for numbers it is "isnumeric" but i cant figure out how to say if it is text.
when one of the text boxes is a letter, it displays error because the other one is blank, but if the first one has a letter and the second one has any character it doesnt display the error
I only need that little bit and i should be able to put it in >.< its been plaguing me haha
thanks in advance
josh
Private Sub btnCalculate1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate1.Click
Message = txtNumber1.Text + "+" + txtNumber2.Text
number1 = Val(txtNumber1.Text)
number2 = Val(txtNumber2.Text)
If IsNumeric(txtNumber1.Text) And IsNumeric(txtNumber2.Text) Then
txtAnswer1.Text = Message + " = " + Str(number1 + number2)
ElseIf (txtNumber1.Text = "" Or txtNumber2.Text = "") Then
MsgBox("Please enter a valid number")
End If
End Sub
Re: [2008] simple question with my if statement.
Something along these lines will work:
Code:
Private Sub btnCalculate1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate1.Click
Dim valid As Boolean = True
If Not EntryIsValid(Me.txtNumber1.Text) Then
valid = valid And False
End If
If Not EntryIsValid(Me.txtNumber2.Text) Then
valid = valid And False
End If
If valid then
'do what needs to be done if the entries are valid
Else
'do what needs to be done if the entries were not numbers
End If
End Sub
Private Function EntryIsValid(ByVal value As String) As Boolean
Dim result As Single = 0
If Single.TryParse(value, result) Then
Return True
End If
Return False
End Function
Alterantively, since we aren't using the variable 'result' you can use this:
Although, the intermediate code will make up a variable for you.
Code:
Private Function EntryIsValid(ByVal value As String) As Boolean
If Single.TryParse(value, Nothing) Then
Return True
End If
Return False
End Function
Re: [2008] simple question with my if statement.
Thanks, ill go through this, and see if i can understand it all lol (still new to VB)
I think i understnad the code, just some parts i havent seen before :) thanks again
Re: [2008] simple question with my if statement.
i figured out how the first part of the code works, but i didn't understand where
Code:
Private Function EntryIsValid(ByVal value As String) As Boolean
came from
alternately i found out how to make my code work by adding something to it from a line in yours
Code:
ElseIf Not IsNumeric(txtNumber1.Text) Or Not IsNumeric(txtNumber2.Text) Then
just using Not isnumeric made it work
thanks heaps
Re: [2008] simple question with my if statement.
IsNumeric is a leftover from older versions of Basic, kept for legacy support, and shouldnt really be used. Same goes for Val() :)
Re: [2008] simple question with my if statement.
Haha ok, well ill try and get out of the habit of using it then. But i dont know much else lol Thanks
Re: [2008] simple question with my if statement.
I'd be inclined to keep using it in this case. There are a whole crowd of replacements for Val, but I don't know a clean replacement for IsNumeric. Replacing a built-in function with a self-rolled function just doesn't seem very satisfying.
Re: [2008] simple question with my if statement.
Oops...should have been Double.TryParse
http://support.microsoft.com/kb/329488
Code:
Private Function EntryIsValid(ByVal value As String) As Boolean
Dim result As Double = 0
If Double.TryParse(value, result) Then
Return True
End If
Return False
End Function
Re: [2008] simple question with my if statement.
I had written the Single.TryParse method (way of doing it) for an application in which the numbers would always be small.
But still Shaggy is correct. :wave:
Re: [2008] simple question with my if statement.
Quote:
Originally Posted by Shaggy Hiker
I'd be inclined to keep using it in this case. There are a whole crowd of replacements for Val, but I don't know a clean replacement for IsNumeric. Replacing a built-in function with a self-rolled function just doesn't seem very satisfying.
The reason Double.TryParse was created in the first place was to improve the performance of IsNumeric. Originally IsNumeric called Double.Parse and caught the exception if it failed. This was a slow process and if IsNumeric failed a lot it created significant lag. They therefore created the Double.TryParse method to speed things up.
It was such a hit that they decided to add similar methods to other types. The IsDate function now uses Date.TryParse as well.
One issue with IsNumeric is that it parses the value to determine whether it is a valid representation of a number. That means that doing something like this:
vb.net Code:
If IsNumeric(myString) Then
myNumber = Convert.ToDouble(myString)
End If
is wasteful because you're parsing the same string twice. If you only want to know whether a value is numeric or not then IsNumeric is cool, but if you actually want the numeric value then don't use it. It uses Double.TryParse internally so just use Double.TryParse yourself.
The other issue is that you cannot specify any format for what's acceptable in a number. In general this is not an issue but but in many cases you need the flexibility of a TryParse method, which lets you specify the type to convert to and the formats that are acceptable.
Re: [2008] simple question with my if statement.
IsNumeric predated Double.Parse, unless that was still around in VB6. Was it re-written? What am I missing here?
Re: [2008] simple question with my if statement.
Quote:
Originally Posted by Shaggy Hiker
IsNumeric predated Double.Parse, unless that was still around in VB6. Was it re-written? What am I missing here?
Remember that all the VB6-esque function in the VB.NET Runtime are NOT VB6 functions. They are VB.NET functions with the same names as VB6 functions and implemented in such a way as to produce the same behaviour.
When they came to implement IsNumeric in VB.NET they originally did so by calling Double.Parse and catching the exception if it failed. As I said, performance was terrible so Double.TryParse was born, specifically to support the VB.NET implementation of IsNumeric.
Re: [2008] simple question with my if statement.
So there was no particular optimization?
Ok, I just tested this out. IsNumeric is significantly slower than using Double.TryParse directly, though there would be some overhead to the function call the way FourBlades has it, it may well be that the function call overhead is less than the penalty for using IsNumeric.
In further testing, I found that when MS says parse, they mean parse. If the string truly is numeric, then the length of the string is directly related to the time taken by either the IsNumeric or the Double.TryParse function. However, if the string is not numeric, then the time taken is determined by where the first non-numeric character is in the string starting from the left. Therefore, the string is being parsed from most significant to least significant, and parsing ends as soon as the first non-numeric character is encountered, or the end of the string is reached.
Lastly, both functions are faster if the result is true than if it is false.
However, upon examining the IL, the Double.TryParse line calls the function of the same name with this line:
IL_0007: call bool [mscorlib]System.Double::TryParse(string,
float64&)
However, IsNumeric doesn't quite do that. If it is calling Double.TryParse, it is buried under another layer, which would account for the slower operation of the IsNumeric call:
IL_0005: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Versioned::IsNumeric(object)
By the way, for my testing, I called each in a loop of 40,000 iterations, and the difference was only in the vicinity of a 10-30% penalty for IsNumeric. What this means is: It really doesn't matter. Double.TryParse is faster, but the difference is so small you will never see it. The other thing this means is that I'm a geek for even having a test bed app where I can look at minutiae like this.
Re: [2008] simple question with my if statement.
Hey Shaggy Hiker,
I am glad that there are geeks like you otherwise how would we even know whether to use a function like IsNumeric versus Double.TryParse.
Re: [2008] simple question with my if statement.
When my programs start to become more sophisticated, i will start using double.parse, first i need to learn it properly lol :)
thanks to all
Re: [2008] simple question with my if statement.
The best way I find to work out what a method does is look it up in .NET Reflector. Here's IsNumeric:
vb.net Code:
Public Shared Function IsNumeric(ByVal Expression As Object) As Boolean
Dim num As Double
Dim convertible As IConvertible = TryCast(Expression,IConvertible)
If (convertible Is Nothing) Then
Dim chArray As Char() = TryCast(Expression,Char())
If (chArray Is Nothing) Then
Return False
End If
Expression = New String(chArray)
End If
Dim typeCode As TypeCode = convertible.GetTypeCode
If ((typeCode <> TypeCode.String) AndAlso (typeCode <> TypeCode.Char)) Then
Return Information.IsOldNumericTypeCode(typeCode)
End If
Dim str As String = convertible.ToString(Nothing)
Try
Dim num2 As Long
If Utils.IsHexOrOctValue(str, (num2)) Then
Return True
End If
Catch exception As StackOverflowException
Throw exception
Catch exception2 As OutOfMemoryException
Throw exception2
Catch exception3 As ThreadAbortException
Throw exception3
Catch exception6 As Exception
Return False
End Try
Return DoubleType.TryParse(str, (num))
End Function
As you can see, it's fairly convoluted. That's the case for a lot of Runtime functions because they are always implemented to produce the same behaviour as they did in VB6, whatever that takes. As you can see, the last line of IsNumeric, which may not be reached, calls DoubleType.TryParse. The DoubleType class is declared in the Microsoft.VisualBasic.CompilerServices namespace speciifcally to support the VB language. It is NotInheritable and has only a Private constructor, so you cannot create an instance. Here's the implementation of DoubleType.TryParse:
vb.net Code:
Friend Shared Function TryParse(ByVal Value As String, ByRef Result As Double) As Boolean
Dim flag As Boolean
Dim cultureInfo As CultureInfo = Utils.GetCultureInfo
Dim numberFormat As NumberFormatInfo = cultureInfo.NumberFormat
Dim normalizedNumberFormat As NumberFormatInfo = DecimalType.GetNormalizedNumberFormat(numberFormat)
Value = Utils.ToHalfwidthNumbers(Value, cultureInfo)
If (numberFormat Is normalizedNumberFormat) Then
Return Double.TryParse(Value, NumberStyles.Any, DirectCast(normalizedNumberFormat, IFormatProvider), Result)
End If
Try
Result = Double.Parse(Value, NumberStyles.Any, DirectCast(normalizedNumberFormat, IFormatProvider))
flag = True
Catch exception As FormatException
Try
flag = Double.TryParse(Value, NumberStyles.Any, DirectCast(numberFormat, IFormatProvider), Result)
Catch exception2 As ArgumentException
flag = False
End Try
Catch exception3 As StackOverflowException
Throw exception3
Catch exception4 As OutOfMemoryException
Throw exception4
Catch exception5 As ThreadAbortException
Throw exception5
Catch exception6 As Exception
flag = False
End Try
Return flag
End Function
As you can see, that's where the call to Double.TryParse is located. So, as Shaggy pointed out, performance really depends on what you're testing. Some values will return True almost immediately while others will take a relatively long time to be confirmed as either numeric or not.
Re: [2008] simple question with my if statement.
After looking at that, it appeared that passing an empty string to IsNumeric might perform better than passing an empty string to Double.TryParse, but that was not the case. In my test, IsNumeric took 50ms longer than Double.TryParse when a single character was passed in, and 45ms longer if an empty string was passed in, but as a percentage, IsNumeric took 50% longer for an empty string, and only about 45% longer for a single character string. Of course, this test is for 40k iterations, and there is plenty of overhead for the testing, and differences in processors, so absolute numbers are meaningless. The percentage should be fairly portable, though.
I was a bit surprised by those results. It sure looks like Double.TryParse does more work before even checking to see that it received an argument, yet that doesn't appear to be the case if an empty string is passed in.
On the other hand, IsNumeric is more than twice as fast as Double.TryParse if the argument is Nothing. On the other hand, Double.TryParse takes about one tenth the time if the argument is Nothing than it takes if the argument is a single character.
Re: [2008] simple question with my if statement.
Upon reflection, I believe we have now beaten this question beyond death to the point where it may be turning into a black hole.