How to write a List(of) to a text file and retrieve it (vb.net) - vb.net

Title. I need to write my ListOf, which just contains values such as Zero, Zero, One, One, Two, etc to a text file, and then load back up again. Any help appreciated!

Hello & Welcome to Stack Overflow!. In the future please show some effort when asking a question and at least google or even bing your question first, there are a stack of tutorials regarding your question.With that being said, I am going to give you a lifeline.From what I can tell, you want to write your list to a text file and then read from that text file.
Module Module1
Dim mylist As List(Of String) = New List(Of String)
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim newfile As String = "myTextFile.txt"
Dim newPath As String = System.IO.Path.Combine(desktopPath, newfile)
Sub Main()
mylist.Add("Zero")
mylist.Add("One")
mylist.Add("Two")
mylist.Add("Three")
writer()
End Sub
Sub writer()
Using sw As New System.IO.StreamWriter(newPath)
For Each item As String In mylist
sw.WriteLine(item)
Next
sw.Flush() ''yeap I'm the sort of person that flushes it then closes it
sw.Close()
End Using
reader()
End Sub
Sub reader()
Using sr As New System.IO.StreamReader(newPath)
Console.WriteLine(sr.ReadToEnd)
sr.Close()
End Using
Console.ReadKey()
End Sub
End Module
I didn't put too much effort into this, I will leave the rest up to you, however this should get your well and truly on your way.This was done with a Console applicationAlso if you have any problems or even a question or two regarding my answer, leave a comment and I will do my best to answer you and help you out as I know learning something for the first time can be difficult and you will have lots of questions.EDIT: If you need to load each value separately eg skip the first 4 lines and only read the 5th line, you should look into learning how to do a loop.
EDIT - Here is what I think you are trying to achieve just from reading your comments.
''Reads whatever is in the newPath Textfile and addes the words to a listbox or wherever is needed.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
ListBox1.Items.Clear() ''This is stop double ups.
Dim myTextFile = System.IO.File.ReadAllLines(newPath)
For Each word As String In myTextFile
ListBox1.Items.Add(word) '' change this to mylist if need be
''mylist.Add(word)
Next
End Sub
This should fix your problem, although you may need to clear the mylist first or even create another array.

Here's some sandbox code:
Imports System.Xml.Serialization
Imports System.IO
Public Class frmTest
Dim l1 As New List(Of String)
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
l1.AddRange({"1", "b", "7"})
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(List(Of String)))
' To write to a file, create a StreamWriter object.
Dim myWriter As StreamWriter = New StreamWriter("C:\temp\list.xml")
mySerializer.Serialize(myWriter, l1)
myWriter.Close()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myFileStream As FileStream = New FileStream("C:\temp\list.xml", FileMode.Open)
Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(List(Of String)))
' Call the Deserialize method and cast to the object type.
l1 = New List(Of String) ' refresh for test
l1 = CType(mySerializer.Deserialize(myFileStream), List(Of String))
Stop ' l1 is populated
End Sub
End Class

Related

