Variable has already been used before and assigned a value - vb.net

I' am making a bot for my assignment which uses proxy to browse websites. I have field called "Browse" which lets me browse for the proxy file and reads into an array and shows the total number of proxy from the counter. I' am stuck here in the following. The following are the code that am currently using. Please help
Variable proxyArray has already been used before and assigned a value. A null
reference exception could result at runtime.
Code
Private Sub browserProxy_Click(sender As Object, e As EventArgs) Handles browserProxy.Click
Dim myStream As Stream = Nothing
Dim selectedFile As String
Dim openFileDialog1 As New OpenFileDialog()
Dim proxyArray() As String
Dim totalProxy As Integer
openFileDialog1.InitialDirectory = "C:\"
openFileDialog1.Filter = "Text File (*.txt)|*.txt"
openFileDialog1.FilterIndex = 1
openFileDialog1.RestoreDirectory = False
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
selectedFile = String.Format(openFileDialog1.FileName)
Dim objreader As New System.IO.StreamReader(selectedFile)
i = 0
Do While Not objreader.EndOfStream
proxyArray(i) = objreader.ReadLine
i += 1
Loop
totalProxy = i
objreader.Close()
End If
End Sub
This pops up during runtime.

The compiler is right, you have declared the variable proxyArray but you never initialize it. This is an initialized array with 10 strings that are Nothing
:
Dim proxyArray(9) As String
But since the number of items is unknown you should use a List(Of String) anyway. It is resizable whereas an array has a fixed size.
Dim proxList As New List(Of String)
'...'
proxList.Add(objreader.ReadLine)
If you need an array you can use proxList.ToArray() at the end.

Either use a List(Of String), or ReDim Preserve proxyArray(i + 1) each time.

Related

Error System.InvalidCastException: 'Conversion from string "" to type 'Integer' is not valid.'

I'm trying to open a file that I already add to my TreeView control by clicking it twice, it should appears in a DataGridView control, when a I do it, it shows me the next error:
System.InvalidCastException: 'Conversion from string "Book1.csv" to type 'Integer' is not valid.'
At the Direccion variable, I'm not pretty sure, what it happening. Does any one could orient me? Please.
Public Sub TV_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As
TreeNodeMouseClickEventArgs) Handles TV.NodeMouseDoubleClick
Dim NombreNodo As String = TV.SelectedNode.Text
Dim parseCSV As String
Dim tstSeq() As String
Dim Direccion As String = My.Computer.FileSystem.CurrentDirectory(NombreNodo)
'Dim x As String = Path.GetFullPath(NombreNodo)
'MessageBox.Show(Direccion)
tstSeqDataGrid.Rows.Clear()
Using FileSystem As FileStream = File.Open(Direccion, FileMode.Open, FileAccess.Read)
Dim TestReader As New System.IO.StreamReader(FileSystem)
Do While TestReader.Peek <> -1
parseCSV = TestReader.ReadLine()
tstSeq = parseCSV.Split(",")
tstSeqDataGrid.Rows.Add(tstSeq)
TstSequenceLoaded = True
Loop
TestReader.Close()
FileSystem.Close()
End Using
End Sub
I am assuming that the TreeView is loaded with file names and those files are located in the directory where the code is running. You can see the value of Direccion in the Immediate Window. Using Debug.Print instead of a message box saves you from the embarrassment of forgetting to remove the message box in the production code. The Debug.Print will just be removed.
I returned an array of lines in the file with ReadAllLines. Then loop through the lines as you did.
With Option Strict On (as it should be) you need to add the lower case c following "," so the compiler knows you intend it as a Char not a String.
Public Sub TV_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TV.NodeMouseDoubleClick
Dim Direccion = My.Computer.FileSystem.CurrentDirectory & TV.SelectedNode.Text
Debug.Print(Direccion)
tstSeqDataGrid.Rows.Clear()
Dim lines = File.ReadAllLines(Direccion)
For Each line In lines
Dim tstSeq = line.Split(","c)
tstSeqDataGrid.Rows.Add(tstSeq)
Next
TstSequenceLoaded = True
End Sub

How to rename suffix of all files in listbox?

