I am writing a console application which requires user input of certain values. I want to disallow any letter input. The console automatically writes "Conversion from string "b" to type 'Integer' is not valid." but I want the console to display my personal message "Not a valid number, please try again." how can I do that?
I've tried many different keywords and phrases but none work. Maybe I'm doing it wrong (not unlikely) or maybe it's just meant for something else. Either way I need help.
To recap: User input in a console that only allows numbers not letters, and will display my message.
I didn't want to post my code since people always pick on it, but here it is. Please note that there MUST be an exception. It is homework and I NEED an exception and this is one way a user can screw up. Please don't tell me not to use an exception.
Module Module1
Sub Main()
Try
System.Console.WriteLine("Input up to 10 valid numbers to have them mathematically averaged.")
For Index = 0 To 9
Dim Input As IList
Input = Console.ReadLine()
Next Index
If ' here is where I want to add that numbers only Then
Throw New exception("Not a valid number, please try again.")
Else
System.Console.WriteLine("Now averaging numbers...")
Dim average As Double = (n + n + n + n + n + n + n + n + n + n) / 10
Console.WriteLine("The average of " & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & "," & n & " and " & n & " is " & average & ".", "Calculation")
End If
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
End Module
Dim inputString = Console.ReadLine
If Integer.TryParse(inputString, num) Then
DoSomething(num)
Else
Console.WriteLine("Not a valid number, please try again.")
End If
Here's one way to do it, honoring your requirements:
Module Module1
Sub Main()
System.Console.WriteLine("Input valid numbers seperated by spaces to have them mathematically averaged.")
Dim inputArray As String() = System.Text.RegularExpressions.Regex.Replace(Console.ReadLine().Trim(), "\s{2,}", " ").Split(New Char() {" "})
Dim values As New ArrayList
Dim sum As Integer
For i As Integer = 0 To inputArray.Length - 1
Try
sum = sum + Integer.Parse(inputArray(i), Globalization.NumberStyles.Integer)
values.Add(inputArray(i))
Catch ex As Exception
Console.WriteLine(String.Format("The value ""{0}"" is not a valid number and will be ignored. ExceptionMessage: {1}", inputArray(i), ex.Message))
End Try
Next
Dim average As Decimal = sum / values.Count
Console.WriteLine(vbCrLf)
Console.WriteLine(String.Format("The average of ""{0}"" is {1}", Join(values.ToArray, ", "), average))
Console.WriteLine(vbCrLf)
Main()
End Sub
End Module
Well for starters, the Try - Catch should be inside the input gathering For loop. As your program is written now, as soon as one wrong value is entered execution jumps to the catch and your program ends! If you try casting your input to an decimal you won't need to throw an exception manually, it will be thrown automatically if your input is not an decimal! Try casting the current console input as a decimal and then add that number to your list.
Dim inputNumber as Decimal = CDec(Console.ReadLine())
Input.Add(inputNumber)
Also n will be the same number every time so how you are doing it won't work (look up the basics of how a list works, how to add elements to a list and how to display list elements)
Related
I have to answer this in Visual Basic.I actually don't have any idea how to solve this, our teacher barely teaches us practical stuff. I have to submit this assignment by today too.
I have tried to do solve it and searched the internet for it, but I could barely understand it.
Here is some code you can build upon:
Public Sub AddTwoNumbers()
Dim FirstNumber As String = Convert.toInt32(InputBox("Enter the first number.")) 'Get the first number
Dim SecondNumber As String = Convert.toInt32InputBox("Enter the second number.")) 'Get the second number
Dim Result As Integer = 0 'Used to store the result in
'Now perform the calculation.
Result = FirstNumber + SecondNumber
'Then show the result in a MessageBox
MessageBox.Show("The result is: " & Result.ToString())
End Sub
Here's an example using Integer.TryParse():
Dim value1, value2 As Integer
Dim response As String = InputBox("Enter first Integer:")
If Integer.TryParse(response, value1) Then
response = InputBox("Enter second Integer:")
If Integer.TryParse(response, value2) Then
Dim sum As Integer = value1 + value2
MessageBox.Show("The sum of " & value1 & " and " & value2 & " is " & sum)
Else
MessageBox.Show(response & " is not a valid Integer!")
End If
Else
MessageBox.Show(response & " is not a valid Integer!")
End If
I have a declaration like number= InputBox("Number for:", "Number:"), number is declared as Dim number As Double but when I enter a double number, for example 5.4, into the Inputbox and transmit it into a cell, the cell shows me 54, it deletes the point.
How can I fix this?
THX
If you want to detect which settings your Excel uses for the Decimal seperator, try the code below:
MsgBox "Excel uses " & Chr(34) & Application.DecimalSeparator & Chr(34) & " as a decimal seperator"
if you want to change it to ., then use the line below:
Application.DecimalSeparator = "."
Unfortunately, VBA is horrible at handling differences in decimal seprators. In your case, you should probably use a comma (,), instead of a punctuation/dot (.).
Edit: Using the Application.DecimalSeparator method, it now works regardless of regional settings. Be aware though, it seems to cause some issues if you change the comma separator settings for Excel (it seems that VBA somewhat ignores this setting). If you do not change that however, the example should work in all other cas
Sub GetNumberFromInputBox()
Dim val As String
Dim num As Double
'Get input
val = InputBox("Number for:", "Number:")
Debug.Print Application.DecimalSeparator
If IsNumeric(val) Then
'Try to convert to double as usual
num = CDbl(val)
'If the dot is removed automatically, then
'you will se a difference in the length. In
'those cases, replace the dot with a comma,
'before converting to double
If Len(val) <> Len(num) Then
If Application.DecimalSeparator = "," Then
num = CDbl(Replace(val, ".", ","))
Else
num = CDbl(Replace(val, ",", "."))
End If
End If
'Pring the number
Debug.Print "You selected number: " & num
Else
'If its not a number at all, throw an error
Debug.Print "You typed " & val & ", which is not a number"
End If
End Sub
I'm finishing up a project and needed some clarification on a particular issue I'm running into.
Do While intCount < dblNumbers.Length AndAlso strInput <> String.Empty
dblNumbers(intCount) = CDbl(InputBox("Please enter number " & (intCount + 1) & "."))
intCount += 1
Loop
I'm running into issues changing that a to Double.TryParse for validating as opposed to the CDbl. Any of the ways I've entered it have caused the inputs to not store in the array. Thanks in advance.
TryParse doesn't return the converted value. It returns the validation result. You get the converted value from the parameter.
Dim number As Double
If Double.TryParse(InputBox("Please enter number " & (intCount + 1) & "."), number) Then
dblNumbers(intCount) = number
Else
'Invalid input.
End If
I am working on a project which allows kids to send a message to Santa. Unfortunately, if they enter a string instead of an integer in the AGE field, the program crashes and returns Conversion from string "[exampleString]" to type 'Double' is not valid.
Is there any way to check if they have entered an integer or not? This is the code.
If childAge > 0 And childAge < 150 Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
End If
Thanks,
Kai :)
A very simple trick is to try parse the string as an Integer. If it succeeds, it is an integer (surprise surprise).
Dim childAgeAsInt As Integer
If Integer.TryParse(childAge, childAgeAsInt) Then
' childAge successfully parsed as Integer
Else
' childAge is not an Integer
End If
Complementing Styxxy's response, if you dont need a result just replace it by vbNull:
If Integer.TryParse(childAge, vbNull) Then
You could perform the following two tests to be reasonably certain that the input you're getting is an integer:
If IsNumeric(childAge) AndAlso (InStr(1, childAge, ".") <> 0) Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
If childAge < 0 OrElse childAge > 150 Then
fmSecA2 = "I don't believe it's possible to be" & childAge & " years old..."
End If
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
The InStr function returns zero if it doesn't find the string that is being looked for, and so when combining that test with IsNumeric, you also rule out the possibility that some floating point data type was entered.
IsNumeric is built into VB, and will return a true/false
If IsNumeric(childAge) AndAlso (childAge > 0 And childAge < 150) Then
fmSecA2 = "Wow! You are already " & childAge & " years old? You're growing to be a big " & childGender & " now! "
Else
fmSecA2 = "Erm, I couldn't really understand your age. Are you making this up? Ho ho ho!"
End If
You can use this.
Sub checkInt()
If IsNumeric(Range("A1")) And Not IsEmpty(Range("A1")) Then
If Round(Range("A1"), 0) / 1 = Range("A1") Then
MsgBox "Integer: " & Range("A1")
Else
MsgBox "Not Integer: " & Range("A1")
End If
Else
MsgBox "Not numeric or empty"
End If
End Sub
Working from Styxxy's answer, if you parse as a byte rather than an integer, then it also checks negative ages and maximum age of 255 all in one go.
Dim childAgeAsByte As Byte
If Byte.TryParse(childAge, childAgeAsByte) Then
' childAge successfully parsed as Byte
Else
' childAge is not a Byte
End If
Kristian
Dim Input
Input = TextBox1.Text
If Input > 0 Then
............................
............................
Else
TextBox2.Text = "Please only enter positive integers"
End If
Try
If TextBox1.Text > 0 Then
Label1.Text = "Integer"
End If
Catch ex As Exception
Label1.Text = "String"
End Try
With this you can put anything in TextBox1, if you put text then you get Label1 is string and if you put number then you get it's integer
In .Net you may use GetType() to determine the data type of a variable.
Dim n1 As Integer = 12
Dim n2 As Integer = 82
Dim n3 As Long = 12
Console.WriteLine("n1 and n2 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n2.GetType()))
Console.WriteLine("n1 and n3 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n3.GetType()))
' The example displays the following output:
' n1 and n2 are the same type: True
' n1 and n3 are the same type: False
Based on the above sample you can write a code snippet:
If childAge.GetType() = "Integer" then '-- also use childAge.GetType().Name = "Int32"
' do something
End if
Reference MSDN
I'm using visual studios 2008, VB9 and I am trying to write an app that basically performs calculations on a set of data input by a user. During the calculations, I want to display the data at each step, and have it retained in the display area on the GUI (not overwritten by the next data being displayed).
For example:
UserInput = 1
Do
UserInput += 1
OutputLabel.Text = "UserInput " & UserInput
Loop Until UserInput = 5
and the output would look like
UserInput 1
UserInput 2
UserInput 3
UserInput 4
UserInput 5
I tried this, and other loop structures and can't seem to get things right. The actual app is a bit more sophisticated, but the example serves well for logical purposes.
Any tips are welcome, thanks!
This is the simple version:
Dim delimiter as String = ""
For UserInput As Integer = 1 To 5
OutputLabel.Text &= String.Format("{0}UserInput {1}", delimiter, UserInput)
delimiter = " "
Next
However, there are two problems with it and others like it (including every other answer given so far):
It creates a lot of extra strings
Since it's in a loop the label won't be able to process any paint events to update itself until you finish all of your processing.
So you may as well just do this:
Dim sb As New StringBuilder()
Dim delimiter As String = ""
For UserInput As Integer = 1 To 5
sb.AppendFormat("{0}UserInput {1}", delimiter, UserInput)
delimiter = " "
Next
OutputLabel.Text = sb.ToString()
And if you really want to have fun you can just do something like this (no loop required!):
OutputLabel.Text = Enumerable.Range(1, 5).Aggregate(Of String)("", Function(s, i) s & String.Format("UserInput {0} ", i))
You need to concatenate the value in OutputLabel.Text.
OutputLabel.Text &= "UserInput " & UserInput
You might also want to reset it before the loop: OutputLabel.Text = ""
If you need an iterated index you can try something like the following
For I As Integer = 1 To 5
If I > 1 Then OutputLabel.Text &= " "
OutputLabel.Text &= "UserInput " & I.ToString()
End For
If you have user inputs in a collection, you might better be served by using ForEach loop.
Do you need to do it in a GUI? If it is simply processing and putting out rows like that, maybe you should consider a console application, in which case it becomes REALLY easy, in simply calling
Console.WriteLine("my string")
All of these ways actually work really well but the one that fit my situation the best was this:
Do
Dim OutputString as String
Application.DoEvents() 'to make things paint actively
UserInput += 1
OutputString = String.Format("{0}", UserInput)
ListBox.Items.Add(OutputString)
Loop Until UserInput = 5
I changed things to a listbox but tried this same method with textboxes and labels, with some tweaks, they all worked very well. Thanks for all your help!
I'd use a more appropriate control, like richtextbox
Dim UserInput As Integer = 0
Const userDone As Integer = 5
RichTextBox1.Clear()
Do
RichTextBox1.AppendText(String.Format("User input {0:n0} ", UserInput))
RichTextBox1.AppendText(Environment.NewLine)
RichTextBox1.Refresh() 'the data at each step
UserInput += 1
Loop Until UserInput = userDone