Validate text box input for numeric range 1-100 - arrays

I am trying to validate inputs to accept only a range of numbers 1-100. I have it where it will accept numbers in the range from 1-100. What I need is how to make sure character inputs such as a letter or symbol (?,/,<,> ect...) can't be used. I am using a loop to look through each input that is put into an array. When inputs are validated I am returning a blnOk = True to use in my button event to run program. I have tried double.TryParse but I can't get it to work with the array. I also have Option Strict ON. dblStudentTestScores(i) is the array that the inputs are stored in. txtTestScores(i) array is being used to tell the program which text box the loop is on so that it can gain focus with an error.
Private Sub ValidateScores()
For i = 0 To 8
If dblStudentTestScores(i) >= 0 And dblStudentTestScores(i) <= 100 Then
blnOK = True
Else
MessageBox.Show("Please Enter Test Score between 0 and 100")
txtTestScores(i).Clear()
txtTestScores(i).Focus()
txtTestScores(i).BackColor = Color.Yellow
blnOK = False
Exit Sub
End If
txtTestScores(i).BackColor = Color.White
Next
blnOK = True
End Sub
This is the code with the IsNumeric but it won't go into the Else clause. It jumps into the try catch. I would really like it to gain focus on the textbox that has the invalid input. Like it does if the number is not between 0 and 100.
Private Sub ValidateScores()
For i = 0 To 8
If CInt(IsNumeric(dblStudentTestScores(i))) >= 0 And CInt(IsNumeric(dblStudentTestScores(i))) <= 100 Then
blnOK = True
Else
MessageBox.Show("Please Enter Test Score between 0 and 100")
txtTestScores(i).Clear()
txtTestScores(i).Focus()
txtTestScores(i).BackColor = Color.Yellow
blnOK = False
Exit Sub
End If
txtTestScores(i).BackColor = Color.White
Next
blnOK = True
End Sub
Each input populates the array.
Public Sub PopulateTestScores()
'Student 1 test scores
dblStudentTestScores(0) = CDbl(txtStudent1Score1.Text)
dblStudentTestScores(1) = CDbl(txtStudent1Score2.Text)
dblStudentTestScores(2) = CDbl(txtStudent1Score3.Text)
'Student 2 test scores
dblStudentTestScores(3) = CDbl(txtStudent2Score1.Text)
dblStudentTestScores(4) = CDbl(txtStudent2Score2.Text)
dblStudentTestScores(5) = CDbl(txtStudent2Score3.Text)
'Student 3 test scores
dblStudentTestScores(6) = CDbl(txtStudent3Score1.Text)
dblStudentTestScores(7) = CDbl(txtStudent3Score2.Text)
dblStudentTestScores(8) = CDbl(txtStudent3Score3.Text)
End Sub

You should use double.TryParse because, if the input is not a valid double, it returns false instead of throwing an exception.
Public Function PopulateTestScores() as Boolean
Dim ok as Boolean
ok = CheckInput(txtStudent1Score1.Text, 0)
if not ok Then
txtStudent1Score1.Focus()
return ok
End if
ok = CheckInput(txtStudent1Score2.Text, 1)
if not ok Then
txtStudent1Score2.Focus()
return ok
End if
.....
return ok
End Function
private Function CheckInput(input as String, index as integer) as Boolean
Dim d as Double
Dim ok as Boolean
ok = double.TryParse(input, d)
if ok Then dblStudentTestScores(index) = d
return ok
End Function
The version of TryParse with two arguments expects the string to be in the same format of your locale (point/comma for decimals). If you want to work with different cultures then just use the appropriate TryParse overload that takes also the CultureInfo parameter.
For example, if you use the overload that takes a NumberStyles and a CultureInfo
ok = Double.TryParse(input, NumberStyles.None, CultureInfo.CurrentCulture, d)
TryParse will return false if the input doesn't match your CultureInfo and the correct convention for digit grouping.
A valid double like 10.1 in en-US culture is invalid the it-IT one where the correct input is 10,1

you can check the input using the isNumeric function.
https://msdn.microsoft.com/en-us/library/6cd3f6w1(v=vs.90).aspx

Related

