Hello again!
This time I came across a situation where I had to write a loop for a part of the program
I have 10 numericupdown boxes
Each one is different from each other set from 1 to 10 value
I want to be able to set a different value for each box (between 1 and 10) and have it check to see if any of the numericupdown boxes have a matching or duplicate number selected in it.
I wrote a loop that works, but I feel its not an efficient way of writing the loop, so if anyone can suggest anything better...
heres what I wrote
If
NUD1.Value = NUD2.Value Then Call errormessage() Else If NUD1.Value = NUD3.Value Then Call errormessage() Else If NUD1.Value = NUD4.Value Then Call errormessage() Elseand so on... then I do the same for NUD2 and so on and so on... until ive done all 10 NUD values.
As you can see, this way got pretty lengthy!

A more efficient Loop
naveen.jaikumar
You can save some effort becaue you don't have to compare NUD1 with NUD2 and compare NUD2 with NUD1. You compare NUD1 against NUD2 through NUD10 and then NUD2 against NUD3 through NUD10 and so on. That still leaves you 45 comparisons to perform.
However, you may be able to take advantage of the extra restrictions that exist. You know the value is limited between 1 and 10. If the number of decimals allowed is also limited you can easily map the value to an integer which you can then use to index an array.
For example, lets assume that all your NUDs are configured with Minimum = 1; Maximum = 10; DecimalPlaces = 2; You know you can turn it into an integer between 1 and 1000 by multiplying by 100.
Declare a bool array with an upper bound of 1000 and you can use the integer to index the array. If the array value is true, the number has already been used. If the array value is false, you set it to true to show the number has been used. This algorithm uses only one comparison plus some arithmetic per NUD
Dim used(1000) As Boolean
______________________________________________
' Use Floor to ensure consistently rounding down
index = Decimal.Floor(NUD1.Value * 100)
If used(index) Then
' number has already been used
Else
used(index) = True
End If
Another interesting variation might be to set CausesValidation and run this test in the Validating event handler against sender.Value. The same handler can validate all ten of your NUDs.
Coldwar
HI Jack,
The following is probably what you looking for although I used textboxes instead of NumericUpDown so you would need to change it a little for the differences.
If you create a form with 4 textboxes and a button and paste this code. It will iterate through the textboxes with the same name prefix and different indexes to confirm all the contents of all the tetxboxes with the same prefix are unique - if not then you get a return type and display a message. Give it a try and you'll be able to trace what its doing.
Scalable by adding more textboxes with the same prefix and adjusting the last parameter on the call from 4 to whatever the maximum index value is for the group of textboxes with the same prefix.
SO If I put textboxes 1-20 on the form I'd simply the line to
b = ValidateTextboxesAreAllUnique(Me, "TextBox", 20)
I think this is pretty close to what you want.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim b As Boolean
b = ValidateTextboxesAreAllUnique(Me, "TextBox", 4)
If b = True Then
MsgBox("Duplicates Found in the textboxes")
End If
End Sub
''' <summary>
''' Validate the values in a group of textboxes with the same prefix are unique
''' </summary>
Function ValidateTextboxesAreAllUnique(ByVal frm As Form, ByVal TextboxPrefix As String, ByVal COunt As Integer) As Boolean
Dim bfoundDuplicate As Boolean = False
'//For All the textboxes in the Group with the same Prefix
'// Textbox1, Textbox2, Textbox3
For i = 1 To COunt
Dim strTextBoxName As String = TextboxPrefix & i.ToString
Dim Value As String = frm.Controls(strTextBoxName).Text
For Each t In frm.Controls
If TypeOf (t) Is TextBox Then
'//If Item I'm Looking at has the same Prefix then I need to get the Index from the name to determine if its the same one
'//I got the initial value on - if its not then I'll compare the value
If CType(t, TextBox).Name.Substring(0, TextboxPrefix.Length) = TextboxPrefix Then
Dim iControlIndex As Integer = CType(SplitName(CType(t, TextBox).Name), Integer)
'//The index is not the same so I can check the value for a duplicate
'//If they match then I've found a duplicate
If i <> iControlIndex Then
If Value = CType(t, TextBox).Text Then
bfoundDuplicate = True
Return bfoundDuplicate
End If
End If
End If
End If
Next
Next
Return bfoundDuplicate
End Function
''' <summary>
''' This will get the Numbers only from a string.
''' Used to get the Number index from the control name
''' </summary>
Function SplitName(ByVal Fullname As String) As String
Dim outputstring As String = ""
For Each c As Char In Fullname
If Char.IsNumber(c) Then outputstring = outputstring & c
Next
Return outputstring
End Function
End Class
Jirka Nouza
I tried out your suggestion...
Since i and t where not declared I set i as an integer and t as an object (not sure if that was right or not)
I did get an error when I ran it though on line:
Dim
Value As String = CType(frm.Controls(strTextBoxName), NumericUpDown).ValueI got a NullReferenceException was unhandled
Object reference not set to an instance of an object... I think the prob was when i declared the t to object but was not sure what else to do with it.
einaros
This is the code for NumericUpDown Controls
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim b As Boolean
b = ValidateNumberUpDownAreAllUnique(Me, "NumericUpDown", 4)
If b = True Then
MsgBox("Duplicates Found in the textboxes")
End If
End Sub
''' <summary>
''' Validate the values in a group of NumericUpDown with the same prefix are unique
''' </summary>
Function ValidateNumberUpDownAreAllUnique(ByVal frm As Form, ByVal TextboxPrefix As String, ByVal COunt As Integer) As Boolean
Dim bfoundDuplicate As Boolean = False
For i = 1 To COunt
Dim strTextBoxName As String = TextboxPrefix & i.ToString
Dim Value As String = CType(frm.Controls(strTextBoxName), NumericUpDown).Value
For Each t In frm.Controls
If TypeOf (t) Is NumericUpDown Then
'//If Item I'm Looking at has the same Prefix then I need to get the Index from the name to determine if its the same one
'//I got the initial value on - if its not then I'll compare the value
If CType(t, NumericUpDown).Name.Substring(0, TextboxPrefix.Length) = TextboxPrefix Then
Dim iControlIndex As Integer = CType(SplitName(CType(t, NumericUpDown).Name), Integer)
'//The index is not the same so I can check the value for a duplicate
'//If they match then I've found a duplicate
If i <> iControlIndex Then
If Value = CType(t, NumericUpDown).Value Then
bfoundDuplicate = True
Return bfoundDuplicate
End If
End If
End If
End If
Next
Next
Return bfoundDuplicate
End Function
''' <summary>
''' This will get the Numbers only from a string.
''' Used to get the Number index from the control name
''' </summary>
Function SplitName(ByVal Fullname As String) As String
Dim outputstring As String = ""
For Each c As Char In Fullname
If Char.IsNumber(c) Then outputstring = outputstring & c
Next
Return outputstring
End Function
End Class