I am running a Do Until Loop and its giving the error Index out of range. I am using this code:
If Not imgList.Item(i).ToString = Nothing Then
but its not working..
Actually this loop (in a private sub) is called before addition of any value in the Listbox..
here is the complete loop..
Dim i As Integer = 0
Do Until i = pagesRange
If Not imgList.Item(i).ToString = Nothing Then
'other code
i += 1
Else
End If
Loop
for the given code to avoid Index out of range exception try below
If imgList.Count < i AndAlso Not (imgList.Item(i).ToString Is Nothing) Then
End If
Remember about Zero Based ..
Dim i As Integer = 0
Do Until i = pagesRange -1
If Not imgList.Item(i).ToString = Nothing Then
'other code
i += 1
Else
End If
'why i += 1 not here ?
Loop
Related
I know in most other languages you can write an expression if (ptr == NULL || ptr->foo()) {something bad happened} to test both the validity of a variable and a test you want to perform. VBA does not let you do that. So I am wracking my brain to figure out a way to write the following code without 1) using error catching as means of conditional branching and 2) not duplicating code.
Type Vector
vData() as Variant
vSize as Long
End Type
Sub add(v as Vector, elem as Variant)
Dim oldSize as Long
if v.vSize = 0 Or UBound(v.vData) >= v.vSize then
oldSize = v.vSize
ReDim Preserve v.vData(0 to (oldSize * 2 + 1))
v.vData(oldSize) = elem
v.vSize = v.vSize + 1
else
v.vData(v.vSize) = elem
v.vSize = v.vSize + 1
end if
End Sub
Now that code will crash on the UBound line regardless if vSize is 0 or not (if vData was never Dim'd). The only other way i can see to do it is do an additional elseif statement to check UBound, but that would duplicate the code of the doubling the vector size.
In case you think this is a duplicate: VBA Short-Circuit `And` Alternatives . This talks about alternatives to AND statements (not or). Nested ifs (aka AND statements) doesn't duplicate code like OR would.
If I understand correctly you need to check if the array has been allocated or not.
One such option is to do this (however weird it may look):
If (Not Not MyArray) <> 0 Then 'Means it is allocated
Answer taken from this thread - see for more ideas.
Using SnowGroomer's answer I am posting the complete solution:
This is a class named Vector
Private data() As Variant
Private size As Long
Property Get vSize() As Long
vSize = size
End Property
Property Let vData(ByVal index As Long, elem As Variant)
If index < 0 Then Exit Property
If index < size Then
data(index) = elem
Else
Me.add elem, index
End If
End Property
Property Get vData(ByVal index As Long) As Variant
If index < 0 Or (Not Not data) = 0 Then
vData = Nothing
Exit Property
End If
vData = data(index)
End Property
Public Sub add(elem As Variant, Optional index As Long = -1)
If index > -2 Then
If index = -1 Then
If size = 0 Or (Not Not data) = 0 Then
ReDim data(0)
data(size) = elem
size = size + 1
Exit Sub
Else 'size <> 0
ReDim Preserve data(0 To size * 2 + 1)
data(size) = elem
size = size + 1
End If
Else 'index <> -1
If index >= size Then
ReDim Preserve data(0 To index)
data(index) = elem
size = index + 1
Else 'index < vSize
data(index) = elem
End If 'index >= vSize
End If 'index = -1
End If 'index > -2
End Sub 'add
I'm trying to do a Do Until Loop to check for duplicates in my combo box. It runs the loop but it never stops looping.
Dim i As Integer = 0
Dim flavors As Integer = flavorsComboBox.Items.Count
Do Until (i < flavors - 1)
If flavors = flavorsComboBox.Items.Count Then
MessageBox.Show("Flavor Already Exists!", "Error")
Else
flavorsComboBox.Items.Add(flavorsComboBox.Text)
End If
Loop
The condition of the loop looks at the i variable and the flavors variable:
Do Until (i < flavors - 1)
But those variables don't ever change at any point in the body of the loop:
If flavors = flavorsComboBox.Items.Count Then
MessageBox.Show("Flavor Already Exists!", "Error")
Else
flavorsComboBox.Items.Add(flavorsComboBox.Text)
End If
You need to add code to change one or both of those variables. But that's still the hard way to do this. Just use the Distinct() method:
Dim items = flavorsComboBox.Items.Distinct().ToArray()
flavorsComboBox.Items.Clear()
flavorsComboBox.Items.AddRange(items)
Here is a simple do until loop
Dim i as integer = 0
Dim flavors as Integer = 10
do until (i > flavors -1)
Console.WriteLine(i.ToString())
i = i +1
loop
Output
0
1
2
3
4
5
6
7
8
9
In your code:
do until (i < flavors - 1)
if i = 0 and flavors is the Count -1 when is 0 greater than count, to enter the condition of the loop.
The next omission is that you never change the value of condition variable of looping, to have an accurate evaluation of the condition to stop the loop.
Try this:
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If AddDistinct(flavorsComboBox, "test") Then
MsgBox("Item did not exist, so it was added.")
Else
MsgBox("Item already existed, so it was not added.")
End If
End Sub
Public Function AddDistinct(cboBox As ComboBox, value As Object) As Boolean
If cboBox.Items.IndexOf(value) = -1 Then cboBox.Items.Add(value) : Return True
Return False
End Function
End Class
You are not resetting the value of flavors
Try this:
Dim i As Integer = 0
Dim flavors As Integer = flavorsComboBox.Items.Count
Do Until (i < flavors - 1)
If flavors = flavorsComboBox.Items.Count Then
MessageBox.Show("Flavor Already Exists!", "Error")
Else
flavorsComboBox.Items.Add(flavorsComboBox.Text)
flavors = flavorsComboBox.Items.Count
End If
Loop
Public Sub GetStationDataFromDatabase()
Dim StationTable As New DataTable
StationTable.TableName = "Station"
Dim Counter As Integer
Dim SqlString As String
Dim OperStaRow As DataRow
Counter = 0
ProgressBar.Visible = True
ProgressBar.Minimum = 1
ProgressBar.Maximum = LocalDataSet.Tables("OR").Rows.Count
ProgressBar.Value = 1
ProgressBar.Step = 1
For Each OperStaRow In LocalDataSet.Tables("OR").Rows
SqlString = "JUST SOME STRING HERE"
ExecuteSqlCommand(SqlString, StationTable)
ProgressBar.PerformStep()
ProgressBar.Refresh()
Counter = Counter + 1
If Counter Mod 20 = 0 Then
Application.DoEvents()
End If
Next
End Sub
so, the error first happpen at progressbar.visible = True. even when i remove it, the error occur the to the line below it. can you tell me what is wrong?
and it happen when user select listbox menu. suppose i have options A and B.
i suspect that there is a typo with progressbar object name. pls check spellings. there is nothing wrong in your code.
other than that,
i suggest that you check row count > 0 before assigning progressbar maximum value.
regards
What is causing 'Index was outside the bounds of the array' error? It can't be my file, defianetly not. Below is my code:
Sub pupiltest()
Dim exitt As String = Console.ReadLine
Do
If IsNumeric(exitt) Then
Exit Do
Else
'error message
End If
Loop
Select Case exitt
Case 1
Case 2
Case 3
End Select
Do
If exitt = 1 Then
pupilmenu()
ElseIf exitt = 3 Then
Exit Do
End If
Loop
Dim score As Integer
Dim word As String
Dim totalscore As Integer = 0
'If DatePart(DateInterval.Weekday, Today) = 5 Then
'Else
' Console.WriteLine("You are only allowed to take the test on Friday unless you missed it")
' pupiltest()
'End If
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
Dim item() As String = line.Split(","c)
founditem = item
Next
Dim stdntfname As String = founditem(3)
Dim stdntsname As String = founditem(4)
Dim stdntyear As String = founditem(5)
Console.Clear()
If founditem IsNot Nothing Then
Do
If stdntyear = founditem(5) And daytoday = founditem(6) Then
Exit Do
ElseIf daytoday <> founditem(6) Then
Console.WriteLine("Sorry you are not allowed to do this test today. Test available on " & item(6).Substring(0, 3) & "/" & item(6).Substring(3, 6) & "/" & item(6).Substring(6, 9))
Threading.Thread.Sleep(2500)
pupiltest()
ElseIf stdntyear <> founditem(5) Then
Console.WriteLine("Year not found, please contact the system analysts")
Threading.Thread.Sleep(2500)
pupiltest()
End If
Loop
End If
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\testtests.csv")
Dim item() As String = line.Split(","c)
Dim mine As String = String.Join(",", item(2), item(3), item(4), item(5), item(6))
For i As Integer = 1 To 10
Console.WriteLine(i.ToString & "." & item(1))
Console.Write("Please enter the word: ")
word = Console.ReadLine
If word = Nothing Or word <> item(0) Then
score += 0
ElseIf word = item(0) Then
score += 2
ElseIf word = mine Then
score += 1
End If
Next
If score > 15 Then
Console.WriteLine("Well done! Your score is" & score & "/20")
ElseIf score > 10 Then
Console.WriteLine("Your score is" & score & "/20")
ElseIf score Then
End If
Next
Using sw As New StreamWriter("F:\Computing\Spelling Bee\stdntscores", True)
sw.Write(stdntfname, stdntsname, stdntyear, score, daytoday, item(7))
Try
Catch ex As Exception
MsgBox("Error accessing designated file")
End Try
End Using
End
End Sub
All help is highly appreciated,
You are constantly replacing the foundItem array when you do founditem = item:
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
Dim item() As String = line.Split(","c)
founditem = item
Next
Also, you are using (=) the assignment operation instead of (==) relational operator, to compare. Refer to this article for help in understanding the difference between the two.
Instead of this: If stdntyear = founditem(5) And daytoday = founditem(6) Then
Use this: If (stdntyear == founditem(5)) And (daytoday == founditem(6)) Then
Now back to your main error. You continue to assign the itemarray to founditem every time you iterate (Which overwrites previous content). At the end of the Iteration you will be left with the last entry in your CSV only... So in other words, founditem will only have 1 element inside of it. If you try to pick out ANYTHING but index 0, it will throw the exception index was outside the bounds of the array
So when you try to do the following later, it throws the exception.
Dim stdntfname As String = founditem(3) 'index 3 does not exist!
To fix it do the following change:
Dim founditem() As String = Nothing
For Each line As String In File.ReadAllLines("F:\Computing\Spelling Bee\stdnt&staffdtls.csv")
'NOTE: Make sure you know exactly how many columns your csv has or whatever column
' you wish to access.
Dim item() As String = line.Split(","c)
founditem(0) = item(0) 'Assign item index 0 to index 0 of founditem...
founditem(1) = item(1)
founditem(2) = item(2)
founditem(3) = item(3)
founditem(4) = item(4)
founditem(5) = item(5)
founditem(6) = item(6)
Next
For more help on how to work with VB.NET Arrays visit this site: http://www.dotnetperls.com/array-vbnet
In your line Dim item() As String = line.Split(","c) there's no guarantee that the correct number of elements exist. It's possible that one of the lines is missing a comma or is a blank trailing line in the document. You might want to add a If item.Length >= 7 and skipping rows that don't have the right number of rows. Also, remember that unlike VB6, arrays in .Net are 0 based not 1 based so make sure that item(6) is the value that you think it is.
The below code should search DataGridView1 which is on the LeaderAccessTable form for an integer that the user inputs into SendFromID, if the DataGridView1's first column contains what the integer that the user has entered into SendFromID then the entire row should be selected. However it doesn't select any rows at all... Can anyone see why? This code is ran from a separate form.
Dim intcount As Integer
For Each Row As DataGridViewRow In LeadersAccessTable.DataGridView1.Rows
If LeadersAccessTable.DataGridView1.Rows(intcount).Cells(0).Value.ToString = SendFromID.Text Then
LeadersAccessTable.DataGridView1.Rows(intcount).Selected = True
End If
Next
MsgBox("Done.")
In the end this code worked.
Dim v_SelectRow As Integer
For counter = 0 To (LeadersAccessTable.DataGridView1.Rows.Count - 1)
For counter2 = 0 To (LeadersAccessTable.DataGridView1.Columns.Count - 1)
If (LeadersAccessTable.DataGridView1.Rows(counter).Cells(0).Value.ToString.Contains(SendFromID.Text)) Then
LeadersAccessTable.DataGridView1.Rows(counter).Cells(0).Selected = True
v_SelectRow = LeadersAccessTable.DataGridView1.CurrentRow.Index
CurrentPoints.Text = LeadersAccessTable.DataGridView1.Item(8, v_SelectRow).Value
'Do Something
Else
'Do Something
End If
Next
Next