A vb.net set of code does not resort the original text file, it only displays the highest alphabetical name 9 x - vb.net

The code was taken from a YouTube video that I watched at: https://www.youtube.com/watch?v=zyN6pZmd2Pk.
There are no errors in the code, just a list of the name Aiden, which was in the original text file 9 places down.
Any ideas would be greatly appreciated.
Imports System.IO
Module Module1
Sub Main()
Dim myArray As New List(Of String)
Using myReader As StreamReader = New StreamReader(".\myFile.txt")
'telling VB that we're using a StreamREader, read a line at a time
Dim myLine As String
myLine = myReader.ReadLine 'assigns the line to String Variable myLine
Do While (Not myLine Is Nothing)
myArray.Add(myLine) 'adding it to the list of words in the array
Console.WriteLine(myLine)
myLine = myReader.ReadLine
Loop
End Using
SortMyArray(myArray)
'Console.ReadLine()
End Sub
Sub SortMyArray(ByVal mySort As List(Of String))
Dim Tmp As String, writePath As String = ".\sorted.txt"
Dim max As Integer = mySort.Count - 1
Dim myWriter As StreamWriter = New StreamWriter(writePath)
For Loop1 = 0 To max - 1
For Loop2 = Loop1 + 1 To max
If mySort(Loop1) > mySort(Loop2) Then
Tmp = mySort(Loop2)
mySort(Loop1) = mySort(Loop1)
mySort(Loop1) = Tmp
End If
Next
myWriter.WriteLine(mySort.Item(Loop1).ToString())
Next
myWriter.Dispose()
End Sub
End Module

Related

Find Value as Integer in a Textbox

I would need a little help. If in the Textbox - TxtStringNum1.Text - we have the Digit 3. and TxtIntDraws.Lines (1) - contains the following set: 13,20,21,23,47,49,50,51,63,64,66,70
It shows me that there is Exists a Digit of 3, but it is actually the Digits of 13. It fails to look for it as a whole.
Private Sub ScanareLinia1()
Dim textsrtring As String = TxtStringNum1.Text
Dim words As String() = textsrtring.Split(New Char() {" "c})
' Split string based on space
Dim found As Boolean = False
' Use For Each loop over words
Dim word As Integer
For Each word In words
For i As Integer = 0 To TxtIntDraws.Lines.Count - 1
If TxtIntDraws.Lines(1).Contains(word) Then
TxtResultStr1.Text = word
End If
Next
Next
ScanareLinia2()
End Sub
I have a good comparison code, but I do not know how to use it for the code above.
Private Sub CompareNumbers()
'Pentru funcția de Check-In (For Match Exactly Value Number in List)
'First Textbox that is to be used for compare
Dim textBox1Numbers As List(Of Integer) = GetNumbersFromTextLine(TxtStringNum1.Text)
'Second Textbox that is to be used for compare
Dim textBox2Numbers As List(Of Integer) = GetNumbersFromTextLine(TxtbValBeforeCompar.Text)
'Union List of Common Numbers (this uses a lambda expression, it can be done using two For Each loops instead.)
Dim commonNumbers As List(Of Integer) = textBox1Numbers.Where(Function(num) textBox2Numbers.Contains(num)).ToList()
'This is purely for testing to see if it worked you can.
Dim sb As StringBuilder = New StringBuilder()
For Each foundNum As Integer In commonNumbers
sb.Append(foundNum.ToString()).Append(TextBox25.Text)
TxtbValAfterCompar.Text = (sb.ToString())
Next
End Sub
Private Function GetNumbersFromTextLine(ByVal sTextLine As String) As List(Of Integer)
'Pentru funcția de Check-In (For Match Exactly Value Number in List)
Dim numberList As List(Of Integer) = New List(Of Integer)()
Dim sSplitNumbers As String() = sTextLine.Split(TextBox8.Text)
For Each sNumber As String In sSplitNumbers
If IsNumeric(sNumber) Then
Dim iNum As Integer = CInt(sNumber)
TxtbValAfterCompar.Text = iNum
If Not numberList.Contains(iNum) Then
TxtbValAfterCompar.Text = ("")
numberList.Add(iNum)
End If
Else
End If
Next
Return numberList
End Function
You can use the following condition using String.Split and Array.IndexOf:
If Array.IndexOf(TxtIntDraws.Lines(1).Split(","c), CStr(word)) > -1 Then
TxtResultStr1.Text = word
End If
So the following Array.IndexOf(CStr("13,14,15,16,17").Split(","c), "13") > -1 is True and Array.IndexOf(CStr("13,14,15,16,17").Split(","c), "3") > -1 is False.

