Input validation help for vb!

JM Aggie08

Diamond Member
Jan 3, 2006
8,436
1,037
136
I need a little help validating that the value entered into a textbox by a user is an integer. I've highlighted the area in red. Any help would be greatly appreciated!

Code:
 Public Class Form1

    Private Sub btnInfo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInfo.Click

        'declare arrays
        Dim strMonth() As String = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
        Dim decRain() As Decimal

        Try

            lstInput.Items.Add("Monthly Rainfall:")
            lstInput.Items.Add("                ")

            'get rainfall amounts
            decRain = GetRain(strMonth)

            'display the gather months and rainfall
            DisplayValues(strMonth, decRain)

            'display total
            TotalRainfall(decRain)

            'display average
            AverageRainfall(decRain)

            'display highest rainfall
            HighRain(decRain, strMonth)

            'display lowest rainfall
            LowRain(decRain, strMonth)


        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub
    Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click


        'clear the form
        ClearValues()

    End Sub
    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click

        'close it all out
        Me.Close()

    End Sub
    [COLOR="Red"]Private Function GetRain(ByVal strMonths() As String) As Decimal()

        'declare array/variables
        Dim decRain(strMonths.Length - 1) As Decimal
        Dim intIndex As Integer


        'get amount of rain
        For intIndex = 0 To decRain.Length - 1
            decRain(intIndex) = CDec(InputBox("Please input rainfall for " & strMonths(intIndex), "Input rainfall"))
        Next

        'return rainfall values
        Return decRain

    End Function[/COLOR]

    Private Sub DisplayValues(ByVal strMonths() As String, ByVal decRain() As Decimal)

        'declare variables
        Dim intIndex As Integer


        'display month with specified rainfall in the listbox
        For intIndex = 0 To strMonths.Length - 1
            lstInput.Items.Add(strMonths(intIndex) & " has a total rainfall of: " & (decRain(intIndex).ToString) & " inches.")
        Next

    End Sub

    Private Sub TotalRainfall(ByVal decRain() As Decimal)

        'declare variables
        Dim decTotal As Decimal

        'calculate the total
        decTotal = decRain.Sum

        'display total
        lblTotal.Text = CStr(decTotal) & " inches."

    End Sub

    Private Sub AverageRainfall(ByVal decRain() As Decimal)

        'declare variables
        Dim decAverage As Decimal

        'calculate average
        decAverage = decRain.Average

        'display average
        lblAverage.Text = decAverage.ToString("n") & " inches."

    End Sub

    Private Sub HighRain(ByVal decRain() As Decimal, ByVal strMonth() As String)

        'declare variables
        Dim decHighestRainfall As Decimal
        Dim strMonthNames As String

        'calulate highest rainfall
        decHighestRainfall = decRain.Max

        'Find month with highest rainfall
        strMonthNames = String.Empty

        'Display salesperson with the largest sales value
        For intIndex As Integer = 0 To decRain.Length - 1
            'Find the largest sales values
            If decRain(intIndex) = decHighestRainfall Then
                strMonthNames = strMonthNames & " " & strMonth(intIndex)
            End If
        Next

        'Display month with highest rainfall
        lblHigh.Text = strMonthNames & ", with " & decHighestRainfall.ToString & " inches of rainfall."

    End Sub

    Private Sub LowRain(ByVal decRain() As Decimal, ByVal strMonth() As String)

        'declare variables
        Dim decLowestRainfall As Decimal
        Dim strMonthNames As String

        'calulate highest rainfall
        decLowestRainfall = decRain.Min

        'Find month with highest rainfall
        strMonthNames = String.Empty

        'Display salesperson with the largest sales value
        For intIndex As Integer = 0 To decRain.Length - 1
            'Find the largest sales values
            If decRain(intIndex) = decLowestRainfall Then
                strMonthNames = strMonthNames & " " & strMonth(intIndex)
            End If
        Next

        'Display month with highest rainfall
        lblLow.Text = strMonthNames & ", with " & decLowestRainfall.ToString & " inches of rainfall."

    End Sub

    Private Sub ClearValues()

        'clear all data from the form
        lstInput.Items.Clear()

        lblAverage.Text = ""
        lblHigh.Text = ""
        lblLow.Text = ""
        lblTotal.Text = ""

    End Sub