VB.NET - System.AccessViolationException: 'Attempted to read or write protected memory...' Occurs sporadically when using autoCompleteSource

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
I started getting this exception after trying to implement AutoComplete into one of my text boxes. It seems to occur somewhat sporadically? It often occurs when trying to use AutoComplete within a couple seconds of loading it's panel but has occured upwards of 5/6 seconds afterwards too. Additionally if it doesn't occur, the AutoComplete can be used endlessly without crashing.
I've had the same error occur on two different machines so I'm really unsure of what could be causing this and would be endlessly grateful if someone could point me in the right direction!
I've tried to strip out all the parts that definitely aren't causing it to save space.
This code runs first:
Private Sub btnManagerEditItem_Click(sender As Object, e As EventArgs) Handles btnManagerEditItem.Click
refreshEditItemsScreen(False) ' clears all on screen data and repopulates DataGrid
txtManagerEditItemsSearchName.AutoCompleteMode = AutoCompleteMode.SuggestAppend
txtManagerEditItemsSearchName.AutoCompleteSource = AutoCompleteSource.CustomSource
End Sub
Private Sub refreshEditItemsScreen(refreshDatabase As Boolean)
dtgrdManagerEditItems.Rows.Clear() ' DataGridView displays items to user.
If refreshDatabase Then
updateItemDatabase() ' reads the database from file and updates _itemDatabase with it
End If
For Each entry In _itemDatabase ' Global variable holding the database
dtgrdManagerEditItems.Rows.Add(entry.Name, entry.Price.ToString("c"), entry.UniqueID, getStaffDictionary(entry.StaffID))
Next
End Sub
Private Sub updateItemDatabase()
_itemDatabase = readItemDatabaseFromFile()
End Sub
Private Function readItemDatabaseFromFile() As List(Of Item)
Dim pathtofile As String = IO.Path.Combine(My.Application.Info.DirectoryPath.Substring(0, My.Application.Info.DirectoryPath.Length - 21), "Item Database.xml")
Dim itemDatabaseFromFile As New List(Of Item)
If System.IO.File.Exists(pathtofile) Then
Dim objStreamReader As New StreamReader(pathtofile)
Dim xsSerialize As New XmlSerializer(itemDatabaseFromFile.GetType)
itemDatabaseFromFile = xsSerialize.Deserialize(objStreamReader)
objStreamReader.Close()
End If
Return itemDatabaseFromFile
End Function
Then this code runs when you start typing in the AutoCorrect box:
Private Sub txtManagerEditItemsName_TextChanged(sender As Object, e As EventArgs) Handles txtManagerEditItemsSearchName.TextChanged
txtManagerEditItemsSearchName.AutoCompleteCustomSource = _autoCompleteSource
End Sub
_autoCompleteSource gets it's value when this code is ran on form load (updateItemDatabase() is also ran on form load):
Private Sub updateAutoCompleteSource()
' reads the id dictionary from file and adds it to the auto complete source
For Each Itm In readItemIDDictionaryFromFile().Keys
_autoCompleteSource.Add(Itm)
Next
End Sub
Private Function readItemIDDictionaryFromFile() As Dictionary(Of String, String)
Dim pathtofile As String = IO.Path.Combine(My.Application.Info.DirectoryPath.Substring(0, My.Application.Info.DirectoryPath.Length - 21), "ID Dictionary.txt")
Dim output As New Dictionary(Of String, String)
If File.Exists(pathtofile) Then
For Each line In IO.File.ReadAllLines(pathtofile)
Dim parts() As String = line.Split(",")
output.Add(parts(1), parts(0))
Next
Return output
End If
End Function
Sorry if some of this code was unnecessary to post, I'm pretty lost as to what's causing the error so I just posted everything that runs before it occurs that I think could be related to it.
Thank you

Could someone explain where are the errors in this code in vb.net

