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
Related
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)
I've written a script that will take a table out of a program, and export it to the local drive in a comma delimited text file. What I need is a script to read the text file. The user will input a string in a text box from Public Class Form 1, then the string gets passed to another Sub in Public Class SpaceMenuClass. The handoff looks ok, but I can't figure out how to parse the text file (match column 1 with the string, and store column 2 from that line to pass back to the SpacemenuClass). I know this may seem ambiguous, but hopefully makes some sense. Thanks to anyone in advance.
From Form1 Class
Private Sub BtnPlano_Click_(sender As Object, e As EventArgs) Handles BtnPlano.Click
If TxtBoxPlano.Text <> "" Then
SpaceCommands.SearchPlano(TxtBoxPlano.Text)
Else MessageBox.Show("Please Enter a Valid Planogram Name!")
End If
TxtBoxPlano.Clear()
End Sub
From SpaceMenuClass:
Public Sub SearchPlano(PlanoName As String)
For Each Plano As Space.Planogram In SpacePlanning.ForPlanograms()
SpacePlanning.SetActivePlanogram(Plano.Number - 1)
'Go open the Searchplano table on the shared drive
SpacePlanning.OpenTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
'Export the table to a Tab Delimited Text file
SpacePlanning.ExportTableData(ExportFileName:="C:\Temp\JDA\SearchPlano.txt", ExportMethod:=ExportMethod.CommaSeparated, UseCurrency:=False, UseQuotedStrings:=False, UseThousandsSeparator:=False)
'Close the Table
SpacePlanning.CloseTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
' Open the text file and parse it
Dim str As System.IO.StreamReader = New System.IO.StreamReader(New System.IO.FileStream("C:\Temp\JDA\SearchPlano.txt", System.IO.FileMode.Open))
Dim strline, arr(), Name, Nbr As String
Try
NextLine:
strline = str.ReadLine
arr = strline.Split(",")
Name = arr(0)
Nbr = arr(1)
If Name = PlanoName Then
SpacePlanning.SetActivePlanogram(Plano.Number = Nbr)
GoTo Finish
Else
GoTo NextLine
End If
Catch
End Try
Next
Finish:
My.Computer.FileSystem.DeleteFile("C:\Temp\JDA\SearchPlano.Txt")
End Sub
You open the file for reading, then try to delete it before closing it. This would raise an exception. To avoid this, wrap the StreamReader in a Using block. The End Using automatically disposes of the object (closes the file for you).
Public Sub SearchPlano(planoName As String)
For Each plano As Space.Planogram In SpacePlanning.ForPlanograms()
SpacePlanning.SetActivePlanogram(plano.Number - 1)
'Go open the Searchplano table on the shared drive
SpacePlanning.OpenTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
'Export the table to a Tab Delimited Text file
SpacePlanning.ExportTableData(
ExportFileName:="C:\Temp\JDA\SearchPlano.txt", ExportMethod:=ExportMethod.CommaSeparated,
UseCurrency:=False, UseQuotedStrings:=False, UseThousandsSeparator:=False)
'Close the Table
SpacePlanning.CloseTableChartView(AnalysisFileName:="\\SERVER1\JDA\Tables\SearchPlano.pst")
' Open the text file and parse it
Using str = New System.IO.StreamReader("C:\Temp\JDA\SearchPlano.txt")
Dim arr(), name, nbr As String
Do
If str.EndOfStream Then
' didn't find item!!!
End If
arr = str.ReadLine.Split(",")
name = arr(0)
nbr = arr(1)
Loop Until name = planoName
SpacePlanning.SetActivePlanogram(plano.Number = nbr)
End Using
Next
My.Computer.FileSystem.DeleteFile("C:\Temp\JDA\SearchPlano.Txt")
End Sub
I also cleaned up your loop and added a check for EndOfStream, in case you couldn't find a match (this would have thrown an exception too).
Also, changed the StreamReader to just open the file. You had a nested FileStream object in there, which would have required another Using block, and is unnecessary.
I have the following visual basic code, which is part of a custom class. I want a simple and effective way(use little computer resources) to assign the "value1" value(100) to "_field1","value2" value(8) to "_field2" etc. Any nice ideas? thanks
Private Sub readcrnFile()
'read files and assing values to the properties
Dim sr As New IO.StreamReader(_fileName)
_field1 = sr.ReadToEnd()
_field2 = sr.ReadToEnd()
_field3 = sr.ReadToEnd()
sr.Close()
End Sub
where _fileName is a full path to a text file which looks like this:
value1: 100
value2: 8
value3: 80
Private Sub readcrnFile()
Dim lines = File.ReadLines(_fileName)
For Each line In lines
Dim val = line.Split(":")(1).Trim
'do something with val?
Next
End Sub
Returning a dictionary is trivial:
Private Sub readcrnFile()
Dim dict = File.ReadLines(_fileName).Select(Function(line) line.Split(":")).ToDictionary(Function(parts) parts(0).Trim, Function(parts) parts(1).Trim)
Debug.WriteLine(dict("value1")) 'will print 100
End Sub
Change your _field1, _field2 and _field3 variables to a List(Of String) (i.e. named field) and access to each field using its index (field(0), field(1), field(2)).
Dim field As New List(Of String)
Private Sub readcrnFile()
For Each line In File.ReadAllLines(_filename)
For i = 1 To 3
If line.Contains("value" & i) Then
field.Add(line.Substring(line.IndexOf(":") + 2))
End If
Next
Next
End Sub
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.
I'm starting with Visual Basic and use Visual Studio 2012 and trying to make a tool for renaming a group of files.
How it shoul be:
1- With the "Select Files" button, I can choose the files and they are listed in the ListBox
2- "Old value" is a textbox and is the value to be changed in the filename. For example: fff
3- "New value" is a textbox and is the new value that should replace the old. For example: zzz
4- Rename is a button to start the process.
To rename only one file it's not a problem.
But how to rename all the files from the ListBox which are containing the Oldvalue ?
Can you please help me!
Thanks
I suggest looping over the selected files in the listbox, checking to see which ones contain the OldValue string.
You could use string.contains http://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Sounds like you have the replace function sorted since you say it's no problem to do just one file.
Thank you 70Mike.
But I have some problem with the loop.
If it works only for 1 file and not for all.
Here is my code:
Public Class frmRename
Private Sub cmdSelectFile_Click(sender As Object, e As EventArgs) Handles cmdSelectFile.Click
If (OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK) Then
For Each S As String In OpenFileDialog1.FileNames
lstSelectFiles.Items.Add(S)
Next
Else : Exit Sub
End If
End Sub
Private Sub cmdRename_Click(sender As Object, e As EventArgs) Handles cmdRename.Click
Try
For LC As Integer = 0 To lstSelectFiles.Items.Count - 1
Dim s1 As String = lstSelectFiles.Items(LC)
Dim s2 As String = txtbOld.Text
Dim b As String
b = s1.Contains(s2)
Console.WriteLine("Is the string, s2, in the string, s1?: {0}", b)
Do While b = True
Dim oldFile As String = lstSelectFiles.Items(LC)
Dim newFile As String = Replace(lstSelectFiles.Items(LC), txtbOld.Text, txtbNew.Text)
If File.Exists(oldFile) And Not File.Exists(newFile) Then
File.Move(oldFile, newFile)
Kill(oldFile)
End If
Loop
Next
Catch ex As Exception
MsgBox("No file renamed")
End Try
End Sub
End Class