Issues with For Loop in VB - vb.net

For i = 1 To 5
If i = 0 Then
i = i + 1
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1
Else
LabelOdds.Text = i
i = i + 1
End If
Next i
I'm making a program in VB where I have to use a for loop to sort between 2 numbers(loop limit 1 and 2) and find if they are even or odd, Then output the results to 2 labels. This loop makes sense to me, but for example when I put in 1 and 4 all it outputs is a 5 in the odd label. I guess my question is can anyone see the issue with my loop?

You don't need to add 1 to your loop variable i manually, the for loop itself does that for you behind the scenes:
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = i
Else
LabelOdds.Text = i
End If
Next i
You'll noticed I've also removed the If i = 0 bit since i can never be zero within that loop. It ranges from one to five inclusive.
One other thing you'll need to do is to append the value to your text box. What you have at the moment is a replacement so that it'll only be set to the last value processed. Something like this should suffice:
' Initialise to empty strings '
LabelEvens.Text = ""
LabelOdds.Text = ""
' Append the values '
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & "," & CStr(i)
Else
LabelOdds.Text = LabelOdds.Text & "," & CStr(i)
End If
Next i
' Remove initial comma from both '
LabelEvens.Text = Mid(LabelEvens.Text,2)
LabelOdds.Text = Mid(LabelOdds.Text,2)

Some issues in your code:
For i = 1 To 5
If i = 0 Then <-- 'I' will never be 0 since you start from 1
i = i + 1 <-- Don't manually increment since you are using a for
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
Else
LabelOdds.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
End If
Next i
Another issue you have is that if you have more than one odd number in the for range (say in a range of 1 to 10) you will only get the last number. What do you want to do in this case? Concatenate all odd numbers in a string or stop after the first one is found? Do you really need a FOR loop at all?

you can Also state
LabelEvens.Text="" 'Clear contents of the label before assigning new values
LabelOdds.Text=""
For i As Integer = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & i
Else
LabelOdds.Text = LabelOdds.Text & i
End If
Next
From Above you can replace '&' with '+' if you want the Total.

Related

Remove duplicates from DataGridView but keep the count?

I have a datagridview with data I pull from an SQL Server. It comes back with some data that are duplicates. I want to remove all the duplicates but keep count of how many there are of each unique items. Here is an example of what the data looks like...
For intI = DataGridView1.Rows.Count - 1 To 0 Step -1
For intJ = intI - 1 To 0 Step -1
If DataGridView1.Rows(intI).Cells(1).Value =
DataGridView1.Rows(intJ).Cells(1).Value AndAlso
DataGridView1.Rows(intI).Cells(3).Value =
DataGridView1.Rows(intJ).Cells(3).Value Then
DataGridView1.Rows.RemoveAt(intI)
Exit For
End If
Next
Next
So I can remove all the duplicates, but I want to be able to have a count of all the items in the end, including the duplicates. For example, There are 5 CA, I want to remove 4 leaving just 1 unique one, but I want to show that there are 5 CA in my datagridview next to California.
So in the end, I want the datagridview to have something like :
State | Short
California | 5
Here is my Query:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SELECT
States , Shorts
FROM
DAT.States
INNER JOIN
DATR.[Shorts]
WHERE #StartDate IS NULL
Thank you for your help!
EDIT:
I came up with a method of counting the GridView1 into GridView2 but I'm not exactly sure on the code. Maybe I could get some help with this part instead?
For i As Integer = DataGridView1.RowCount - 1 To 1 Step -1
For j As Integer = DataGridView2.RowCount - 1 To 1 Step -1
'If Grid2.Row(j).Cells(1).Value = Grid1.Rows(i).Cells(1).Value Then
' Grid2 already has that value, +1 to Column 2 of Cell(j)
' Delete row(i)
'Else
'Value does not exist, add row(i) into Grid2, and in the 2nd column of Grid2, the count is 1
'End If
Next
Next
The end result for GridView2 would be something like :
Here is my code I came up with to try and count the States in Column 1 and then delete it and add it to the Grid2, but it's not working...
Dim Counts As Integer = 0
Dim State As String = ""
Dim CurLoop As Integer = 0
Do Until CurLoop > DataGridView1.RowCount - 1
State = DataGridView1.Rows(CurLoop).Cells(0).Value
For i As Integer = DataGridView1.RowCount - 1 To 1 Step -1
If DataGridView1.Rows(i).Cells(0).Value = State Then
Counts += 1
DataGridView1.Rows.RemoveAt(i)
End If
Next
DataGridView2.Rows.Add(State, Counts)
State = ""
Counts = 0
CurLoop += 1
Loop
I have figured out the answer to my own question. It's not the prettiest solution but it works. If anyone else is in need of something like this, here is what I did...
Dim Counts As Integer = 0
Dim State As String = ""
Dim CurLoop As Integer = 0
Do Until CurLoop > DataGridView1.RowCount - 1
State = DataGridView1.Rows(CurLoop).Cells(0).Value
For i As Integer = DataGridView1.RowCount - 1 To 1 Step -1
If DataGridView1.Rows(i).Cells(0).Value = State Then
Counts += 1
DataGridView1.Rows.RemoveAt(i)
End If
Next
DataGridView2.Rows.Add(State, Counts)
State = ""
Counts = 0
CurLoop += 1
Loop
Counts = DataGridView2.Rows(0).Cells(1).Value
Counts += 1
DataGridView2.Rows(0).Cells(1).Value = Counts
For some reason, whatever in the first row of Grid1 is, it's always 1 lower than what it's supposed to be, so I add 1 to it in the end.