How to call function from another function in VBA? (Error in results)

I am working on 2 functions in VBA.
Function 1:
Function sort_range(data_o As Range)
Set wf = WorksheetFunction
N = data_o.Rows.Count
data_sort1 = data_o
data_sort2 = data_o
For i = 1 To N
data_sort1(i, 1) = wf.Min(data_sort2)
data_sort2(wf.Match(data_sort1(i, 1), data_sort2, 0), 1) = 999999
Next i
sort_range = data_sort1
End Function
Function 2:
Function sort_range_2(data_o1 As Range, k_default As Long)
Set wf = WorksheetFunction
data_sort3 = sort_range(data_o1)
sort_range_2 = data_sort3(k_default, 1)
End Function
When I input "999,999,999,999,999" into "data_o" of sort_range, sort_range_2 returns 999 (which is correct).
However, sort_range_2 returns an error if I input e.g. "999,1.457,999,999,0.157" into "data_o".
Could anyone please help? Thanks

VBScript function to read multiple strings not working properly

I have a function to read multiple string that I copied from another thread here.
I have the whole document that I need in a string name strResult, my intention is to compare only the fields on the strList, and find them in the strResult.
This is the function:
Function FindString(strCheck,strFind)
Arr = Split(strResult,",")
Flag = 0
And I call it like this: Call FindString(strResult,strList)
For Each str in Arr
If InStr(strCheck, str) > 0 Then
Flag = 1
Reporter.ReportEvent micPass,"Field Found","Field:"&str&" was found"
Else
Flag = 0
Reporter.ReportEvent micFail,"Field not Found","Field:"&str&" was not found"
End If
Next
If Flag = 1 Then
FindString = True
Reporter.ReportEvent micPass,"Field Found","Field"&str&"was found"
Else
FindString = False
Reporter.ReportEvent micFail,"Field not found","Field"&str&"was not found"
End If
It should return fail when the fields are not found, but it just ignores them, The list of string is on a variable that contains something like "field1,"&_"field2", the main problem is that even if "field3" is not in the strList, it will display it as found, and I only want it to take the fields that are on the strList not all of the strResult string
I fixed the function by splitting the list of values too, like this
Arr = Split(strCheck,",")
Arr2 = Split(strFind,",")
Flag = 0
For Each str in Arr
For Each str2 in Arr2
If InStr(str, str2) > 0 Then
Flag = 1
Reporter.ReportEvent micPass,"Field "&str2&" Found","Field:"&str&" was found"
Exit For
End If
Next

How do I check if an object collides with every object in an array?(Picture boxes)

High school student here and I'm pretty rusty on my code. Okay, I have to have an image scroll along, and if it hits an object(in this case both are picture boxes), it resets.
The problem is when it gets to the If statement below, it won't work saying " 'bounds' is not a member of 'system.array' "
If PtbIcon.Bounds.IntersectsWith(objects.Bounds) Then
The error is the Objects.bounds
If PtbIcon.Bounds.IntersectsWith(objects.Bounds) Then
t = t + 1
PtbIcon.Location = New Point(29, 236)
'resets when you die, sets the score
End If
lblScore.Text = "Your Score Equals" & t
End
Why doesn't this work? Why? Is there a simpler way of checking all of this, such as calling a function which checks the bounds individually?
Use Linq.
Dim t As Integer = 0
PtbIcon.All(Function(pb As PictureBox) As Boolean
' Checking goes here with pb
' Return True if you want to go through all of them
End Function)
lblScore.Text = "Your Score Equals" & t

Convert.ChangeType() Returns incorrect value

