Index was outside the bounds of the array? - arrays

I have a text-file(customers.txt) from which I'm trying to extract certain pieces of data from to place in a list-box(lstReportsUnresolved). I'm using commas to split up lines in the text-box and at a certain split, if the text is equal to "No" then the previous split is added to the listbox.
Code:
Private Sub btnUnresolved_Click(sender As Object, e As EventArgs) Handles btnUnresolved.Click
For Each line As String In File.ReadLines("customers.txt")
Dim data As String() = line.Split(",")
If data(18) = "No" Then
lstReportsUnresolved.Items.Add(data(17))
End If
If data(20) = "No" Then
lstReportsUnresolved.Items.Add(data(19))
End If
If data(22) = "No" Then
lstReportsUnresolved.Items.Add(data(21))
End If
If data(24) = "No" Then
lstReportsUnresolved.Items.Add(data(23))
End If
Next
End Sub
It was working fine earlier, but I came back and now try to run it and it stops and highlights the line If data(18)="No" Thenwith the error "An unhandled exception of type 'System.IndexOutOfRangeException' occurred in Semester Two Project.exe" with additional info saying "Index was outside the bounds of the array."
Here is an example of a line from the text file
Mark,Barry,07/04/1996,Redbrook,Sandymount,Dublin,Ireland,094-378231,085-0983623,markbarry96#gmail.com,Basic Cable,VB Fibre Broadband,VB Sports,VB Movies,Chat Chat Phone,VB Anywhere,VB Data,Unavailable Services,Yes,Incorrect Bill,Yes,Poor Tv Reception,No, ,No
Thank you for your help and time