I have 8 rows but when (i = 7) it says (i + 1) is out of range?

I have a DataGridView with 8 Rows. In the following Sub i have an If statement to only do something when i is less than the RowCount, this is purposely so when i use (i + 1) on the last row it will still be in range, yet it is not? I can't figure out why. Would appreciate any help.
This is the sub
Public Sub Durations(dgv As DataGridView)
For i As Integer = 0 To dgv.RowCount
Dim intTotalMinutesOfRows As Integer
Dim IntHoursForRows As Integer
Dim intMinutesForRows As Integer
If i < dgv.RowCount Then
If dgv.Rows(i).Cells("EmployeeID").Value = dgv.Rows(i + 1).Cells("EmployeeID").Value _
And dgv.Rows(i).Cells("Date").Value = dgv.Rows(i + 1).Cells("Date").Value Then
intTotalMinutesOfRows = intTotalMinutesOfRows + dgv.Rows(i).Cells("TotalDurationOfRow").Value
Else
intTotalMinutesOfRows = intTotalMinutesOfRows + dgv.Rows(i).Cells("TotalDurationOfRow").Value
IntHoursForRows = Math.Floor(intTotalMinutesOfRows / 60)
intMinutesForRows = intTotalMinutesOfRows Mod 60
dgv.Rows(i).Cells("TotalDurationForDay").Value = "" & IntHoursForRows & " Hrs " & intMinutesForRows & " Mins"
intTotalMinutesOfRows = 0
End If
End If
Next
Iterate to RowCount - 1 only:
For i As Integer = 0 To dgv.RowCount - 1
^^^
Note that despite you've got If i < dgv.RowCount Then, later in this conditional operator you're trying to access Rows(i + 1), which causes the exception for i = dgv.RowCount - 1. So you have to change your condition to If i < dgv.RowCount - 1 Then as well.
Indexes are zero-based (they start at 0), so index 7 is the 8th row.
Row : 1 2 3 4 5 6 7 8
Index : 0 1 2 3 4 5 6 7
Infact even your loop's end is wrong, because i will go to whatever RowCount is. Thus if RowCount is 8 then i will be 8 as well in the end (which doesn't work, as seen in the indexes above).
In order to loop to the last index you must loop to RowCount - 1:
For i As Integer = 0 To dgv.RowCount - 1

VB - comparing numbers in two labels