I'm new to this site and also a newbee in vb.net, I created a simple form in vb.net, a form with 3 buttons, by clicking Button1 Species1.txt is created, and by clicking Button2 the lines in Species1.txt are copied in a String Array called astSpecies(), and by Button3 the String Array is copied in a new file, named Species2.txt, below is the code.
Public Class Form4
Dim astSpecies() As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myStreamWriter = New StreamWriter("C:\Users\Administrator\Documents\species1.txt", True)
myStreamWriter.WriteLine("Pagasius pangasius")
myStreamWriter.WriteLine("Meretrix lyrata")
myStreamWriter.WriteLine("Psetta maxima")
myStreamWriter.WriteLine("Nephrops norvegicus")
myStreamWriter.WriteLine("Homarus americanus")
myStreamWriter.WriteLine("Procambarus clarkii")
myStreamWriter.Close()
MsgBox("list complete")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim myStreamReader = New StreamReader("C:\Users\Administrator\Documents\species1.txt")
Dim i As Integer
Dim stOutput As String
stOutput = ""
Do While Not myStreamReader.EndOfStream
astSpecies(i) = myStreamReader.ReadLine
stOutput = stOutput & astSpecies(i) & vbNewLine
i = i + 1
Loop
myStreamReader.Close()
MsgBox(stOutput)
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim myStreamWriter = New StreamWriter("C:\Users\Administrator\Documents\species2.txt", True)
Dim o As Integer
Do While o <= astSpecies.Length
myStreamWriter.WriteLine(astSpecies(o))
o = o + 1
Loop
myStreamWriter.Close()
End Sub
End Class
First of all, you should make a few settings when it comes to VB.Net. 1.) set Option Strict to On 2.) remove the VB6 namespace. VB6 is the old Visual Basic. There are many functions in this that are inefficient from today's perspective. So please do not write MsgBox() but MessageBox.Show("").
(If you still need control characters such as NewLine or Tab, you can set a selective reference with Imports Microsoft.VisualBasic.ControlChars. Sounds contradictory, but it is useful, because why should you also write ChrW(9), it is not legible.)
I quickly started a project myself and wrote whatever you wanted.
I still don't quite understand why you first write things into a text file, then read them out, and then write that into a second text file – I want to say: where do the strings originally come from? The strings must have been there already? Anyway, I filled a List(of String) in the Button2_Click procedure. This has the advantage that you don't have to know in advance how many strings are coming, and you can sort them later and so on ...
You should also discard all Writers when you no longer need them. So use Using. Otherwise it can happen that the written files are not discarded and you can no longer edit the file.
Imports Microsoft.VisualBasic.ControlChars
Imports Microsoft.WindowsAPICodePack.Dialogs
Public NotInheritable Class FormMain
Private Path As String = ""
Private allLines As New List(Of String)
Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.BackColor = Color.FromArgb(161, 181, 165)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using OFolderD As New CommonOpenFileDialog
OFolderD.Title = "Ordner auswählen"
OFolderD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
OFolderD.IsFolderPicker = True
If OFolderD.ShowDialog() = CommonFileDialogResult.Ok Then
Path = OFolderD.FileName
Else
Return
End If
End Using
Path &= "\Data.txt"
Using txtfile As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Path, True)
txtfile.WriteLine("Pagasius pangasius")
txtfile.WriteLine("Meretrix lyrata")
txtfile.WriteLine("Psetta maxima")
txtfile.WriteLine("Nephrops norvegicus")
txtfile.WriteLine("Homarus americanus")
txtfile.WriteLine("Procambarus clarkii")
txtfile.Close()
End Using
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'read all Text
Dim RAT() As String = System.IO.File.ReadAllLines(Path, System.Text.Encoding.UTF8)
If RAT.Length = 0 OrElse RAT.Length = 1 Then
MessageBox.Show("The File only contains 0 or 1 characters.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand)
Return
End If
allLines.AddRange(RAT)
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim Pfad_txt As String = Path.Substring(0, Path.LastIndexOf("\"c)) & "\Data2.txt"
Using txtfile As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Pfad_txt, True)
For Each Line As String In allLines
txtfile.WriteLine(Line)
Next
txtfile.Close()
End Using
End Sub
End Class
By the way: I use a FolderBrowserDialog in the Button1_Click procedure. This should be done so that the program also runs properly on other PCs. In order to be able to use the FBD, you have to download Microsoft.WindowsAPICodePack.Dialogs in Visual Studio's own Nuget package manager.
how to set Option Strict to On
How to uncheck VB6.
how to install FolderBrowserDialog in Visual Studio
Button1
If you want to use a StreamWriter it should be disposed. Classes in the .net Framework that have a Dispose method may use resources outside of the framework which need to be cleaned up. The classes shield you from these details by provided a Dispose method which must be called to properly do the clean up. Normally this is done with Using blocks.
I used a string builder which saves creating and throwing away a string each time you change the string. You may have heard that strings are immutable (cannot be changed). The StringBuilder class gets around this limitation. It is worth using if you have many changes to your string.
The File class is a .net class that you can use to read or write files. It is not as flexible as the stream classes but it is very easy to use.
Button 2
When you declared your Array, you declared an array with no elements. You cannot add elements to an array with no space for them. As Daniel pointed out, you can use the .net class List(Of T) The T stands for Type. This is very good suggestion when you don't know the number of elements in advance. I stuck with the array idea by assigning the array returned by File.ReadAllLines to the lines variable.
You get the same result by simply reading all the text and displaying it.
Button 3
Again I used the File class here which allows you to complete your task in a single line of code. Using 2 parameters for the String.Join method, the separator string and the array to join, we reproduce the original file.
Private SpeciesPath As String = "C:\Users\maryo\Documents\species1.txt"
Private lines As String()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sb As New StringBuilder
sb.AppendLine("Pagasius pangasius")
sb.AppendLine("Meretrix lyrata")
sb.AppendLine("Psetta maxima")
sb.AppendLine("Nephrops norvegicus")
sb.AppendLine("Homarus americanus")
sb.AppendLine("Procambarus clarkii")
File.WriteAllText(SpeciesPath, sb.ToString)
MsgBox("list complete")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
lines = File.ReadAllLines(SpeciesPath)
MessageBox.Show(String.Join(Environment.NewLine, lines))
'OR
MessageBox.Show(File.ReadAllText(SpeciesPath))
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
File.WriteAllLines("C:\Users\maryo\Documents\species2.txt", lines))
End Sub

VB Can I sort multiple list boxes together using criteria from one list box

So as part of a school project I am creating a program that uses a Public Structure:
Public Structure ClientDatabase
Dim clientID As Integer
<VBFixedString(15)> Dim forename As String '15 bytes
<VBFixedString(15)> Dim surname As String '15 bytes
<VBFixedString(30)> Dim address1 As String '30 bytes
<VBFixedString(9)> Dim postcode As String '9 bytes
Dim Rdate As Date '8 bytes
<VBFixedString(1000)> Dim notes As String '1000 bytes
Dim p_homeIns As Boolean '4 bytes
Dim p_reMort As Boolean '4 bytes
Dim p_homemover As Boolean '4 bytes
Dim p_firstbuy As Boolean '4 bytes
Dim p_buylet As Boolean '4 bytes
Dim p_lifeinsur As Boolean '4 bytes
Dim p_criticalIllness As Boolean '4 bytes
Dim p_IncomeProtec As Boolean '4 bytes
End Structure
where the user can create and view clients' information in a table format. This 'table' was created using 3 list boxes. I know there are probably a million ways that this could have been done more efficiently but that's just how I've done it. Here is the code for how information is read into each list box:
filename = "D:\temp\clients.txt"
FileOpen(1, filename, OpenMode.Random, OpenAccess.Read, OpenShare.LockRead, 1103)
filelength = LOF(1)
numrecs = filelength / 1103
For index = 1 To numrecs
FileGet(1, client, index)
ListBoxClientID.Items.Add(client.clientID)
ListBoxClientID.Items.Add("")
ListBoxFname.Items.Add(client.forename)
ListBoxFname.Items.Add("")
ListBoxSname.Items.Add(client.surname)
ListBoxSname.Items.Add("")
ListBoxAddress.Items.Add(client.address1)
ListBoxAddress.Items.Add("")
Next
FileClose(1)
and I have attached a picture of how this main menu looks. Is there anyway that I could sort the Clients by, for example, their first name and then the client ID and Surname and Address would also sort accordingly so that the information is still correct?
I would suggest abandoning the Structure and go with a DataTable bound to a DataGridView which is essentially how you want to display the data anyways. That away you can serialize/deserialize the DataTable to an XML file. Take a look at this example; all I did was create a form, add a BindingSource, BindingNavigator, and DataGridView, and I added a TextBox and Button to the BindingNavigator:
Public Class Form1
Private clients As DataTable
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Create a new instance of a datatable
clients = New DataTable("Clients")
'Add your columns
clients.Columns.AddRange({
New DataColumn("client_id", GetType(Integer)) With {.AutoIncrement = True},
New DataColumn("forename") With {.MaxLength = 15},
New DataColumn("surname") With {.MaxLength = 15},
New DataColumn("address1") With {.MaxLength = 30},
New DataColumn("postcode") With {.MaxLength = 9},
New DataColumn("rdate", GetType(DateTime)),
New DataColumn("notes") With {.MaxLength = 1000},
New DataColumn("home_insurance", GetType(Boolean)),
New DataColumn("mortgage", GetType(Boolean)),
New DataColumn("home_mover", GetType(Boolean)),
New DataColumn("first_time_buyer", GetType(Boolean)),
New DataColumn("buy_let", GetType(Boolean)),
New DataColumn("life_insurance", GetType(Boolean)),
New DataColumn("critical_illness", GetType(Boolean)),
New DataColumn("income_protection", GetType(Boolean))
})
'Check if the file exists to deserialize the data
If IO.File.Exists("D:\temp\clients.xml") Then
clients.ReadXml("D:\temp\clients.xml")
End If
'Bind the controls
BindingSource1.DataSource = clients
DataGridView1.DataSource = clients
BindingNavigator1.BindingSource = BindingSource1
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
'Create a file if it does not exist
If Not IO.File.Exists("D:\temp\clients.xml") Then
IO.File.Create("D:\temp\clients.xml")
End If
'Serialize the data
clients.WriteXml("D:\temp\clients.xml", XmlWriteMode.WriteSchema)
Catch ex As Exception
'Display any errors
MessageBox.Show("There was an error serializing the data.", "Error", MessageBoxButtons.OK)
Console.WriteLine(ex.Message)
End Try
End Sub
Private Sub ToolStripButtonSearch_Click(sender As Object, e As EventArgs) Handles ToolStripButtonSearch.Click
If String.IsNullOrWhiteSpace(ToolStripTextBoxSearch.Text) Then
'If there is no String, remove the filter
BindingSource1.RemoveFilter()
Else
'If there is
BindingSource1.Filter =
$"forename = '{ToolStripTextBoxSearch.Text}'
OR surname = '{ToolStripTextBoxSearch.Text}'
OR CONVERT(client_id, 'System.String') = '{ToolStripTextBoxSearch.Text}'"
End If
End Sub
End Class
Firstly. I would recommend that you never use controls as your primary place to store data. It's much better to create a separate object such as a List(Of ClientDatabase) so that it can't accidentally be modified by users or bad code.
Have a read at the SOLID programming principle
With that in mind, have a look at the code below. It looks a bit different to your code, but I've added some comments along the way.
Also a good thing to get into the habit of doing, Write your methods so that, as much as possible, they do a single thing. Instead of piling all that code into a single method, separate it into separate methods such as LoadData, SortClientListByclientId, ClearListBoxes andPopulateListBoxes
'OK. First thing, this creates the list I mentioned earlier
Dim clientRecords As New List(Of ClientDatabase)
'So here is the replacement for your original method.
'Its much easier to tell what it does :-)
Private Sub WhateverOriginalMethodIs()
LoadCLientList()
SortClientListByclientID()
PopulateListboxes()
End Sub
'This method carries out the single task of reading your data
'into the list called clientRecords
Private Sub LoadClientList()
filename = "D:\temp\clients.txt"
FileOpen(1, filename, OpenMode.Random, OpenAccess.Read, OpenShare.LockRead, 1103)
filelength = LOF(1)
numrecs = filelength / 1103
For Index As Integer = 1 To numrecs
Dim client As New ClientDatabase
FileGet(1, client, Index)
clientRecords.Add(client)
Next
FileClose(1)
End Sub
'Now that the data is separated from your listbox, you can sort it
'using the method .OrderBy which takes a lambda method as its
'parameter to decide which property you want to sort by
Private Sub SortClientListByclientID()
clientRecords = clientRecords.OrderBy(Function(x) x.clientID)
End Sub
'As above, but by surname
Private Sub SortClientListByclientSurname()
clientRecords = clientRecords.OrderBy(Function(x) x.surname)
End Sub
'As above, but by address
Private Sub SortClientListByAddress()
clientRecords = clientRecords.OrderBy(Function(x) x.address1)
End Sub
'This is pretty self explanatory. A good reason for separating this
'out is so that you can re-use the code, and in future, if you want to
'change it, you only have to edit this one block of code instead of several
'if you use the code in multiple parts of you overall program
Private Sub PopulateListboxes()
ClearListBoxes()
For Each record As ClientDatabase In clientRecords
For Each client As ClientDatabase In clientRecords
AddClientToListBoxes(client)
Next
Next
End Sub
'Same again here there is a programming principle called "DRY"
'Don't Repeat Yourself :-) You can reuse this elsewhere now.
Private Sub AddClientToListBoxes(client As ClientDatabase)
ListBoxClientID.Items.Add(client.clientID)
ListBoxClientID.Items.Add("")
ListBoxFname.Items.Add(client.forename)
ListBoxFname.Items.Add("")
ListBoxSname.Items.Add(client.surname)
ListBoxSname.Items.Add("")
ListBoxAddress.Items.Add(client.address1)
ListBoxAddress.Items.Add("")
End Sub
'Finally - I added this bit to make an easy way of clearing the ListBoxes
Private Sub ClearListBoxes()
ListBoxClientID.Items.Clear
ListBoxFname.Items.Clear
ListBoxSname.Items.Clear
ListBoxAddress.Items.Clear
End Sub