It could be due to File.ReadLines(). The method only reads some (or maybe even one) lines at a time, meaning it could have read less (if it's split into lines) than required to make your split return an array of at least 19 elements. You should use File.ReadAllLines() instead.
Just replace File.ReadLines() with File.ReadAllLines():
For Each line As String In File.ReadAllLines("customers.txt")
If this is a big file and you don't want to use File.ReadAllLines(), you could instead check the end of the array (if the "No" always appears there), instead of having a static index.
EDIT:
Actually, either if you use ReadLines or ReadAllLines you should probably stick with checking from the end:
If data(data.Length - 1) = "No" Then
lstReportsUnresolved.Items.Add(data(data.Length - 2))
End If

Related

application defined or object defined error whey copying data into array

I am used to assigning ranges to arrays. However, for some reason right now I am constantly getting an application or object defined error (the first code line below). The second line below works fine. It is identical to the first line except I just copy the range showing all the variables exist.
I have checked in the watch window, arrActuals is Variant/Variant(). Adding .Value at the end of the first line did not solve the error either. Any ideas on why this is happening?
arrActuals = wkbOVHFile.Sheets(szAOPPage).Range(Cells(iStartCopy, IntActOVHCol), Cells(iEndCopy, IntActOVHCol))
wkbOVHFile.Sheets(szAOPPage).Range(Cells(iStartCopy, IntActOVHCol), Cells(iEndCopy, IntActOVHCol)).Copy
Cells without a qualifying worksheet object defaults to the active sheet, so your code fails when wkbOVHFile.Sheets(szAOPPage) is not the active sheet.
More robust like this:
Dim rng As Range
With wkbOVHFile.Sheets(szAOPPage)
Set rng = .Range(.Cells(iStartCopy, IntActOVHCol), _
.Cells(iEndCopy, IntActOVHCol))
End With
arrActuals = rng.Value
rng.Copy

Check if a string contains all other strings

I am trying to code a part of a software where I try to show the results that match search criteria.
I have a textbox where I can type one or more words I want to search and a listview that contains 4 different columns and a dozen rows. The idea is that each listview row contains lots of words and I want to see only the rows that contain all the words I have typed in the textbox. I have finished the code that searches for one term only. The problem I am having is that I don't fully understand how to do the same, but using multiple terms instead of one term only.
In the textbox, I write the words I want to search separated by a space. I have a variable where I keep the whole content of the listview row separated by : (example => col1row1content:col1row2content:col1row3content,etc). Summarizing, I want to check if a string (the full content of a row) contains all other strings (each word I have typped in the textbox).
This is the code I have implemented:
Dim textboxFullContentArray As String() = textboxSearch.Split(New Char() {" "c})
Dim Content As String
Dim containsAll As Boolean = False
Dim wholeRowContent(listviewMain.Items.Count - 1) As String ' each index of the array keeps the entire row content (one array contains all 4 cells of the row)
' wholeRowContent contains in one index the entire content of a row. That means,
' the index contains the 4 cells that represent an entire row.
' The format is like "rowData1:rowData2:rowData3:rowData4" (omitted for simplicity)
For Q As Integer = 0 To listviewMain.Items.Count - 1
For Each Content In textboxFullContentArray
If wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = True
' rest of the code...
ElseIf Not wholeRowContent(Q).ToLower.Contains(Content) Then
containsAll = False
Exit For
End If
Next
Next
But of course, this code is showing false positives and I think it's not a good solution. I think it must be much easier and I am overcomplicating the concept.
I am using VB.Net 2013
You can determine whether a String contains all of a list of substrings with a single line of code:
If substrings.All(Function(s) str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) Then
Notice that I have actually implemented a case-insensitive comparison, rather than using ToLower or ToUpper.
It may not seem as neat to call IndexOf rather than Contains but guess what: Contains actually calls IndexOf internally anyway:
public bool Contains(string value)
{
return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}
You can write your own extension methods if you want a case-insensitive Contains method:
<Extension>
Public Function Contains(source As String,
value As String,
comparisonType As StringComparison) As Boolean
Return source.IndexOf(value, comparisonType) >= 0
End Function
Your If/Else looks like it could be simplified. I would set your containsAll value to true outside the nested loops, and only if you encounter a "Content" in "textboxFullContentArray" that is not contained in wholeRowContent(Q) you set containsAll to false, otherwise do nothing.
Also, one way to see what's going on is to print statements with the values that are being compared throughout your function, which you can read through and see what is happening at runtime when the false positives occur.
After some hours looking for a simple and effective solution (and trying different codes), I have finally found this solution that I adapted from: Bad word filter - stackoverflow
For Q As Integer = 0 To listviewMain.Items.Count - 1
If textboxFullContentArray.All(Function(b) wholeRowContent(q).ToLower().Contains(b.ToLower())) Then
' my code
End If
Next

Find Array index that contains string

I have file with tags and targets, this is example:
TAG1|TARGET1,TARGET2
TAG2|TARGET3,TARGET4
I start by creating String Array using File.ReadAllLines
Dim MAIN As String() = File.ReadAllLines("")
At some point I have one of targets and I need to know what was the tag index (which array line is it), so for example if I have TARGET3 I want to know it's in second line so it's in MAIN(1) and then I can grab TAG = TAG2.
I can't get it working, I tried few methods:
Array.IndexOf(MAIN,"TARGET3")
always returned -1, it worked with full string tho,
Array.IndexOf(MAIN,"TAG2|TARGET3,TARGET4")
returned 1. I tried with Array.FindIndex, was the same.
So my question is: how to get index of partial array item. Thank you for any help.
You can use Linq to search your array in this way
Dim search = "TARGET3"
Dim line = MAIN.FirstOrDefault(Function(x) x.Contains(search))
This will return directly the line with the matching word

String array not accepting a string

I'm trying to make a simple login program, but I'm having troubles with assigning a value to my two arrays "User()" and "Pass()". I have the following code on a form titled "frmCreate". This is the form I will be using to create the accounts.
Public Class frmCreate
Dim passs() As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnCreate.Click
If Not (txtUser.Text = "") And Not (txtPass.Text = "") Then
userCount = userCount + 1
User(userCount) = txtUser.Text
Pass(userCount) = txtPass.Text
Else
MsgBox("Please enter a username or password")
End If
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
passs(0) = "hi"
End Sub
End Class
The issue I'm getting is as follows:
Error in array
The txtPass and txtUser are both text boxes, which can be edited by the user.
Any help would be much appreciated! (Also, I tried mucking around with the variables and all, the strings after the = sign aren't the problem, and when I set the "userCount" inside the brackets to "0" for example, it still returned the same error)
EDIT Added code as text, rather then image (image still there). Note the extra few lines at the end where I set a new array which I named passs() to "hi". The dim is also further up. If I am declaring my variables incorrectly, please let me know.
EDIT2 Ok, I changed my declaration of "User()" and "Pass()" to = {}. Now my problem is that I'm getting the error that the value is out of the bounds of the array. I understand that this happens when you try to call on a non existent value which is outside the arrays boundaries, but the array I set has no boundaries, and I'm just trying to give it a value, not call on one.
EDIT3 Ugh... Ok tweaked a bit, I've found that if I add an unused value to "User()" then it is able to replace it. So I can get the program to replace already existent values in arrays, but I can not get it to create new values in arrays.
It would appear your User variable is NULL. I presume this is intended to be a list of strings or something similar?
You should check the place you are initializing this variable to make sure it is being created...
You could add an
If User Is Nothing
line at the start of the function to check this, and if the list is null at this point create it.
I have discovered what it is I was doing wrong. See, I thought when I declared a variable with empty parenthesis, it created a dynamic variable. This is obviously not the case. Since setting the size of my variable to the ludicrous size of 50,000, my program now works. Thanks to all who tried to help, and sorry for asking the wrong thing :/
Your problem here is that you only defined the variable array. You never reserved a spot for the array values in memory. Therefore your variable has a value of Nothing.
Before assigning the first item, you must assign room for it...
'We say we want an array
Dim passs() As String
'We ask the memory to reserve six spots for our array
passs = New String(5) {}
'We assign the first spot to the String "hi"
passs(0) = "hi"
However, if you don't know how many items you are going to add in your array, I strongly suggest you to use a List(of T) instead :
Dim passs As New List(of String)
passs.Add("hi")

Error when checking if an array element actually hold data

I have a short app that check if my music files are names to a specific routine (track number and then track name), but I'm getting an error whenever there are no files that need renaming, because the array in initialised, but the first item is nothing, null, empty (however VB refers to it).
To try and fix this, I'm running this check, but I'm still getting an error.
' Array declared like this
Dim nc_full_names(0) As String
<Code goes here to ReDim 'nc_full_names' and add the file name to the array, if a file needs renaming>
For i = 0 To UBound(nc_full_names)
'Checking if the array element actually has something in it like this
If Not nc_full_names Is Nothing Then
My.Computer.FileSystem.RenameFile(nc_full_names(i), nc_new_names(i))
Else
Exit For
End If
Next i
Here is the error that I am getting -
Argument cannont be nothing. Parameter name: file
Can anyone tell me the correct way to carry out this check?
I found that the answer was to check the first element in the array, as opposed the array itself. Thus, changing this...
If Not nc_full_names Is Nothing Then
...to this...
If Not nc_full_names(i) Is Nothing Then
...works just fine.
You can also start with a truly empty array:
Dim nc_full_names(-1) As String
Now nc_full_names.Length = 0.

Resources