I've got a class that parses a CNC file, but I'm having difficulties with trailing "words" on each line of the file.
My code parses all leading "words" until it reaches the final word. It's most noticeable when parsing "Z" values or other Double type values. I've debugged it enough to notice that it successfully parses the numerical value just as it does with "X" and "Y" values, but it doesn't seem to successfully convert it to double. Is there an issue with a character I'm missing or something?
Here's my code:
If IO.File.Exists("Some GCode File.eia") Then
Dim sr As New IO.StreamReader("Some GCode File.eia")
Dim i As Integer = 0
'Read text file
Do While Not sr.EndOfStream
'Get the words in the line
Dim words() As String = sr.ReadLine.Split(" ")
'iterate through each word
For i = 0 To words.Length - 1 Step 1
'iterate through each "registered" keyword. Handled earlier in program
For Each cmd As String In _registeredCmds.Keys
'if current word resembles keyword then process
If words(i) Like cmd & "*" Then
_commands.Add(i, _registeredCmds(cmd))
'Double check availability of a Type to convert to
If Not IsNothing(_commands(i).DataType) Then
'Verify enum ScopeType exists
If Not IsNothing(_commands(i).Scope) Then
'If ScopeType is modal then just set it to True. I'll fix later
If _commands(i).Scope = ScopeType.Modal Then
_commands(i).DataValue = True
Else
'Catch errors in conversion
Try
'Get the value of the gcode command by removing the "registered" keyword from the string
Dim strTemp As String = words(i).Remove(0, words(i).IndexOf(_commands(i).Key) + _commands(i).Key.Length)
'Save the parsed value into an Object type in another class
_commands(i).DataValue = Convert.ChangeType(strTemp, _commands(i).DataType)
Catch ex As Exception
'Log(vbTab & "Error:" & ex.Message)
End Try
End If
Else
'Log(vbTab & "Command scope is null")
End If
Else
'Log(vbTab & "Command datatype is null")
End If
Continue For
End If
Next
Next
i += 1
Loop
Else
Throw New ApplicationException("FilePath provided does not exist! FilePath Provided:'Some GCode File.eia'")
End If
Here's an example of the GCode:
N2930 X-.2187 Y-1.2378 Z-.0135
N2940 X-.2195 Y-1.2434 Z-.0121
N2950 X-.2187 Y-1.249 Z-.0108
N2960 X-.2164 Y-1.2542 Z-.0096
N2970 X-.2125 Y-1.2585 Z-.0086
N2980 X-.207 Y-1.2613 Z-.0079
N2990 X-.2 Y-1.2624 Z-.0076
N3000 X0.
N3010 X12.
N3020 X24.
N3030 X24.2
N3040 X24.2072 Y-1.2635 Z-.0075
N3050 X24.2127 Y-1.2665 Z-.0071
N3060 X24.2167 Y-1.2709 Z-.0064
N3070 X24.2191 Y-1.2763 Z-.0057
N3080 X24.2199 Y-1.2821 Z-.0048
N3090 X24.2191 Y-1.2879 Z-.004
N3100 X24.2167 Y-1.2933 Z-.0032
N3110 X24.2127 Y-1.2977 Z-.0026
N3120 X24.2072 Y-1.3007 Z-.0021
N3130 X24.2 Y-1.3018 Z-.002
N3140 X24.
N3150 X12.
N3160 X0.
N3170 X-.2
N3180 X-.2074 Y-1.3029 Z-.0019
N3190 X-.2131 Y-1.306 Z-.0018
N3200 X-.2172 Y-1.3106 Z-.0016
N3210 X-.2196 Y-1.3161 Z-.0013
N3220 X-.2204 Y-1.3222 Z-.001
N3230 X-.2196 Y-1.3282 Z-.0007
N3240 X-.2172 Y-1.3338 Z-.0004
N3250 X-.2131 Y-1.3384 Z-.0002
N3260 X-.2074 Y-1.3415 Z-.0001
N3270 X-.2 Y-1.3426 Z0.
N3280 X0.
N3290 X12.
N3300 X24.
N3310 X24.2
N3320 G0 Z.1
N3330 Z1.0
N3340 G91 G28 Z0.0
N3350 G90
With regard to the sample CNC code above, you'll notice that X and Y commands with a trailing Z command parse correctly.
EDIT
Per comment, here is a breakdown of _commands()
_commands = SortedList(Of Integer, Command)
Command is a class with the following properties:
Scope as Enum ScopeType
Name as String
Key as String
DataType as Type
DataValue as Object
EDIT: Solution!
Figured out what was wrong. The arrays that make up the construction of the classes were essentially being passed a reference to the "registered" array of objects from the Command class. Therefore every time I parsed the value out of the "word" each line, I was overwriting the DataValue in the Command object.
The solution was to declare a new 'Command' object with every parse and append it to the proper array.
Here's my short hand:
...
For I = 0 To words.Length - 1 Step 1
'iterate through each "registered" keyword. Handled earlier in program
For Each cmd as String in _registeredCmds.Keys
'if current word resembles keyword then process
If words(I) Like cmd & "*" Then
'NEW!!! Declare unassigned Command object
Dim com As Command
' ****** New elongated logic double checking existence of values.....
If _registeredCmds.Keys.Scope = ScopeType.Modal Then
'assign Command object to previously declared variable com
com = New Command()'There's technically passing arguments now to ensure items are transferred
Else
'Parse and pass DataValue from this word
com = New Command()'There's technically passing arguments now to ensure items are transferred
End If
'New sub to add Command object to local array
Add(com)
Continue For
End If
Next
Next
...