VB.NET Program is always reading last created textfile

Trying to create a login form,
My coding is currently:
Imports System
Imports System.IO
Public Class frmLogin
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String
Dim files As Integer
Dim filepath As String
Public Structure info
Dim U As String
Dim P As String
End Structure
Dim details As info
Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
If txtusername.Text = details.U And txtpassword.Text = details.P Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
End Sub
Private Sub btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
files = files + 1
filepath = "C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt"
Dim di As DirectoryInfo = New DirectoryInfo("C:\Users\TheGlove\Desktop\Alex's Program")
folderpath = "C:\Users\TheGlove\Desktop\Alex's Program"
files = System.IO.Directory.GetFiles(folderpath, "*.txt").Count
For Each fi In di.GetFiles()
MsgBox(fi.Name)
Dim FILE = System.IO.File.ReadAllLines("C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt")
Dim myArray As String() = FILE
details.U = myArray(0)
details.P = myArray(1)
Next
End Sub
End Class
Button 1 will be merged with btnlogin when i get it working and for now is currently just a seperate button to read each textfile.
When each button is pressed (Button 1 -> btnlogin), only the last created textfile is correct.
By the looks of things, your code does read all the text files, but keeps overwriting details.u and details.p with the value retrieved from each file. So, when the loop gets to the last file, those values are what ends up in the details object.
I'm assuming that you want to read all the usernames and passwords into a list and check the details in the TextBoxes against that list, so .. Your code should probably be something like the code below (see the code comments for an explanation of some of the differences.
Before we get to the code, can give you a couple of pointers.
Firstly, always try to use names that are meaningful. Defining your structure as Info is not as meaningful as it could be. For example, you would be better calling it UserInfo and rather than use P and U, you would be better using Password and UserName. It may not matter so much right now, but when you start writing larger more complex programs, and have to come back to them in 6 months time to update them, info.P or details.P aren't as informative as the suggested names.
Secondly, as #ajd mentioned. Don't use magic strings. Create one definition at the beginning of your code which can be used throughout. Again it makes maintenance much easier if you only have to change a string once instead of multiple times, and reduces the chance of mistakes.
Finally, several of the variables you have defined aren't used in your code at all. Again, at this level, it isn't a major issue, but with large programs, you could end up with a bigger memory footprint than you want.
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String = "C:\Users\TheGlove\Desktop\Alex's Program"
Dim files As Integer
Dim filepath As String
Public Structure UserInfo
Dim Name As String
Dim Password As String
End Structure
'Change details to a list of info instead of a single instance
Dim userList As New List(Of UserInfo)
Private Sub Btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
'Iterate through the list of details, checking each instance against the textboxes
For Each tempUserInfo As UserInfo In userList
If txtusername.Text = tempUserInfo.Name And txtpassword.Text = tempUserInfo.Password Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
'This is here, because after your form has opened an closed, the loop
'that checks usernames and passwords will continue. The line below exits the loop safely
Exit For
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
Next
End Sub
Private Sub Btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'clear the list of user details otherwise, if the files are loaded a second time,
'you'll get the same details added again
userList.Clear()
'This line replaces several lines in your code that searches the folder for files
'marching the search pattern
Dim fileList() As FileInfo = New DirectoryInfo(folderpath).GetFiles("loginfile*.txt")
For Each fi As FileInfo In fileList
MsgBox(fi.Name)
Dim userDetails() As String = System.IO.File.ReadAllLines(fi.FullName)
Dim tempInfo As New UserInfo With {.Name = userDetails(0), .Password = userDetails(1)}
'An expanded version of the above line is
'Dim tempInfo As New info
'tempInfo.U = userDetails(0)
'tempInfo.P = userDetails(1)
userList.Add(tempInfo)
Next
files = fileList.Count
End Sub

