VB.NET System.IndexOutOfRangeException: 'Index was outside the bounds of the array.' - vb.net

Hi any idea why i'm getting this error message?
The original piece of code i'm using which works normally.. However, I decided I wanted to add more values to the code hoping it would work.. but I keep getting this error message. And for project a module was made.
(Module Code)
Module Structure_Units
Structure UnitsStruct
Public ValueOne As String
Public ValueTwo As String
Public ValueThree As String
Public ValueFour As String
Public ValueFive As String
Public ValueSix As String
Public Sub New(rawValue As String)
Dim Values() As String = Split(rawValue, ",")
ValueOne = Values(0)
ValueTwo = Values(1)
ValueThree = Values(2)
ValueFour = Values(3)
ValueFive = Values(4)
ValueSix = Values(5)
End Sub
End Structure
End Module
(Original Code)
Imports System
Imports System.IO
Imports System.Collections
Public Class Structures
Dim Units(3) As UnitsStruct
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Label5.Text = Units(ListBox1.SelectedIndex).ValueOne
Label6.Text = Units(ListBox1.SelectedIndex).ValueThree
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim path As String = "C:\Users\Justi\Desktop\SDD Major Project\NLR.txt"
Dim reader As New System.IO.StreamReader(path)
Dim Index As Integer = -1
While Index < 3
Index += 1
Dim Current As String = reader.ReadLine
Dim fields() As String = Current.Split(";"c)
Units(Index).ValueOne = fields(0)
Units(Index).ValueTwo = fields(1)
Units(Index).ValueThree = fields(2)
ListBox1.Items.Add(Units(Index).ValueTwo)
Label1.Text = Units(Index).ValueOne
Label2.Text = Units(Index).ValueTwo
Label3.Text = Units(Index).ValueThree
End While
End Sub
(New Code I attempted to remake)
Imports System
Imports System.IO
Imports System.Collections
Public Class frmLightRail
Dim Units(7) As UnitsStruct
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Label5.Text = Units(ListBox1.SelectedIndex).ValueOne
Label6.Text = Units(ListBox1.SelectedIndex).ValueThree
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim path As String = "C:\Users\Justi\Desktop\SDD Major Project\NLR.txt"
Dim reader As New System.IO.StreamReader(path)
Dim Index As Integer = -1
While Index < 7
Index += 1
Dim Current As String = reader.ReadLine
Dim fields() As String = Current.Split(";"c)
Units(Index).ValueOne = fields(0)
Units(Index).ValueTwo = fields(1)
Units(Index).ValueThree = fields(2)
Units(Index).ValueFour = fields(3)
Units(Index).ValueFive = fields(4)
Units(Index).ValueSix = fields(5)
ListBox1.Items.Add(Units(Index).ValueTwo)
Label1.Text = Units(Index).ValueOne
Label2.Text = Units(Index).ValueTwo
Label3.Text = Units(Index).ValueThree
Label4.Text = Units(Index).ValueFour
Label5.Text = Units(Index).ValueFive
Label6.Text = Units(Index).ValueSix
End While
End Sub

At first glance, it could go wrong if the code tries to read a line from the NLR.txt input file that contains less than 6 fields (separated by semicolons, not commas).
The code is pretty messy. I have the impression that the "original" code is not complete as well. Was the UnitsStruct part of the original code, or have you added/modified that code as well? Why does the original program only read three lines from the input file and your new code seven lines? Why does the original code split each line into three fields and your new code into six fields?
I guess you should analyze your input file in some more detail and share that information with us by adding it to your question. How many lines does (or can) the input file actually contain? In how many fields should each line actually be split? Does each line have a fixed number of fields, or can the number of fields be different per line?