I'm doing a school project in Visual Basic (using visual studio 2015) and i'm kinda stuck.
My goal is to create a lottery, where player chooses 6 numbers from checkboxes, then he generates six random numbers (1 - 49) and finally, those two sets should be compared and needed result is the number of correctly guessed numbers.
I have both results (guessed numbers, generated numbers) saved in two different labels.
The checkboxes itself are genereted like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lev = 20
tt = 0
For j = 1 To 50
tt = tt + 1
n = n + 1
box(j) = New CheckBox
box(j).Name = "box(" & Str(j) & ")"
If n = 11 Then lev = lev + 110 : n = 1 : tt = 1
box(j).Left = lev
box(j).Parent = Me
box(j).Top = tt * 20
box(j).Tag = j
box(j).Text = j
box(j).Visible = True
Next
box(50).Enabled = False
End Sub
First label (guessed numbers) is filled this way (i'm not posting whole code)
For j = 1 To 50
If box(j).Checked = True Then Label9.Text = Label9.Text + " " + box(j).Text
Next
and the second one (generated numbers) like this:
Do
rn = rg.Next(1, 50)
If Not r.Contains(rn) Then
r.Add(rn)
End If
Loop Until r.Count = 6
Label1.Text = r(0).ToString + " " + r(1).ToString + " " + r(2).ToString + " " + r(3).ToString + " " + r(4).ToString + " " + r(5).ToString
any idea how to compare numbers stored in those labels and get the result (number of correctly guessed numbers).
thanks in advance
You can compare numbers in the labels by splitting the Text properties of the labels into arrays of strings and converting them to integer arrays. First though there is a tiny problem with your code that adds the guessed numbers to the label.
For j = 1 To 50
If box(j).Checked = True Then Label9.Text = Label9.Text + " " + box(j).Text
Next
The " " should be moved to the end of the line because at the moment, the label will always start with a space and that messes with the function below. So you should have -
For j = 1 To 50
If box(j).Checked = True Then Label9.Text = Label9.Text + box(j).Text + " "
Next
Ok. The function below splits the two text labels into their own array and loops through the guesses and checks if any number is contained in the generated numbers. It then returns the number of matches.
Private Function ComparePicks() As Integer
Dim numbersMatched As Integer
Dim picks(5) As Integer
Dim generatedNumbers(5) As Integer
For i As Integer = 0 To 5
picks(i) = CInt(Split(Label9.Text, " "c)(i))
Next
For i As Integer = 0 To 5
generatedNumbers(i) = CInt(Split(Label1.Text, " "c)(i))
Next
For i As Integer = 0 To 5
If generatedNumbers.Contains(picks(i)) Then
numbersMatched += 1
End If
Next
Return numbersMatched
End Function

Moving textbox output into a different textbox

I am trying to output text into another text box once the first has 5 entries in it. Example; i give the scores 100,200,300,200,200. Now when I try to enter a new score it should place it in the next textbox, but doesent.
Dim Testint As Integer ' define an Integer for testing
Dim sampleTextBox(3) As TextBox
sampleTextBox(0) = txtPlayer1Scores
sampleTextBox(1) = txtPlayer2Scores
sampleTextBox(2) = txtPlayer3Scores
sampleTextBox(3) = txtPlayer4Scores
Dim sampleLabel(3) As Label
sampleLabel(0) = lblPlayer1Average
sampleLabel(1) = lblPlayer2Average
sampleLabel(2) = lblPlayer3Average
sampleLabel(3) = lblPlayer4Average
scoreArray(textCount, gameNumber - 1) = CInt(txtScoreInput.Text) ' subtracting 1 from the score array
sampleTextBox(textCount).Text &= " Score:" & scoreArray(textCount, gameNumber - 1) & vbCrLf
'output statement
gameNumber = gameNumber + 1 'increment the counter
If gameNumber > MAX_SCORE_LENGTH Then
sampleTextBox(textCount).Focus()
sampleTextBox(textCount).Enabled = False
For i As Integer = 0 To 4 'Add the array values up
scoreTotal += scoreArray(textCount, i)
Next
playerAverage = scoreTotal / MAX_SCORE_LENGTH
sampleLabel(labelCount).Text = playerAverage
' I need the textbox switch here
textCount = textCount + 1
labelCount = labelCount + 1 ' and labels
ElseIf textCount > MAX_PLAYERS Then
'calculate team average
btnEnterScore.Enabled = False
Else
lblEnterScore.Text = "Enter Score for game #" & gameNumber ' 5 scores have not be inputted,
txtScoreInput.Text = "" 'ask for more
txtScoreInput.Focus() 'refocus the input textbox
End If
Fixed it...setting the max length to 15 forces it to move on after 15 digits, it also works when there are less than 15 digits
txtscore1.MaxLength = 15

Adding Data to an existing SeriesCollection in excel

I am creating a chart from data inside an Excel sheet. Everything works. But now I want to remove values that are below a limit and display them as "Others". Removing them works but I don't know how to add an additonal "others" value.
This is part of the code:
Co.chart.SetSourceData Source:=DataSource
Co.chart.ChartTitle.Text = "Best selling games"
Co.chart.SeriesCollection(1).ApplyDataLabels ShowPercentage:=True, ShowValue:=False
For Each d In Co.chart.SeriesCollection(1).DataLabels
v = CLng(Split(d.Caption, "%")(0))
If v < 10 Then
Rest = Rest + v
d.Delete
End If
Next
If Rest > 0 Then
Co.chart.SeriesCollection(1).DataLabels.AddData("Others",Rest); ' HERE
End If
In the second last line is some pseudocode about what I want to achieve.
I found a "dirty" solution for this. Instead of deleting the first item I RENAME it to "Others" instead of deleting it and adding the "Others" afterwards:
For Each d In Co.chart.SeriesCollection(1).DataLabels
Counter = Counter + 1
v = CLng(Split(d.Caption, "%")(0))
If v <= 10 Then
If RestPos < 0 Then
RestPos = Counter
Else
d.Delete
End If
Rest = Rest + v
End If
Next
If Rest > 0 Then
Co.chart.SeriesCollection(1).DataLabels(RestPos).Caption = Rest & " %"
End If