Trouble with getting value from a website - vb.net

i'm not searching to do something complicated , i just want to retrieve certain titles from a website , the first button was just for a test ... The thing is , even the "lala" text isn't showing up which means it doesn't enter in the loop in the first place ...
Public Class Form1
Function ElementsByClass(document As HtmlDocument, classname As String)
Dim coll As New Collection
For Each elem As HtmlElement In document.All
If elem.GetAttribute("appcenter").ToLower.Split(" ").Contains(classname.ToLower) Then
coll.Add(elem)
End If
Next
Return coll
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim wb As New System.Net.WebClient
wb.Headers.Add("user-agent", "Only a test!")
Dim sourceString As String = wb.DownloadString("http://www.ign.com/games/upcoming")
RichTextBox1.Text = sourceString
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim elementss As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("div")
For Each pElem As HtmlElement In elementss
If pElem.GetAttribute("class") = "item-title" Then
RichTextBox1.Text = "lala"
RichTextBox1.Text = pElem.InnerHtml
End If
Next
End Sub
End Class
Ok, from what I can tell you are after the titles of each new upcoming game.Something like this should do the trick for you.I would recommend that for larger web scraps that you use the HTML Agility PackHowever since you are only wanting a few strings, this solution should be ok for you.
Imports System.Net
Imports System.Text.RegularExpressions
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim websiteURL As String = "http://www.ign.com/games/upcoming"
getTiles(websiteURL) 'where you access this is up to you
End Sub
Private Sub getTiles(website As String)
ListBox1.Items.Clear() 'Clear old results or any errors
Dim tempTitles As New List(Of String)()
Dim webClient As New WebClient()
webClient.Headers.Add("user-agent", "null")
Try 'If the website happens to go offline, at least your application wont crash.
Dim content As String = webClient.DownloadString(website)
Dim pattern As String = "alt=""(?<Data>[^>]*)""/>"
For Each title As Match In (New Regex(pattern).Matches(content)) 'Since you are only pulling a few strings, I thought a regex would be better.
tempTitles.Add(title.Groups("Data").Value)
Next
Dim titles = tempTitles.Distinct().ToArray() 'remove duplicate titles
For Each title As String In titles
ListBox1.Items.Add(title) 'what you do with the values from here is up to you.
Next
If titles.Count() = 0 Then
ListBox1.Items.Add("Nothing Found")
End If
Catch ex As Exception
ListBox1.Items.Add(ex.Message)
Return
End Try
End Sub
I have written some comments to go along with the code to answer any questions you might have.If i have missed something out, feel free to leave a comment below, Happy Coding
I'm sorry but I suck at explaining these things so please analyze the regex in the site I mentioned in the comment earlier.
The site you specified lists the games like this:
<a class="product_spot " href="/browse?nav=16k-3-rime,28zu0" data-date="05/06/2017"><img src="/gs/pages/landing/upcoming-video-games/images/223x120_rime.jpg"><p>RiME<br><br><span>05/06/2017</span></p></a>
<a class="product_spot " href="/browse/games?nav=16k-3-the+surge,28zu0,13ffff2418" data-date="05/16/2017"><img src="/gs/pages/landing/upcoming-video-games/images/223x120_thesurge.jpg"><p>The Surge<br><br><span>05/16/2017</span></p></a>
So this regex will match that.
<a class=.product_spot\s.\shref=.(?:.+?)\sdata-date=.(?:.+?)><img\ssrc=(?:.+?)><p>(.+?)<br><br><span>(?:.+?)<\/span><\/p><\/a>
Imports System.Net
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim wc As New WebClient
Dim input As String = wc.DownloadString("http://www.gamestop.com/collection/upcoming-video-games")
Dim games As New List(Of String)
Dim matchCollection As MatchCollection = Regex.Matches(input, "<a class=.product_spot\s.\shref=.(?:.+?)\sdata-date=.(?:.+?)><img\ssrc=(?:.+?)><p>(.+?)<br><br><span>(.+?)<\/span><\/p><\/a>")
For Each item As Match In matchCollection
games.Add(item.Groups(1).Value.ToString)
Next
For Each item As String In games
Console.WriteLine(item)
Next
Console.ReadLine()
End Sub
End Module
Output:
Dead Island 2
Final Fantasy XV
De-Formers
Injustice 2
...
Killing Floor 2
Tales of Berseria
Nintendo Switch
Mass Effect Andromeda
MLB The Show 17
Has-Been Heroes
Ride 2
...
..
.