How to save the names of clicked objects to a text file (Visual Basic)

I am doing a cinema booking system as my A-Level Computing project, I am using labels as seats, when they are clicked they turn green and I am trying to save the name of each clicked label to an array that will be later saved to a file. This is the procedure for when a seat is clicked:
Private Sub lblA1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblA1.Click, lblA2.Click, lblA3.Click, lblA4.Click, lblA5.Click, lblA6.Click, lblA7.Click, lblB1.Click, lblB2.Click, lblB3.Click, lblB4.Click, lblB5.Click, lblB6.Click, lblB7.Click, lblC1.Click, lblC2.Click, lblC3.Click, lblC4.Click, lblC5.Click, lblC6.Click, lblC7.Click, lblD1.Click, lblD2.Click, lblD3.Click, lblD4.Click, lblD5.Click, lblD6.Click, lblD7.Click, lblE1.Click, lblE2.Click, lblE3.Click, lblE4.Click, lblE5.Click, lblE6.Click, lblE7.Click, lblF1.Click, lblF2.Click, lblF3.Click, lblF4.Click, lblF5.Click, lblF6.Click, lblF7.Click, lblG1.Click, lblG2.Click, lblG3.Click, lblG4.Click, lblG5.Click, lblG6.Click, lblG7.Click, lblH1.Click, lblH2.Click, lblH3.Click, lblH4.Click, lblH5.Click, lblH6.Click, lblH7.Click, lblI1.Click, lblI2.Click, lblI3.Click, lblI4.Click, lblI5.Click, lblI6.Click, lblI7.Click, lblJ1.Click, lblJ2.Click, lblJ3.Click, lblJ4.Click, lblJ5.Click, lblJ6.Click, lblJ7.Click, lblK1.Click, lblK2.Click, lblK3.Click, lblK4.Click, lblK5.Click, lblK6.Click, lblK7.Click, lblL1.Click, lblL2.Click, lblL3.Click, lblL4.Click, lblL5.Click, lblL6.Click, lblL7.Click
ClickedBox = CType(sender, Label)
If ClickedBox.BackColor = Color.DodgerBlue Then 'Checks if seat is free
ClickedBox.BackColor = Color.LawnGreen 'Changes colour of seats clicked to green
ClickedBox.ForeColor = Color.LawnGreen
TotalNoOfSeats = TotalNoOfSeats + 1
strSeats(intCounter3) = ClickedBox.Name
intCounter3 = intCounter3 + 1
Else
MsgBox("This seat has already been booked")
End If
End Sub
When the user clicks the 'Book Seats' button I have called a procedure that attempts to save the array of seat names to a text file. The following code is the procedure:
Sub SaveSeats()
Dim intloop As Integer
FileWriter = New StreamWriter("Seats " + AddFilm.strFilms(1, intSelectedFilm) + ".txt")
FileWriter.WriteLine(intCounter3)
For intloop = 0 To intCounter3
FileWriter.WriteLine(strSeats(intloop))
Next
FileWriter.Close()
End Sub
On the line that contains:
FileWriter.WriteLine(strSeats(intloop))
I get the following error: "System.IndexOutOfRangeException was unhandled
Message=Index was outside the bounds of the array."
Any help is appreciated.
Edit: i have used this approach but now i have another problem:
The error containing: "ObjectDisposedException - Cannot write to a closed TextWriter." appears on the line:
FileWriter.WriteLine(SeatList(intloop))
This is the procedure I am using now to Save the list to the text file:
Sub SaveSeats()
Dim intloop As Integer
FileWriter = New StreamWriter("Seats " + AddFilm.strFilms(1, intSelectedFilm) + ".txt")
FileWriter.WriteLine(NoOfClickedSeats)
For intloop = 1 To NoOfClickedSeats
FileWriter.WriteLine(SeatList(intloop))
FileWriter.Close()
Next
End Sub
Array indices are zero based, so you have to subtract 1 from intCounter3:
For intloop As Int32 = 0 To intCounter3 - 1
FileWriter.WriteLine(strSeats(intloop))
Next
Consider that intCounter3 is 1 (the array contains one element). You would try to access the second element with intCounter3(1) which causes the IndexOutOfRangeException.
By the way, you should choose more meaningful names than intCounter3, otherwise it'll be soon difficult to understand your code for you or others.
Edit: another problem with code is that you are resizing the array without redim. You should use a List(Of String) instead which can be resized:
So instead of:
strSeats(intCounter3) = ClickedBox.Name
Use a list instead and it's Add method:
Private SeatList As New ist(Of String)
Private Sub lblA1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblA1.Click, lblA2.Click, lblA3.Click, lblA4.Click, lblA5.Click, lblA6.Click, lblA7.Click, lblB1.Click, lblB2.Click, lblB3.Click, lblB4.Click, lblB5.Click, lblB6.Click, lblB7.Click, lblC1.Click, lblC2.Click, lblC3.Click, lblC4.Click, lblC5.Click, lblC6.Click, lblC7.Click, lblD1.Click, lblD2.Click, lblD3.Click, lblD4.Click, lblD5.Click, lblD6.Click, lblD7.Click, lblE1.Click, lblE2.Click, lblE3.Click, lblE4.Click, lblE5.Click, lblE6.Click, lblE7.Click, lblF1.Click, lblF2.Click, lblF3.Click, lblF4.Click, lblF5.Click, lblF6.Click, lblF7.Click, lblG1.Click, lblG2.Click, lblG3.Click, lblG4.Click, lblG5.Click, lblG6.Click, lblG7.Click, lblH1.Click, lblH2.Click, lblH3.Click, lblH4.Click, lblH5.Click, lblH6.Click, lblH7.Click, lblI1.Click, lblI2.Click, lblI3.Click, lblI4.Click, lblI5.Click, lblI6.Click, lblI7.Click, lblJ1.Click, lblJ2.Click, lblJ3.Click, lblJ4.Click, lblJ5.Click, lblJ6.Click, lblJ7.Click, lblK1.Click, lblK2.Click, lblK3.Click, lblK4.Click, lblK5.Click, lblK6.Click, lblK7.Click, lblL1.Click, lblL2.Click, lblL3.Click, lblL4.Click, lblL5.Click, lblL6.Click, lblL7.Click
ClickedBox = CType(sender, Label)
If ClickedBox.BackColor = Color.DodgerBlue Then 'Checks if seat is free
ClickedBox.BackColor = Color.LawnGreen 'Changes colour of seats clicked to green
ClickedBox.ForeColor = Color.LawnGreen
TotalNoOfSeats = TotalNoOfSeats + 1
SeatList.Add(ClickedBox.Name)
intCounter3 = intCounter3 + 1
Else
MsgBox("This seat has already been booked")
End If
End Sub
Edit: according to your last edit related to the ObjectDisposedException:
You cannot close the writer in the loop since a closed writer cannot be used anymore. So you should close it after the loop.
For intloop = 0 To NoOfClickedSeats - 1
FileWriter.WriteLine(SeatList(intloop))
Next
FileWriter.Close()
or use the Using-statement which also ensures that it gets closed/disposed in case of an error:
Using FileWriter = New StreamWriter("Seats " + AddFilm.strFilms(1, intSelectedFilm) + ".txt")
For intloop = 0 To NoOfClickedSeats - 1
FileWriter.WriteLine(SeatList(intloop))
Next
End Using

Resources