I made the Structure into a Class and made the fields into Properties. I also added a .ToString method so the ListBox would know what to display.
My test.txt file looks like this.
Mary,had,a,little,lamb,it's
The,quick,brown,fox,jumped,over
Now,is,the,time,for,all
We,the,people,of,the,United
Streams need to be disposed. So, let's simplify by using the System.IO File Class. .ReadAllLines returns an array of lines in the file. We loop through each line, passing it to the constructor of the class which sets all the properties. Then the new UnitClass is added to the list, all fleshed out with its properties.
Create a BindingSource and set its DataSource to the list. The BindingSource becomes the DataSource for the ListBox. The same BindingSource is used for each of the labels. This will syn the ListBox and the Labels. As items in the ListBox are selected the proper values appear in each Label.
Class UnitClass
Public Property ValueOne As String
Public Property ValueTwo As String
Public Property ValueThree As String
Public Property ValueFour As String
Public Property ValueFive As String
Public Property ValueSix As String
Public Sub New(rawValue As String)
Dim Values() As String = Split(rawValue, ",")
ValueOne = Values(0)
ValueTwo = Values(1)
ValueThree = Values(2)
ValueFour = Values(3)
ValueFive = Values(4)
ValueSix = Values(5)
End Sub
'The list box will call .ToString on the UnitClass instance to determin what to display
Public Overrides Function ToString() As String
Return ValueTwo
End Function
End Class
Private UnitBinding As BindingSource
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lst As New List(Of UnitClass)
Dim path As String = "C:\Users\*****\Desktop\test.txt"
Dim lines = File.ReadAllLines(path)
For Each line In lines
Dim unit As New UnitClass(line)
lst.Add(unit)
Next
UnitBinding = New BindingSource
UnitBinding.DataSource = lst
ListBox1.DataSource = UnitBinding
Label1.DataBindings.Add(New Binding("Text", UnitBinding, "ValueOne"))
Label2.DataBindings.Add(New Binding("Text", UnitBinding, "ValueTwo"))
Label3.DataBindings.Add(New Binding("Text", UnitBinding, "ValueThree"))
Label4.DataBindings.Add(New Binding("Text", UnitBinding, "ValueFour"))
Label5.DataBindings.Add(New Binding("Text", UnitBinding, "ValueFive"))
Label6.DataBindings.Add(New Binding("Text", UnitBinding, "ValueSix"))
End Sub

Related

Utilizing wildcards and variables for getFiles

