I have strings stored in an array and need to check if the 5th character of each string is a number or not. The code I used is:
If Mid(arr(i), 5, 1) = IsNumeric(True) Then
MsgBox("Number")
End If
It is giving an error:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Boolean' is not valid.
You originally tagged your question as vba, but VBA doesn't throw System.InvalidCastException, or any other exception for that matter; vb.net does.
IsNumeric(True) returns True if True is numeric. You want to verify if the string retrieved from the array is numeric; give it the string retrieved from the array as a parameter:
If IsNumeric(Mid(arr(i), 4, 1)) Then
MsgBox("Number")
End If
Your code reads like VB6/VBA though, because of this:
Imports Microsoft.VisualBasic
That namespace contains VB6-like things that you don't need to use at all. The beauty of .net is that everything is an object, so assuming the array is an array of String, you can call the actual String instance methods instead of VB6's Mid function.
Dim theFifthCharacter As String = arr(i).Substring(4, 1)
Or, because you're only interested in 1 character, and a String is itself an IEnumerable(Of Char), you can do this:
Dim theFifthCharacter As Char = arr(i)(4)
Notice the off-by-one - in .net indices start at 0, so if you want the 5th item you'll fetch index 4.
Now, if you want to see if it's numeric, you can try to parse it:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
Else
'non-numeric: digitValue contains an Integer's default value (0)
End If
Lastly, if you want a message box, use WinForms' MessageBox instead of VB6's MsgBox:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
MessageBox.Show(string.Format("Number: {0}", digitValue))
Else
'non-numeric: digitValue contains an Integer's default value (0)
MessageBox.Show("Not a number")
End If
A more correct way to do this would be:
If Char.IsDigit(arr(i)(4)) Then
Your syntax is incorrect. It should be:
If IsNumeric(Mid(arr(i), 5, 1)) Then
Related
I do not understand at all how to use TryCast in my code, but it is something I need to use for validating user input. I have done various searches and looked at various questions on here, but no one seems to actually say how to use it, and the MSDN website doesn't seem to help at all.
Function ValidateInput(Var_In As String) As Integer
If TryCast(Var_In, Integer) = Nothing Then
Return vbNull
Else
Return Var_In
End If
End Function
The error says that
The operand must be of reference type but Integer is of value type
What is the explanation of what I have done wrong?
TryParse doesn't accept more than 10 digits so for example, an input of "12345678901" won't be accepted. How do I fix this?
Let's try to understand the differences between TryCast, Convert and TryParse.
TryCast
This function will attempt to convert one object into another type, as long as it is a reference type.
Dim MyNewObject = TryCast(MyObject, MyReferenceClass)
If IsNothing(MyNewObject) Then
MessageBox.Show("Impossible to cast")
End If
Since Integer is a value type, it will not work, so we have to figure something out...
Convert
Convert Class on MSDN
From MSDN:
Converts a base data type to another base data type.
So we can try:
Dim myInt = Convert.ToInt32(MyObject)
The problem is that it will generate an exception InvalidCastException if it's impossible to do the conversion.
TryParse
This function is trying to convert a String into something you want. And it will not generate an exception:
Dim myInt As Integer = 0
If Not Integer.TryParse(MyString, myInt) Then
MessageBox.show("This is not an integer")
End If
Limitation
Converting a String into a Integer can sometimes be tricky... If the String represents a number that is greater or lesser than Integer.MaxValue and Integer.MinValue, you will end up with no conversion...
So you can go with a Double:
Double.TryParse(MyString, MyDouble)
Or personally, if you know that it will be a number, use Decimal:
Decimal.TryParse(MyString, MyDecimal)
See Decimals on MSDN
Decimal still has a Max and Min value, according to MSDN:
The Decimal value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The Decimal value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors.
Convert.ChangeType
This one is also interesting, but is a bit weird...
You are attempting to perform TryCast against an Integer, which is a value type. TryCast works only on reference types, such as (but not limited to) a Class, Object, or String type.
If you are trying to convert the input parameter to an Integer, you might try one of the methods in the Convert class, such as Convert.ToInt32() or Integer.TryParse.
Instead of TryCast, use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim iNum As Integer
If (Integer.TryParse(Var_In, iNum)) Then
Return iNum
Else
Return vbNull
End If
End Function
Much better is to use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim num as Integer
If Not Integer.TryParse(Var_In, num) Then
Return vbNull
Else
Return num
End If
End Function
I'm late to the discussion, but if anyone lands here (like I did) looking for a quick & dirty solution, here a function I'm using for simple cell validation in a DataGridView control.
Function TryTypeFit(theString As String, theType As Type, ShowError As Boolean) As Boolean
Dim TempReturn As Boolean = False
Dim TempObject As Object
Try
TempObject = Convert.ChangeType(theString, theType)
TempReturn = True
Catch ex As Exception
' didn't work
TempReturn = False
If ShowError Then
Dim eMessage As String = "Error: Value must be castable to a " & CStr(theType.Name)
MsgBox(eMessage)
End If
End Try
100:
Return TempReturn
End Function
I am doing this simple operation with a string in VB.NET
I have a string of information called segmentInfo looking like this:
XRT0034:3:89:23
So I am just trying to get a number out of it:
Dim rowNum As Integer = segmentInfo.split(":")(1)
And I am getting actually 2 warnings. Both warning are given on the same line of code.
Warning - Implicit conversion from 'String' to 'Integer'
Warning - Implicit conversion from 'String' to 'Char'
Maybe I could understand the first one, about the string to integer...but the second one?? I do not understand.
Anyway, can anybody tell me what I am doing wrong and how to fix it?
The Split method takes a Char (array) as a parameter, not a string. Hence:
.... segmentInfo.split(":"c)(1)
Secondly, you need to parse the resulting string to an integer:
Dim rowNum As Integer = Integer.Parse(segmentInfo.split(":"c)(1))
Do this only when you know that the string is a number. Otherwise, use TryParse.
No such overload method String.Split which take one parameter of type String
From MSDN String.Split Method
You can change to
Dim rowNum As Integer = segmentInfo.split(":"c)(1)
":"c - c is character of type Char Type Characters (Visual Basic)
For converting String to Integer use Int32.TryParse or Int32.Parse method to convert string to integer
Dim rowNum As Int32 = Int32.Parse(segmentInfo.split(":"c)(1))
'Exception will be thrown if string value not convertible to Integer type
Or
Dim rowNum As Int32
If Int32.TryParse(segmentInfo.split(":"c)(1), rowNum) = True Then
'Use succesfully converted integer value
Else
'Show message about invalid text
End If
You must parse it to integer form
Dim rowNum As Integer = Convert.ToInt32(segmentInfo.split(":")(1))
Dim rowNum As Integer = Integer.Parse(segmentInfo.split(":"c)(1))
I am trying to write a program where the user inputs a telephone number and a message is displayed if it contains a letter.
Module Module1
Sub Main()
Dim TelNumber As String
Dim Character As String
TelNumber = Console.ReadLine()
For Number = 0 To TelNumber.Length - 1
Character = TelNumber.Substring(Number)
If Integer.TryParse(Character, 0) <> 0 Then
Console.WriteLine("It cannot contain a letter")
Exit For
End If
Next
Console.ReadLine()
End Sub
End Module
However with this code even it only works properly if the string contains less than 11 charcaters, after that even if it does not contain any letters it still displays the message. How do I fix this? Also I don't understand what the second parameter of the Integer.TryParse function represents?
TelNumber.Substring(Number) does not just the Numberth character of the string.
It returns the string with Number characters stripped off its beginning.
Thus, in the first step of the loop, TelNumber.Substring(0) returns the whole string.
Then, Integer.TryParse() fails with integer overflow with long string.
Hint: simple string validation is a task for regular expressions.
With regular expressions it will also be very easy to extend tel.number format to something like +4915771828000 or 12-34-56.
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim telNumber As String = Console.ReadLine()
Dim telValidationRegex As Regex = New Regex("^\d+$")
If NOT telValidationRegex.Match(telNumber).Success Then
Console.WriteLine("Wrong telephone number format")
End If
Console.ReadLine()
End Sub
End Module
I don't have a compiler handy, but I can tell you what I think this should look like. First let's look at Int32.TryParse's documentation
result
Type: System.Int32
When this method returns, contains the 32-bit signed integer value equivalent of the number contained in s, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null or String.Empty, is not of the correct format, or represents a number less than MinValue or greater than MaxValue. This parameter is passed uninitialized.
So, the second parameter is supposed to be an integer variable that contains the result of trying to parse the string.
Then, let's look at substring
startIndex
Type: System.Int32
The zero-based starting character position of a substring in this instance.
So what you're doing isn't looking at each character and trying to convert it to an integer. It's looking at the whole number, and trying to convert that to an integer. Then the whole number, except for the first character, and trying to convert that to a number. And so on.
I suspect you'll find that Int32 can only store numbers about 10 digits long (2^32, or 4294967296)
What you want to do is look at each character, something like this.
Module Module1
//Warning, did not try to compile
Sub Main()
Dim TelNumber As String
Dim Character As String
TelNumber = Console.ReadLine()
For Number = 0 To TelNumber.Length - 1
Character = TelNumbert(Number)
Dim OutputNumber as Integer
If Not Integer.TryParse(Character, OutputNumber) Then
Console.WriteLine("It cannot contain a letter")
Exit For
End If
Next
Console.ReadLine()
End Sub
End Module
I have some customized string formats of double values. I need to convert these strings to double values at some point (Note that these strings may contain error messages other than numbers). So I first check if these strings are numbers, and if yes, then convert them to double. Isnumeric works for my first customized string format. But I found that is numeric cannot recognize percentage strings. I wonder why isnumeric understands () but cannot understand %. And what is the better way to convert "(100.00)" and "50%" to doubles other than Cdbl?
Private Format As String = "###,###,###,##0.00;(###,###,###,##0.00);0" 'negative values are in the format (number)
Private rateFormat as string="p"
Dim str1 as string=-100.0.Tostring(Format) 'str1=(100.0)
Dim str2 as string=0.5.Tostring(rateFormat) 'str2=50%
Dim value1,value2 as double
If isnumeric(str1)
value1=Cdbl(str1) 'True. value1=-100.0
else
value1=Double.MinValue
End If
If isnumeric(str2)
value2=cdbl(str2) 'False.value2=Double.Minvalue
else
value2=Double.MinValue
End If
First, IsNumeric and C<whatever> generally aren't used because they can provide unexpected outputs. Typically you would use Double.TryParse or Convert.ToDouble (or whatever type) because they reliably parses numbers as you would expect; you just have to make sure it's in the right format.
Also, those methods are more efficient because you can determine if a string is a number and parse it all in one go. Just note that Parse and Convert throw exceptions when the format is wrong.
Now, as far as I know, there's know built-in way convert from percent notation. I went ahead and wrote three methods (current culture, any culture, invariant culture) that tested fine with 0.5 and -0.5 on the four possible locations of the percent symbol.
'these will return Double.NaN if they fails
'this parses based on the current culture
Public Function ParseDoublePercent(ByVal input As String) As Double
Return ParseDoublePercent(input, System.Globalization.NumberFormatInfo.CurrentInfo)
End Function
'invariant culture
Public Function ParseDoublePercentInvariant(ByVal input As String) As Double
Return ParseDoublePercent(input, System.Globalization.NumberFormatInfo.InvariantInfo)
End Function
'this parses based on a specified culture
Public Function ParseDoublePercent(ByVal input As String, ByVal provider As IFormatProvider) As Double
If String.IsNullOrEmpty(input) OrElse input.Length < 3 Then Return Double.NaN 'minimum length of string is 2 (0%)
'get some information about how the percent should be formatted
Dim format As System.Globalization.NumberFormatInfo = System.Globalization.NumberFormatInfo.GetInstance(provider)
'how this will be parsed will first depend on if it's positive or negative
Dim isNegative As Boolean = input.Substring(0, 1) = "-"
Dim percentPattern As Integer = If(isNegative, format.PercentNegativePattern, format.PercentPositivePattern)
'i'm using convert.todouble because I don't want to use NumberStyles in Double.TryParse
Try
Select Case percentPattern
Case 0 'n %, such as -50.00 %, 50.00 %
Return Convert.ToDouble(
input.Replace(" " & format.PercentSymbol, "e-" & format.PercentDecimalDigits),
provider)
Case 1 'n%, such as -50.00%, 50.00%
Return Convert.ToDouble(
input.Replace(format.PercentSymbol, "e-" & format.PercentDecimalDigits),
provider)
Case 2 '%n, such as -%50.00, %50.00
'need to do some special parsing just in case there are incorrect percent signs in the middle of the number
'dont want to just replace all of them
Return Convert.ToDouble(
input.Remove(If(isNegative, 1, 0), 1) & "e-" & format.PercentDecimalDigits, provider)
Case 3 '% n, such as '%-50.00, % 50.00
Return Convert.ToDouble(input.Remove(0, 1) & "e-" & format.PercentDecimalDigits, provider)
Case Else
Return Double.NaN 'should not happen
End Select
Catch ex As FormatException 'an exception is thrown when the string fails to parse
Return Double.NaN
End Try
End Function
isnumeric returns a Boolean value indicating whether an expression can be evaluated as a number. In your case % is not a number, so the error. Try the following code.
If isnumeric(str2.Substring(0,str2.length-2))
IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort, or an Object that contains one of those numeric types. It also returns True if Expression is a Char or String that can be successfully converted to a number.
IsNumeric returns False if Expression is of data type Date or of data type Object and it does not contain a numeric type. IsNumeric returns False if Expression is a Char or String that cannot be converted to a number.
() is, in fact, a numeric format. It's used in bookkeeping to represent negative values, instead of "-".
See http://blog.accountingcoach.com/use-of-parentheses/, or
in fact, a numeric format.In your case % is not a number, so the error.
I am facing a problem with String.CopyTo() method.
I am trying to the copy the value from string to char array using String.CopyTo() method.
Here's my code
Dim strString As String = "Hello World!"
Dim strCopy(12) As Char
strString.CopyTo(0, strCopy, 0, 12)
For Each ch As Char In strCopy
Console.Write(ch)
Next
Can any one point me in the right direction ?
Thanks.
Edit : I get the this error at runtime.
ArgumentOutOfRangeException
Index and count must refer to a location within the string.
Parameter name: sourceIndex
From the documentation you get ArgumentOutOfRangeException when:
sourceIndex, destinationIndex, or count is negative
-or-
count is greater than the length of the substring from startIndex to the end of this instance
-or-
count is greater than the length of the subarray from destinationIndex to the end of destination
The first case isn't true as these values are zero or positive.
So it must be that the count is too great for the destination array. Rather than hard code the length do something like this:
strSource.CopyTo ( 0, destination, 4, strSource.Length );
You should call the ToCharArray() method instead:
Dim strCopy As Char() = strString.ToCharArray()