exclude header from csv in vb.net

I got a .csv and I want to load it into a datagridview. I have a button called button1 and I got a datagridview called datagridview1. I click the button and it appears... including the header, which I don't want.
Please:
How do I exclude the header from the .csv ?
code:
Imports System.IO
Imports System.Text
Public Class CSV_Reader
Private Sub CSV_Reader_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filename As String = "C:\Users\Gaius\Desktop\meepmoop.csv"
Dim thereader As New StreamReader(filename, Encoding.Default)
Dim colsexpected As Integer = 7
Dim sline As String = ""
DataGridView1.Rows.Clear()
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";")
DataGridView1.Rows.Add("")
If words.Length = colsexpected Then
For ix As Integer = 0 To 6
DataGridView1.Rows(DataGridView1.Rows.Count - 2).Cells(ix).Value = words(ix)
Next
Else
DataGridView1.Rows(DataGridView1.Rows.Count - 2).Cells(0).Value = "ERROR"
End If
Loop
thereader.Close()
End Sub
End Class
meepmoop.csv:
alpha;bravo;charlie;delta;echo;foxtrot;golf
1;meep;moop;meep;moop;meep;moop
2;moop;meep;moop;meep;moop;meep
3;meep;moop;meep;moop;meep;moop
4;moop;meep;moop;meep;moop;meep
5;meep;moop;meep;moop;meep;moop
6;moop;meep;moop;meep;moop;meep
7;meep;moop;meep;moop;meep;moop
8;moop;meep;moop;meep;moop;meep
9;meep;moop;meep;moop;meep;moop
10;moop;meep;moop;meep;moop;meep
edit:
[...]
Dim sline As String = ""
DataGridView1.Rows.Clear()
Dim line As String = thereader.ReadLine()
If line Is Nothing Then Return
Do
sline = thereader.ReadLine
[...]
The above addition to the code works but I have no idea why. Nor do I understand why I have to -2 rather than -1. I can't rely on guesswork, I'm expected to one day do this professionally. But I just can't wrap my head around it. Explanation welcome.
edit:
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";")
If words.Count = 7 Then
DataGridView1.Rows.Add(words(0), words(1), words(2), words(3), words(4), words(5), words(6))
Else
MsgBox("ERROR - There are " & words.Count & " columns in this row and there must be 7!")
End If
Loop
I've shortened the Loop on the advice of a coworker, taking his word on it being 'better this way'.
Another method, using Enumerable.Select() + .Skip()
As noted in Ondřej answer, there's a specific tool for these operations: TextFieldParser
But, if there are no special requirements and the string parsing is straightforward enough, it can be done with the standard tools, as shown in Tim Schmelter answer.
This method enumerates the string arrays returned by the Split() method, and groups them in a list that can be then used in different ways. As a raw text source (as in this case) or as a DataSource.
Dim FileName As String = "C:\Users\Gaius\Desktop\meepmoop.csv"
Dim Delimiter As Char = ";"c
Dim ColsExpected As Integer = 7
If Not File.Exists(FileName) Then Return
Dim Lines As String() = File.ReadAllLines(FileName, Encoding.Default)
Dim StringColumns As List(Of String()) =
Lines.Select(Function(line) Split(line, Delimiter, ColsExpected, CompareMethod.Text)).
Skip(1).ToList()
DataGridView1.Rows.Clear()
'If the DataGridView is empty, add a `[ColsExpected]` number of `Columns`:
DataGridView1.Columns.AddRange(Enumerable.Range(0, ColsExpected).
Select(Function(col) New DataGridViewTextBoxColumn()).ToArray())
StringColumns.Select(Function(row) DataGridView1.Rows.Add(row)).ToList()
If you instead want to include and use the Header because your DataGridView is empty (it has no predefined Columns), you could use the Header line in the .csv file to create the control's Columns:
'Include the header (no .Skip())
Dim StringColumns As List(Of String()) =
Lines.Select(Function(line) Split(line, Delimiter, ColsExpected, CompareMethod.Text)).ToList()
'Insert the columns with the .csv header columns description
DataGridView1.Columns.AddRange(Enumerable.Range(0, ColsExpected).
Select(Function(col, idx) New DataGridViewTextBoxColumn() With {
.HeaderText = StringColumns(0)(idx)
}).ToArray())
'Remove the header line...
StringColumns.RemoveAt(0)
StringColumns.Select(Function(row) DataGridView1.Rows.Add(row)).ToList()
You can skip the header by calling ReadLine twice. Also use the Using-statement:
Using thereader As New StreamReader(filename, Encoding.Default)
Dim colsexpected As Integer = 7
Dim sline As String = ""
Dim line As String = thereader.ReadLine() ' header
if line is Nothing Then Return
Do
sline = thereader.ReadLine()
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";"c)
' ... '
Loop
End Using
You should use VB.NET class that is designed and tested for this purpose. It is Microsoft.VisualBasic.FileIO.TextFieldParser and you can skip header by calling ReadFields() once before you start parsing in loop.