I am kinda new to VB.net, so I am not sure if I try this the right way. I have the following piece of code.
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Dim TextLine As String
Do While objReader.Peek() <> -1
Dim newString As String = TextLine.Replace(vbCr, "").Replace(vbLf, "") & ".wav"
Dim SongName As String = My.Computer.FileSystem.GetName(newString)
Dim MyFile As String = Dir("C:\AllSongs\" & newString)
Dim Searchquery As IEnumerable(Of String) = IO.Directory.EnumerateFiles("C:\AllSongs", "*", IO.SearchOption.AllDirectories).Where(Function(f) IO.Path.GetFileNameWithoutExtension(f).IndexOf(SongName, StringComparison.CurrentCultureIgnoreCase) >= 0)
For Each Result In Searchquery
ListBox1.Items.Add(Result)
Next
I am trying to use the lines in the text file, and get the .wav in AllSongs dir that partially correspond in these files. Can it be done?
Edit: Part of the code contains a media player. I want to be able to play songs from this player, by choosing files in the list.
Private Sub ListBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
AxWindowsMediaPlayer1.URL = ListBox1.SelectedItem
Dim variables As New Dictionary(Of String, String)()
Dim selectedItem As Object = ListBox1.SelectedItem
variables("MyDynamicVariable") = selectedItem ' Set the value of the "variable"
selectedItem1 = selectedItem
Dim value As String = variables("MyDynamicVariable") ' Retrieve the value of the variable
End Sub
Incidental to the question, but important, is that when you're working with files it's often necessary to clean up some resources (file handles, I guess) that the operating system uses even though you don't see it directly in the code as written. There is a way of doing that automatically with the Using statement, as shown in the following code.
To find out if a filename contains some text (string), you can extract the filename with no path or extension with Path.GetFileNameWithoutExtension and check if it contains the desired string with the IndexOf function, which lets you ignore uppercase/lowercase by specifying how to do the check.
I notice from an update to the question that some improvements can be made, such as using a Class for the song entries so that the displayed list can have more information behind it, which means that the song name can be shown on its own but you can get the full path to the file when you click on it.
I made a new Windows Forms project and added just a ListBox to it, and used this code to show the full path (which you can use for your media player) to the song when its name is double-clicked:
Imports System.IO
Public Class Form1
Public Class SongEntry
Property Name As String
Property FullName As String
End Class
Sub PopulateSongList(musicDirectory As String, songsList As String)
Dim songList As New List(Of SongEntry)
Using sr As New System.IO.StreamReader(songsList)
Do While Not sr.EndOfStream
Dim thisSong = sr.ReadLine()
If thisSong <> "NaN" Then
Dim fs = Directory.EnumerateFiles(musicDirectory, "*.wav", SearchOption.AllDirectories).
Where(Function(f) Path.GetFileNameWithoutExtension(f).IndexOf(thisSong, StringComparison.CurrentCultureIgnoreCase) >= 0).
Select(Function(g) New SongEntry With {.Name = Path.GetFileNameWithoutExtension(g), .FullName = g})
songList.AddRange(fs)
End If
Loop
End Using
ListBox1.DataSource = songList
ListBox1.DisplayMember = "Name"
ListBox1.ValueMember = "FullName"
End Sub
Private Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick
Dim lb = DirectCast(sender, ListBox)
If lb.SelectedIndex >= 0 Then
Dim fullPathToSong = lb.SelectedValue.ToString()
MsgBox(fullPathToSong)
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim songsList = "C:\temp\AllSongs\songsList.txt"
Dim musicDirectory = "C:\temp\AllSongs"
PopulateSongList(musicDirectory, songsList)
End Sub
End Class

Parsing String into an Array (VB)

I have tried to make a program that would parse a raw list from Chrome://policy (input by RichTextbox) into a text array, then dump it into another RichTextbox. All of the raw string are exactly 32 characters long, followed by a comma. Here is the code:
Public Class Form1
Dim tempExt As String
Dim extsHandled As Integer
Dim numOfExts As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If RichTextBox1.Text = "" Then
MsgBox("Please enter the raw extensions from Chrome://policy")
Else
RichTextBox3.Text = RichTextBox1.Text
numOfExts = TextBox1.Text
Dim place As Integer = 0
Dim exts(150) As String
While extsHandled < numOfExts
tempExt = RichTextBox1.Text.Substring(0, 32)
exts(place) = tempExt
RichTextBox1.Text.Remove(0, 33)
place = place + 1
extsHandled = extsHandled + 1
End While
Dim newPlace As Integer = 0
While newPlace < numOfExts
RichTextBox2.AppendText(exts(newPlace))
newPlace = newPlace + 1
RichTextBox2.AppendText(" ")
End While
End If
End Sub
End Class
Most of it works, but it would seem something is going wrong with removing the characters from the richtextbox, as when I run it, it only parses the first part of the string over and over:
Am I doing something wrong?
If it's always like that you can do it like this:
RichTextBox3.Text = RichTextBox1.Text.Replace(",", vbNewLine)
The #3 is your result, while #1 is original right?
Ah yeah, you can count how many there simply by
RichTextBox2.Text= RichTextBox1.Text.Split({","}, StringSplitOptions.RemoveEmptyEntries).Count.ToString
This line returns a new string:
RichTextBox1.Text.Remove(0, 33)
It does not modify the textbox in place. The next iteration through the loop, you're still working with the original value, looking at the same set of 32 characters at the beginning of the string.
Additionally, nothing in this code initializes the extsHandled variable. You should turn on Option Strict, which helps catch that kind of error. Running of Option Strict off is poor practice. You should also give a meaningful name to any control you will actually reference from code.
It's not clear to me right now the exact format. If it's all on the same line (no line break characters as part of the string, even if it wraps), this should work:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If String.IsNullOrWhitespace(RichTextBox1.Text) Then
MsgBox("Please enter the raw extensions from Chrome://policy")
Exit Sub
End If
RichTextBox3.Text = RichTextBox1.Text
Dim exts() As String
Using rdr As New TextFieldParser(RichTextBox1.Text)
rdr.TextFieldType = FileIO.FieldType.Delimited
rdr.Delimiters = New String() {","}
exts = rdr.ReadFields()
End Using
For Each ext As String In exts
RichTextBox2.AppendText(ext)
Next ext
RichTextBox1.Text = ""
End Sub
The problem is this code doesn't do anything. The array is gone when the method ends. Consider making the array a property of the class, or having method that returns the array as the result.
You can also look at this, to save typing into the textbox, though it's just a starting point:
Public Function GetChromeExtensionKeys() As IEnumerable(Of String)
Dim BasePath As String =
EndEnvironment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
BasePath = Path.Combine(BasePath, "Google\Chrome\User Data")
Dim dflt As String = Path.Combine(BasePath, "Default\Extensions")
Dim profileExts() As String = Directory.GetDirectories(BasePath, "Profile *").
Select(Function(p) Path.Combine(p, "Extensions"))
Dim result As New List(Of String)()
result.AddRange(Directory.GetDirectories(dflt))
For Each folder As String In profiles
result.AddRange(Directory.GetDirectories(folder))
Next folder
Return result.Select(Function(e) Path.GetFileName(e)).Distinct()
Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each ext As String In GetChromeExtensionKeys()
RichTextBox2.AppendText(ext)
Next ext
End Sub

How do I get the data of datagridview per row and show it in the textboxes in the ANOTHER FORM? VB.Net

I have two forms. One is the Main.vb which the datagridview is located and the other one is the EditPage.vb which consist a set of textboxes. If I click a row in datagridview and click the edit button in the datagridview in Main.vb it will go in EditPage.vb. Then, the data of the clicked row will show in the textboxes in EditPage.vb... I'll try to public my variables and set it in the other form(EditPage.vb) but still the data of the selected row didn't shown up. What's something wrong in my code even it has no error?
Here's the code of my datagridview Cell Content Click in Main.vb
Private Sub tblAttendance_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles tblAttendance.CellContentClick
Dim row As DataGridViewRow = tblAttendance.CurrentRow
Try
id = row.Cells(0).Value.ToString()
firstname = row.Cells(1).Value.ToString
lastname = row.Cells(2).Value.ToString
birthdate = row.Cells(3).Value.ToString
position = row.Cells(4).Value.ToString
sex = row.Cells(5).Value.ToString
address = row.Cells(6).Value.ToString
contact_num = row.Cells(7).Value.ToString
email = row.Cells(8).Value.ToString
Catch ex As Exception
MessageBox.Show("Input Data Properly!", "Error Message")
End Try
End Sub
Here's the code of my Edit Button in Main.vb
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim result As Integer = MessageBox.Show("Are you sure you want to Edit the Info?", "Validation", MessageBoxButtons.YesNoCancel)
If DialogResult.Yes Then
Edit_Page.Show()
ElseIf DialogResult.No Then
MessageBox.Show("Edit Cancelled", "Message")
End If
End Sub
And Here's my Public Variables in Main.vb
Public id As Integer
Public firstname As String
Public lastname As String
Public birthdate As String
Public position As String
Public sex As String
Public address As String
Public contact_num As String
Public email As String
My Public Variables in EditPage.vb to get the public variables in Main.vb
Public id_edit As Integer
Public firstname_edit As String
Public lastname_edit As String
Public birthdate_edit As String
Public position_edit As String
Public sex_edit As String
Public address_edit As String
Public contact_num_edit As String
Public email_edit As String
The code in the of the form of Edit.Page.vb or called Edit_Page_Load
id_edit = Main.id
firstname_edit = Main.firstname
lastname_edit = Main.lastname
birthdate_edit = Main.birthdate
position_edit = Main.position
sex_edit = Main.sex
address_edit = Main.address
contact_num_edit = Main.contact_num
email_edit = Main.email
firstname_txtbox.Text = firstname_edit
lastname_txtbox.Text = lastname_edit
DateTimePicker1.Text = birthdate_edit
position_txtbox.Text = position_edit
sex_combo.Text = sex_edit
address_txtbox.Text = address_edit
contact_mask.Text = contact_num_edit
email_txtbox.Text = email_edit
AGAIN, MY PROBLEM IS I CAN'T GET THE DATA OF THE SELECTED ROW OF MY DATAGRIDVIEW IN MAIN.VB AND SHOW IT IN EDITPAGE.VB'S TEXTBOXES.
Declare a class (Form level) level Public variable for a binding source.
Public bind As New BindingSource()
Bind to your DataGridView
Private Sub FillGrid()
Dim dt As New DataTable
Using cn As New SqlConnection(My.Settings.CoffeeConnectionString)
Dim strSQL As String = "Select * From Coffees;"
Using cmd As New SqlCommand(strSQL, cn)
'dr As SqlDataReader
cn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader
dt.Load(dr)
End Using
End Using
End Using
bind.DataSource = dt
DataGridView1.DataSource = bind
End Sub
Then on the second form use the BindingSource from the first form.
Private Sub TestBindingSource_Load(sender As Object, e As EventArgs) Handles MyBase.Load
txtCoffeeName.DataBindings.Add("Text", ExcelToDGV.bind, "Name")
End Sub

Own class can't convert string to integer

https://imgur.com/a/gaXh4
Ok so I have a problem a really weird problem. So I created a new class which is a new type of TextBox. It keeps track of the objects created from it with the help of a list but. This all works, with for each I can get all objects of the class but when I want to convert the string from the TextBox into a integer I can't do it because it thinks its not convertable eventhought the string only consists out of number symbols
Code for Button
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'TextBox1.Text = CInt(SumTextBox1.Text) + CInt(SumTextBox2.Text)
For Each item As SumTextBox In SumTextBox.sumList
Dim textItem As SumTextBox = item
TextBox1.Text = CInt(TextBox1.Text) + CInt(textItem.Text)
Next
End Sub
Public Class SumTextBox
Inherits TextBox
Public Shared sumList As New List(Of SumTextBox)
Sub New()
Size = New Size(90, 10)
sumList.Add(Me)
End Sub
End Class
Try using Convert.toInt32(TextBox1.Text) and the same for textitem.text

Saving and loading a game in vb.net

Is there away I can save or load a game a lot more easier than I have?
Saving Code
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("c:\Pugio Cadite\CharacterInformation.txt", True)
file.WriteLine(charactername)
file.WriteLine(characterrace)
file.WriteLine(characterclass)
file.WriteLine(characterGender)
file.WriteLine(charactergold)
file.WriteLine(characterlevel)
file.Close()
and I have not yet wrote the load function.
Imports System.Xml.Serialization
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'save the program variables
Dim p As New ProgramVars
p.Prop1 = "1"
p.Prop2 = "2"
p.Prop3 = "3"
p.Prop4 = "4"
Dim strFilename As String = "C:\Junk\Junk.xml"
p.Save(strFilename)
'load them into a different object
Dim p2 As ProgramVars = ProgramVars.Load(strFilename)
MsgBox(p2.Prop3)
End Sub
End Class
<Serializable>
Public Class ProgramVars
Property Prop1 As String
Property Prop2 As String
Property Prop3 As String
Property Prop4 As String
Sub Save(filename As String)
Using fs As New System.IO.FileStream(filename, IO.FileMode.OpenOrCreate)
Dim xs As New XmlSerializer(GetType(ProgramVars))
xs.Serialize(fs, Me)
End Using
End Sub
Shared Function Load(filename As String) As ProgramVars
Using fs As New System.IO.FileStream(filename, IO.FileMode.OpenOrCreate)
Dim xs As New XmlSerializer(GetType(ProgramVars))
Return xs.Deserialize(fs)
End Using
End Function
End Class