I have a windows form that contains two list boxes and two tool strip labels (buttons).
On pressing the first button (Open folder), a file browser opens and you can select multiple files, these are then loaded into listbox 1 (ListFilesLoaded), now what I want to do is display converted file names in Listbox 2 (ConvertedNames). for example...
apple_001.jpg > apple_Ambrosia.jpg
apple_002.jpg > apple_Melba.jpg
apple_003.jpg > apple_Granny.jpg
Then press my second button (Rename Files) to save the renamed files in their original directory (removing the old files / names).
So far I have gotten the loading listbox1 (ListFilesLoaded) working fine. I'm just not sure how to go about changing their display names in listbox 2 (ConvertedNames) and saving them out as the new file names.
Imports System.IO
Public Class Form1
Private openFile As OpenFileDialog 'window to open files
Private Sub ToolStripLabel1_Click(sender As Object, e As EventArgs) Handles ToolStripLabel1.Click
Try
openFile = New OpenFileDialog
openFile.Title = "Select files."
openFile.CheckFileExists = True
openFile.Multiselect = True
openFile.RestoreDirectory = False
If openFile.ShowDialog = Windows.Forms.DialogResult.OK Then
openFile.SafeFileNames.Count()
For i As Integer = 0 To openFile.SafeFileNames.Count() - 1
ListFilesLoaded.Items.Add(openFile.SafeFileNames(i))
ConvertedNames.Items.Add(openFile.SafeFileNames(i))
Next
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End Sub
Private Sub ToolStripLabel2_Click(sender As Object, e As EventArgs) Handles ToolStripLabel2.Click
End Sub
So essentially I think I need something like...
If ConvertedNames.Items.string.contains "_001" then
ConvertedNames.Items.string = ConvertedNames.Items.string -4 + _Ambrosia
else if
ConvertedNames.Items.string.contains "_002" then
ConvertedNames.Items.string = ConvertedNames.Items.string -4 + _Melba
else if
ConvertedNames.loaded.name.contains "_003" then
ConvertedNames.Items.string = ConvertedNames.Items.string -4 + _Granny
End If
When it comes to the saving names part, I have no idea at all.
Thanks for taking the time too look.
I changed the names of your controls to match my test program.
I used a List(Of Tuple(Of String, String) to store the path and file name of the original files. https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/tuples and https://learn.microsoft.com/en-us/dotnet/api/system.tuple?view=net-5.0 Without named items, the Tuple elements are referred to as Item1 for the first string and Item2 as the second string. Since our method is small, I felt that naming the elements or using a structure or class was not necessary.
Item1 is the full path (with file name and extension)
Item2 is the file name only with extension
Next, we bind the list to the first list box setting the display and value members. Now we can loop through the list box. Remember that each item in the list box is a Tuple(Of String, String) and we can refer to its elements with Item1 and Item2. We send the file name off to a function that returns the new file name
To actually change the file name on disk we can use the Visual Basic specific FileIO.FileSystem.Rename method. https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.filesystem.renamefile?view=net-5.0 This method takes as parameters, the full path of the original file and the new file name.
Finally, the new name is added to the second list box.
The GetNewName function uses a Select Case and the String.Replace method to do the job.https://learn.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-5.0
Private Sub ToolStripLabel1_Click(sender As Object, e As EventArgs) Handles ToolStripLabel1.Click
Dim openFile = New OpenFileDialog
openFile.Title = "Select files."
openFile.CheckFileExists = True
openFile.Multiselect = True
openFile.RestoreDirectory = False
If openFile.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim lstPathAndFile As New List(Of Tuple(Of String, String))
For Each filePath In openFile.FileNames
lstPathAndFile.Add(Tuple.Create(filePath, Path.GetFileName(filePath)))
Next
ListBox1.DisplayMember = "Item2"
ListBox1.ValueMember = "Item1"
ListBox1.DataSource = lstPathAndFile
For Each t As Tuple(Of String, String) In ListBox1.Items
Dim NewName = GetNewName(t.Item2)
FileIO.FileSystem.RenameFile(t.Item1, NewName)
ListBox2.Items.Add(NewName)
Next
End If
End Sub
Private Function GetNewName(OriginalFileName As String) As String
Dim NewFileName As String = ""
Select Case True
Case OriginalFileName.Contains("001")
NewFileName = OriginalFileName.Replace("001", "Ambrosia")
Case OriginalFileName.Contains("002")
NewFileName = OriginalFileName.Replace("002", "Melba")
Case OriginalFileName.Contains("003")
NewFileName = OriginalFileName.Replace("003", "Granny")
End Select
Return NewFileName
End Function

VB.Net Search for text and replace with file content

This is a follow on question to a post I made. Append one file into another file
I need to search the master document for entities "&CH1.sgm" to "&CH33.sgm",
mark where they are in the master document and replace the entity call with the matching file "Chapter1.sgm" found in "fnFiles". I can change the file names and entities to anything if that will help.
My code copies the text of a file and appends it to the bottom of the master_document.sgm. But now I need it to be more intelligent. Search the Master document for entity markers, then replace that entity marker with that file contents match. The file number and entity number match up. e.g.(&CH1; and Bld1_Ch1.sgm)
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
Dim searchDir As String = txtSGMFile.Text 'Input field from form
Dim masterFile = "Bld1_Master_Document.sgm"
Dim existingFileMaster = Path.Combine(searchDir, masterFile)
'Read all lines of the Master Document
Dim strMasterDoc = File.ReadAllText(existingFileMaster) '// add each line as String Array.
'?search strMasterDoc for entities &Ch1.sgm
'?replace entity name "&Ch1.sgm" with content of file "Bld1_Ch1.sgm" this content if found below
'? do I use a book mark? Replace function?
'Get all the sgm files in the directory specified
Dim fndFiles = Directory.GetFiles(searchDir, "*.sgm")
'Set up the regular expression you will make as the condition for the file
Dim rx = New Regex(".*_Ch\d\.sgm")
Dim ch1 = New Regex(".*_Ch[1]\.sgm")
'Use path.combine for concatenatin directory together
'Loop through each file found by the REGEX
For Each fileNo In fndFiles
If rx.IsMatch(fileNo) Then
If ch1.IsMatch(fileNo) Then
Dim result = Path.GetFileName(fileNo)
'Use path.combine for concatenatin directory together
Dim fileToCopy = Path.Combine(searchDir, result)
'This is the file we want to copy into MasterBuild but at specific location.
'match &ch1.sgm inside strMasterDoc
Dim fileContent = File.ReadAllText(fileToCopy)
'Search master file for entity match then append all content of fileContent
File.AppendAllText(existingFileMaster, fileContent)
MessageBox.Show("File Copied")
End If
End If
Next
Close()
End Sub
If I understand correctly (big if), you want to replace the the text of the abbreviated chapter name in the master file with the contents of the file it refers to at the spot where the abbreviation is found.
I made a class to handle the details.
Private Sub btnImport_Click(sender As Object, e As EventArgs) Handles btnImport.Click
'Add a FolderBrowseDialog to your form designer
FolderBrowserDialog1.ShowDialog()
Dim searchDir As String = FolderBrowserDialog1.SelectedPath
Dim existingFileMaster = Path.Combine(searchDir, "Bld1_Master_Document.sgm")
Dim lstFileChanges = CreateList(searchDir)
'The following method does NOT return an array of lines
Dim strMasterDoc = File.ReadAllText(existingFileMaster)
For Each fc In lstFileChanges
strMasterDoc = strMasterDoc.Replace(fc.OldString, fc.NewString)
Next
File.WriteAllText(existingFileMaster, strMasterDoc)
End Sub
Private Function CreateList(selectedPath As String) As List(Of FileChanges)
Dim lstFC As New List(Of FileChanges)
For i = 1 To lstFC.Count
Dim fc As New FileChanges
fc.OldString = $"&CH{i}.sgm"
fc.FileName = $"Chapter{i}.sgm"
fc.NewString = File.ReadAllText(Path.Combine(selectedPath, fc.FileName))
lstFC.Add(fc)
Next
Return lstFC
End Function
Public Class FileChanges
Public Property OldString As String '&CH1.sgm
Public Property FileName As String 'Chapter1.sgm
Public Property NewString As String 'Contents of Chapter1.sgm, the string to insert
End Class
Testing .Replace
Dim s As String = "The quick brown fox jumped over the lazy dogs."
s = s.Replace("fox", "foxes")
MessageBox.Show(s)

Reading from text file to ListBox

I am having a bit of trouble reading data from a text file. This almost works, however data in separate lines in the text file is combined to one long line in the ListBox. How else to do it?
Private Sub frmOpretrskAar_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim FILE_NAME As String = "c:\users\claus\onedrive\SLERP\fmr.txt"
Dim objReader As New System.IO.StreamReader(FILE_NAME)
LBmuligeFirmaer.Items.Add(objReader.ReadToEnd)
objReader.Close()
End Sub
Use the ListBox.Items.AddRange method to add an array, in this case it would be an array that represents the lines of the text file. You can get the lines by using IO.File.ReadAllLines method. Here is a quick example:
LBmuligeFirmaer.Items.AddRange(IO.File.ReadAllLines("c:\users\claus\onedrive\SLERP\fmr.txt"))
Its very simple -
List<string> _list = File.ReadAllLines(fileName).ToList();
See the below image -
You can use array.
Try this code:
Dim FILE_NAME As String = "c:\users\claus\onedrive\SLERP\fmr.txt"
Dim AllLines() As String = System.IO.File.ReadAllLines(FILE_NAME)
For i As Integer = 0 To AllLines.Count - 1
LBmuligeFirmaer.Items.Add(AllLines(i))
Next
I can't test this in my IDE currently so tell me if something doesn't work right but I have used something similar:
Imports System.IO
Imports System.Windows.Forms
'assigning a string value to the file's location
Dim FILE_NAME As String = "c:\users\claus\onedrive\SLERP\fmr.txt"
'clearing the listbox
LBmuligeFirmaer.items.clear
'declaring a filereader
Dim fileReader As System.IO.StreamReader
fileReader =
'obtaining file location from string to the stringreader
My.Computer.FileSystem.OpenTextFileReader(FILE_NAME)
Dim stringReader As String
'reading first line
stringReader = fileReader.ReadLine()
'adding line to the listbox
LBmuligeFirmaer.items.add(stringreader)
'reading second line
stringReader = fileReader.ReadLine()
'adding line to listbox
LBmuligeFirmaer.items.add(stringreader)
'and so on...

Referencing an Unbound DataGridView Without Specifically Naming It?

I am using 3 unbound DataGridView controls to display certain information. To load the information into those DGVs, I am pulling the information from an encrypted file, decrypting it, parsing the information, then trying to fill the DGVs with that information. The loading from the file is called by the menu item click. Here is what I have so far:
Private Sub miCLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles miCLoad.Click
Dim FilePath As String = "C:\FList\CList.clt"
Dim LoadFile As New SaveandLoad.SaveAndLoad
Dim FileRead As New Simple3Des("MyPassword")
Dim FileString As String = FileRead.ReadFile(FilePath)
With LoadFile
.WhichList = dgCourses
.FilePath = FilePath
.DecryptedString = FileRead.DecryptData(FileString)
.dgList = dgCourses
End With
Call LoadFile.LoadFile()
End Sub
Public Class SaveandLoad
Public Property WhichList As New DataGridView
Public Property FilePath As String
Public Property DecryptedString As String
Public Property EncryptedString As String
Public Property dgList As Control
Public Sub LoadFile()
Dim dgRow As DataGridViewRow
Dim dgCell As DataGridViewTextBoxCell
Dim Lines() As String = DecryptedString.Split(vbLf)
Dim LinesList As List(Of String) = Lines.ToList
LinesList.RemoveAt(Lines.Length - 1)
For Each Line As String In LinesList
Dim Fields() As String = Line.Split(",")
dgRow = New DataGridViewRow
For x = 0 To (WhichList.Columns.Count - 1) Step 1
dgCell = New DataGridViewTextBoxCell
dgCell.Value = Fields(x).ToString
dgRow.Cells.Add(dgCell)
Next
WhichList.Rows.Add(dgRow)
Next
Select Case WhichList.Name
Case "dgCourses"
frmFacultyList.dgCourses = WhichList
frmFacultyList.dgCourses.Refresh()
WhichList.Dispose()
Case "dgFList"
frmFacultyList.dgFList = WhichList
frmFacultyList.dgFList.Refresh()
WhichList.Dispose()
Case "dgSList"
frmFacultyList.dgSList = WhichList
frmFacultyList.dgSList.Refresh()
WhichList.Dispose()
End Select
MsgBox("List Successfully Loaded", vbOKOnly, "Load")
End Sub
I want to be able to reference (or fill) a DGV without using 'select case' or 'if-then' statements. This will be too inefficient once I start adding the many other DGVs, that will be added in the future. Therefore, the title is the main question. I am using VS Express 2010.
I don't know VB too much, however, I'll post my solution in C# (may be helpfull in some way....)
DataGridView myDGV;
foreach (var item in this.Controls)
{
if (item.GetType() == typeof(DataGridView))
{
if (((DataGridView)item).Name == WhichList.Name)
{
//Cannot assing to 'item' here, because it is a 'foreach iteration variable'
//However you can save the variable for later use.
myDGV = (DataGridView)item;
}
}
}
myDGV = WhichList;
// different approach
DataGridView myDGV = (DataGridView)this.Controls.Find(WhichList.Name, false).First();
myDGV = WhichList;
Here is what worked for me in VB.NET:
Dim FormControls As New frmFacultyList.ControlCollection(frmFacultyList)
For Each DGV As DataGridView In FormControls
If WhichList.Name = DGV.Name Then
DGV = WhichList
DGV.Refresh()
End If
Next
Make an instance of the control collection then search specifically for DGVs using For Each. Simple and efficient.