End Class
 
Last edited:

Cogman

Lifer
Sep 19, 2000
10,286
147
106
If you need to do validation, you shouldn't be doing conversion and input gathering as a one step process.

Rather, the steps for validation usually follow the flow of

Get user input and save it off into a variable
check that user input is valid
If valid, convert, else, throw an error.

When checking if a string is a valid string, it is important to define what good input looks like rather then trying to find every case of bad input.

I suggest reading up on regular expressions
http://msdn.microsoft.com/en-us/library/ms974570.aspx
http://www.regular-expressions.info/dotnet.html

BTW, if the user ever inputs anything, you should always treat the input like the user is either retarded or malicious. Never, ever, assume that the user is going to do things the right way, always assume they will do things wrong. This rule applies whenever your program imports data from some outside source (even sometimes from inside sources). The assumption that the user will do things right has led to many a security hole in many an application. Read up on "buffer overflows" and "SQL injections" for classic examples of what happens when you trust the user.
 
Last edited:

JM Aggie08

Diamond Member
Jan 3, 2006
8,436
1,037
136
If you need to do validation, you shouldn't be doing conversion and input gathering as a one step process.

Rather, the steps for validation usually follow the flow of

Get user input and save it off into a variable
check that user input is valid
If valid, convert, else, throw an error.

When checking if a string is a valid string, it is important to define what good input looks like rather then trying to find every case of bad input.

I suggest reading up on regular expressions
http://msdn.microsoft.com/en-us/library/ms974570.aspx
http://www.regular-expressions.info/dotnet.html

Could you possibly give me an example? I'm fairly new to programming :/
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Could you possibly give me an example? I'm fairly new to programming :/

I'm not familiar enough with VB string functions to give you a VB example. But if I were to do this in c++ it would go something like this.

Code:
int GetRain(string month)
{
   char validValues[] = "0123456789";

   // Make sure that the month string is valid
   if(month.find_first_of(validValues) != string::npos)
   {
      MessageBox("Error", "Error, invalid month value", MB_OK); // You could throw an error here as well.  Messageboxs are considered evil by some.
      return -1;  // Exit the function if things are going well.
   }

   
   string userInput = GetUserInput();
   int monthVal = atoi(month.c_str()); // Converts the month value into a decimal value

   while(userInput.find_first_of(validValues) != string::npos)
   {
      MessageBox("Error", "Error, invalid input", MB_OK);
      userInput = GetUserInput(); // Keep trying to get input until they do it right.
   }
   return atoi(userInput.c_str());
}

Obviously not exactly the same as what you are doing, but it should highlight the form of how you should do it. (I'm not going to give you something you can just copy and paste into your program. You'll never learn anything if you do things that way.)
 

JM Aggie08

Diamond Member
Jan 3, 2006
8,436
1,037
136
Totally understandable. I ended up doing a couple nested ifs and loops.

Code:
        For intIndex = 0 To strMonths.Length - 1
            blnStatus = False
            Do While blnStatus = False
                strInput = InputBox("Please input rainfall for " & strMonths(intIndex), "Input rainfall")
                If Not Decimal.TryParse(strInput, decRain(intIndex)) Then
                    MessageBox.Show("Please enter a numeric value.", "Invalid entry")
                Else
                    If decRain(intIndex) < 0 Then
                        MessageBox.Show("Monthly rainfall must be greater than or equal to 0", "Error Message")
                    Else
                        blnStatus = True
                    End If
                End If
            Loop
        Next

thanks again for the help!
 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
If you want to use tryParse you're going to need a local variable to hold the output value in case the parse is valid.

In C# syntax
Code:
int val;
string parseMe = "1234";
if (Int32.tryParse(parseMe, out val))
	do_something_with_int_value(val);
else 
	handle_invalid_input();