Output random lines from a large document to a TextBox

I'm trying to make a program that reads a large document, for example the bible, and outputs multiple random lines. I can get it to output one random line, but no others.
The end goal is to have a user input to determine how many lines are displayed.
Here's my code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Dim howmanylines As Integer
' howmanylines = InputBox("how many lines for paragrpah", "xd",,,)
'Dim count As Integer = 0
' Do Until count = howmanylines
Dim sr As New System.IO.StreamReader("C:\Users\Dumpster Fire\Desktop\bible.doc")
Dim sr2 As New System.IO.StreamReader("C:\Users\Dumpster Fire\Desktop\bible.doc")
Dim sr3 As New System.IO.StreamReader("C:\Users\Dumpster Fire\Desktop\bible.doc")
Dim xd As Integer = 0
Dim curline As Integer = 0
Dim random As Integer = 0
Do Until sr.EndOfStream = True
sr.ReadLine()
xd = xd + 1
Loop
sr.Dispose()
sr.Close()
Randomize()
random = Rnd() * xd
Do Until curline = random
TextBox1.Text = sr2.ReadLine
' curline = curline + 1
Randomize()
random = Rnd() * xd
TextBox1.Text = sr3.ReadLine
curline = curline + 1
' count = count + 1
Loop
End Sub
End Class
A couple of things I would suggest to improve your code.
Implement Using. This will ensure that the StreamReader is disposed of when finished. It saves you having to remember and it's less lines of code so improves readability.
I would consider using Integer.TryParse:
Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the conversion succeeded.
You only need to use one StreamReader and add all the lines to a List(Of String).
Use a StringBuilder to add your lines too and then output this to the TextBox at the end. Note that you will have to import System.Text to reference the StringBuilder class.
Use Random.Next:
Returns a random integer that is within a specified range.
The end result would be something like this:
txtLines.Text = ""
Dim howManyLines As Integer = 0
If Integer.TryParse(txtUserInput.Text, howManyLines) Then
Dim lines As New List(Of String)
Using sr As New StreamReader("C:\test\test.txt")
Do Until sr.EndOfStream()
lines.Add(sr.ReadLine)
Loop
End Using
Dim sb As New StringBuilder
Dim rnd As New Random()
For i = 0 To howManyLines - 1
Dim nextLine As Integer = rnd.Next(lines.Count - 1)
sb.AppendLine(lines(nextLine))
Next
txtLines.Text = sb.ToString()
End If
You would ideally place this code on a button click event.

VB "Index was out of range, must be non-negative and less than the size of the collection." When trying to generate a random number more than once

So I'm trying to generate a random number on button click. Now this number needs to be between two numbers that are inside my text file with various other things all separated by the "|" symbol. The number is then put into the text of a textbox which is being created after i run the form. I can get everything to work perfectly once, but as soon as i try to generate a different random number it gives me the error: "Index was out of range, must be non-negative and less than the size of the collection." Here is the main code as well as the block that generates the textbox after loading the form. As well as the contents of my text file.
Private Sub generate()
Dim newrandom As New Random
Try
Using sr As New StreamReader(itemfile) 'Create a stream reader object for the file
'While we have lines to read in
Do Until sr.EndOfStream
Dim line As String
line = sr.ReadLine() 'Read a line out one at a time
Dim tmp()
tmp = Split(line, "|")
rows(lineNum).buybutton.Text = tmp(1)
rows(lineNum).buyprice.Text = newrandom.Next(tmp(2), tmp(3)) 'Generate the random number between two values
rows(lineNum).amount.Text = tmp(4)
rows(lineNum).sellprice.Text = tmp(5)
rows(lineNum).sellbutton.Text = tmp(1)
lineNum += 1
If sr.EndOfStream = True Then
sr.Close()
End If
Loop
End Using
Catch x As Exception ' Report any errors in reading the line of code
Dim errMsg As String = "Problems: " & x.Message
MsgBox(errMsg)
End Try
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
rows = New List(Of duplicate)
For dupnum = 0 To 11
'There are about 5 more of these above this one but they all have set values, this is the only troublesome one
Dim buyprice As System.Windows.Forms.TextBox
buyprice = New System.Windows.Forms.TextBox
buyprice.Width = textbox1.Width
buyprice.Height = textbox1.Height
buyprice.Left = textbox1.Left
buyprice.Top = textbox1.Top + 30 * dupnum
buyprice.Name = "buypricetxt" + Str(dupnum)
Me.Controls.Add(buyprice)
pair = New itemrow
pair.sellbutton = sellbutton
pair.amount = amounttxt
pair.sellprice = sellpricetxt
pair.buybutton = buybutton
pair.buyprice = buypricetxt
rows.Add(pair)
next
end sub
'textfile contents
0|Iron Sword|10|30|0|0
1|Steel Sword|20|40|0|0
2|Iron Shield|15|35|0|0
3|Steel Shield|30|50|0|0
4|Bread|5|10|0|0
5|Cloak|15|30|0|0
6|Tent|40|80|0|0
7|Leather Armour|50|70|0|0
8|Horse|100|200|0|0
9|Saddle|50|75|0|0
10|Opium|200|500|0|0
11|House|1000|5000|0|0
Not sure what else to add, if you know whats wrong please help :/ thanks
Add the following two lines to the start of generate():
Private Sub generate()
Dim lineNum
lineNum = 0
This ensures that you don't point to a value of lineNum outside of the collection.
I usually consider it a good idea to add
Option Explicit
to my code - it forces me to declare my variables, and then I think about their initialization more carefully. It helps me consider their scope, too.
Try this little modification.
I took your original Sub and changed a little bit take a try and let us know if it solve the issue
Private Sub generate()
Dim line As String
Dim lineNum As Integer = 0
Dim rn As New Random(Now.Millisecond)
Try
Using sr As New StreamReader(_path) 'Create a stream reader object for the file
'While we have lines to read in
While sr.Peek > 0
line = sr.ReadLine() 'Read a line out one at a time
If Not String.IsNullOrEmpty(line) And Not String.IsNullOrWhiteSpace(line) Then
Dim tmp()
tmp = Split(line, "|")
rows(lineNum).buybutton.Text = tmp(1)
rows(lineNum).buyprice.Text = rn.Next(CInt(tmp(2)), CInt(tmp(3))) 'Generate the random number between two values
rows(lineNum).amount.Text = tmp(4)
rows(lineNum).sellprice.Text = tmp(5)
rows(lineNum).sellbutton.Text = tmp(1)
lineNum += 1
End If
End While
End Using
Catch x As Exception ' Report any errors in reading the line of code
Dim errMsg As String = "Problems: " & x.Message
MsgBox(errMsg)
End Try
End Sub

vb.net select random folder name

Dose anybody know how I can select an existing random directory name (C:\ drive) using vb.net and store its location in a variable.
I had to googel this one but seem to only be able to find example in relation to files, not folders
Try this out, hope this will suits your requirement,
'----------------- Global Variables
Dim xCnter = 0
Dim xRndNo = 0
Dim xSubdirectory As String
Private Sub Basement()
Dim xGenerator As System.Random = New System.Random()
xRndNo = xGenerator.Next(1, 100)
AssignRndDirectory("C:\")
msgbox(subdirectory)
End Sub
Private Sub AssignRndDirectory(xPath as string)
For Each subdirectory In Directory.GetDirectories(xPath)
if xCnter = xRndNo then Exit sub
xCnter += 1
call AssignRndDirectory(subdirectory)
Next
End Sub
[Note: This code is not tested with IDE, Tell me if anything cause errors.]
EDIT: TESTED WITH IDE
Dim xCnter = 0
Dim xRndNo = 0
Dim xSubdirectory As String
Private Sub Basement()
Dim xGenerator As System.Random = New System.Random()
xRndNo = xGenerator.Next(1, 100)
AssignRndDirectory("C:\")
MsgBox(xSubdirectory)
xCnter = 0
End Sub
Private Sub AssignRndDirectory(ByVal xPath As String)
Try
For Each Subdirectory In Directory.GetDirectories(xPath)
If xCnter = xRndNo Then Exit Sub
xSubdirectory = Subdirectory
xCnter += 1
Call AssignRndDirectory(Subdirectory)
Next
Catch ex As Exception
Exit Sub
End Try
End Sub
Just make a list of directories, and select a random item from it.
Dim rnd As New Random()
Dim path As String = "C:\"
Dim dir = New DirectoryInfo(path)
Dim subDirs = dir.GetDirectories()
Dim randomDir = subdirs(rnd.[Next](subDirs.Length))
Or, if you prefer Linq, the last line can be:
Dim randomDirectory = subdirs.Skip(rnd.[Next](subdirs.Length)).First()