Save changes made to file names in folder. All 762 of them - vb.net

I downloaded a pack of roms for a SNES emulator and when I went to transfer them over I received an error on the illegal file names. So I started coding a simple app that will remove the problem char from the roms title. I got that part figured out however I cannot figure out how to save the edited file names. Keep in mind there are 762 roms in the folder so manually doing this is not an option. Thanks in advance for any guidance.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.Items.AddRange(IO.Directory.GetFiles("c:\ROMS"))
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Index As Integer = ListBox1.SelectedIndex
Dim Results = (From T In ListBox1.Items
Select System.Text.RegularExpressions.Regex.Replace(CStr(T),
"[""]", String.Empty).Replace("[!]", "")
).ToArray
ListBox1.Items.Clear()
ListBox1.Items.AddRange(Results)
If Index <> -1 Then
ListBox1.SelectedIndex = Index
End If
End Sub
End Class
I am using button1 to open the folder into a listbox.
Button 2 removes the unwanted [!] from the title
Button 3 would be where the save feature is.
####### EDIT #####
I figured out what the real problem was for my particular case.
I was transferring the folder of roms over to my Xbox and apparently the is a character limit not so much a restriction on chars used. Dont know the actual allowed amount of chars to be used but for anyone who may be trying to do what I did just use my code to remove unnecessary chars in the title.

Add another Listbox to your form called Listbox2 then use this code below. Also notice in Button2 the use of GetDirectoryName and GetFileName so that you don't replace any chars in the folder name...only the filename
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.Items.AddRange(IO.Directory.GetFiles("c:\ROMS"))
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Index As Integer = ListBox1.SelectedIndex
Dim Results = (From T In ListBox1.Items
Select IO.Path.GetDirectoryName(CStr(T)) & "\" & System.Text.RegularExpressions.Regex.Replace(IO.Path.GetFileName(CStr(T)),
"[""]", String.Empty).Replace("[!]", "")
).ToArray
ListBox2.Items.Clear()
ListBox2.Items.AddRange(Results)
If Index <> -1 Then
ListBox1.SelectedIndex = Index
ListBox2.SelectedIndex = Index
End If
End Sub
Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
For x As Integer = 0 To Me.ListBox1.Items.Count - 1
IO.File.Move(Me.ListBox1.Items(x), Me.ListBox2.Items(x))
Next
MsgBox("Done!")
End Sub
End Class

Related

Create a right triangle with loop in Visual Basic

I tried to solve the Visual Basic assignment in dart and I was able to using this :
I don't know if that's the best way to do it though. In Visual Studio I don't know what commands or methods that can help me do this and this is the result there.
Public Class Form1
Dim input As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Text = "Nested Loops"
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label.Click
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles InputTextBox.TextChanged
input = Val(InputTextBox.Text)
End Sub
Private Sub ComputeButton_Click(sender As Object, e As EventArgs) Handles ComputeButton.Click
For outer As Integer = 1 To input
For inner As Integer = 1 To outer
ListBox.Items.Add("#")
Next
ListBox.Items.Add("")
Next
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox.SelectedIndexChanged
End Sub
End Class
I get this error when trying to treat it like dart
System.InvalidCastException: 'Conversion from string "#" to type 'Double' is not valid.'
I need help.
Consider:
For outer As Integer = 1 To input
Dim s as String
For inner As Integer = 1 To outer
s &= "#"
Next
ListBox.Items.Add(s)
Next
i.e. you want to have a string that grows by one # each time before you add it to the thing that will display it:
"#"
"##"
"###"
"####"
This uses simple string concatenation. In the future when you're programming for real (and e.g. wanting to run a process that creates millions of strings) you should consider using something designed for the job, such as a StringBuilder. This will be ok for some small handful of operations though
Though I'm rather puzzled why you use a listbox and not just a textbox..

when the text in a textbox is equal to a certain word i need to value in the combo box to be saved for that text

I have orders in text files in the debug folder and when i type the name of the order in a text box it displays the order is a list box and there is a combo box underneath where i can change the status of the meal preparation (Being prepared, ready to deliver etc,). If i go back to that form and type in the same order name into the textbox i need to previous prepartion status to be already in the textbox. Thanks for any help!
Public Class frmOrderStatus
Private Sub btnStatus_Click(sender As Object, e As EventArgs) Handles btnStatus.Click
Dim sr As IO.StreamReader = IO.File.OpenText(strTxtOrderNum & ".txt")
Do Until sr.EndOfStream
lstOrder.Items.Add(sr.ReadLine)
Loop
End Sub
Private Sub OrderStatus_Load(sender As Object, e As EventArgs) Handles MyBase.Load
lstOrder.Items.Clear()
btnStatus.Enabled = False
ChangeStatus.Enabled = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnValidate.Click
strTxtOrderNum = txtOrderNum2.Text
btnStatus.Enabled = True
ChangeStatus.Enabled = True
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
strSaveStatus = ChangeStatus.SelectedIndex
End Sub
Private Sub ChangeStatus_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ChangeStatus.SelectedIndexChanged
End Sub
End Class
It recognizes the file; it just tells you it is in use. A Stream must be closed and disposed. I don't see the StreamReader even being closed let alone disposed. A `Using...End Using block will close and dispose of objects even if there is an error.
I just used a text file I happened to have to test.
Private strTxtOrderNum As String = "host"
Private Sub ReadFile()
Using sr As IO.StreamReader = IO.File.OpenText(strTxtOrderNum & ".txt")
Do Until sr.EndOfStream
ListBox1.Items.Add(sr.ReadLine)
Loop
End Using
End Sub
Private Sub WriteFile()
Dim strSelectedItem = ComboBox1.Text
Using swVar As IO.StreamWriter = IO.File.AppendText(strTxtOrderNum & ".txt")
swVar.WriteLine(strSelectedItem)
End Using
End Sub

Visual Basic Beginner ..SubStrings

I'm new to programming and I'm trying to figure out this simple question! The language is Visual Basic! The Question is below:
"Users of a computer program often like to enter numbers with commas inserted in the middle, such as "1,234,000,688". Most computer languages consider this format to be non numeric. Write a program that inputs a number containing no more than three commas, and produces a string containing the same number without the commas"
When I enter this number: 1,234,000,688 and hit Display in Visual Basic I get this error message --> Argument is out of range Exception was unhanded
I'm not exactly sure why this is happening because I'm within my strUserInput length.
My Code:
Public Class Form1
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
'Variable declarations
Dim strUserInput = txtUserInput.Text
Dim strOutputNumber1 As String
Dim strOutputNumber2 As String
Dim strOutputNumber3 As String
Dim strOutputNumber4 As String
' 1,234,000,688
strOutputNumber1 = strUserInput.Substring(0, 1)
strOutputNumber2 = strUserInput.Substring(2, 4)
strOutputNumber3 = strUserInput.Substring(5, 8)
strOutputNumber4 = strUserInput.Substring(9, 12)
lblDisplayNumber.Text = strOutputNumber1 & strOutputNumber2 & strOutputNumber3 & strOutputNumber4
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
lblDisplayNumber.Text = String.Empty
txtUserInput.Text = String.Empty
End Sub
End Class
You're getting that exception because of the way you're using substring, the last one there starts at index 9 and extends 12 characters...that would be a 22 character number, and the text you have as input is probably much shorter. You don't need to make things overly complicated for yourself using substrings, all of the above code could be greatly condensed and cleaned up by simply using String.Replace like this:
Public Class Form1
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
lblDisplayNumber.Text = txtUserInput.Text.Replace(",", "")
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
lblDisplayNumber.Text = String.Empty
txtUserInput.Text = String.Empty
End Sub
End Class

Copying multiple sources to single destination

I am new to VB.net and am trying to create a backup utility to copy a set of local folders to a single backup destination (on usb for example) with a progress bar. After googling for the last few hours I can only find examples of single folder to single destination.
Can anyone point me in the direction of an example?
UPDATE:
Based of #Werdna example, I have created a simple FOR EACH NEXT loop. However the next issue is that only the files within the source directories are being copied to the target directory, rather than the folders and all their contents. Can anyone see where I am going wrong?
Public Class Form1
Private Sub Start_Click(sender As Object, e As EventArgs) Handles Start.Click
Dim destination = "E:\Backup Folder"
Dim sources As New List(Of String)
sources.Add("D:\Profiles\Users\Desktop")
sources.Add("D:\Profiles\Users\Mail")
sources.Add("D:\Profiles\Users\Downloads")
For Each source As String In sources
My.Computer.FileSystem.CopyDirectory(source, destination)
Next
MessageBox.Show("Copy Completed")
End Sub
End Class
Also, what is the best method to use the FOR EACH NEXT loop to count the number of files to be copied? I would like to output the amount to a label as well as use it for a progressbar as the utility evolves.
here is something that i have quickly written up for you to give you some idea on how i went about completing your task. You will need to add 2 listboxes to your application, a folder open dialog and a few buttons, this might not be what you are looking for, unfortunately you cant select multiable folders with the other dialogs, however nevertheless, take a look below, the code isn't completely as there is always something to do, however this should lead you in the right direction hopefully!
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each item In IO.Directory.GetDirectories("C:\")
ListBox1.Items.Add(item)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each item In ListBox1.SelectedItems
ListBox2.Items.Add(item & "\")
Next
ListBox1.SelectedItem = Nothing
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
ListBox2.Items.Remove(ListBox2.SelectedItem)
ListBox2.SelectedItem = Nothing
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For Each item In IO.Directory.GetDirectories(ListBox1.SelectedItem)
ListBox1.Items.Clear()
ListBox1.Items.Add(item)
Next
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
If FolderBrowserDialog1.ShowDialog = DialogResult.OK Then
My.Computer.FileSystem.CreateDirectory(FolderBrowserDialog1.SelectedPath)
For Each item In ListBox2.Items
My.Computer.FileSystem.CopyDirectory(item, FolderBrowserDialog1.SelectedPath)
Next
MessageBox.Show("Copy Completed.")
End If
End Sub
End Class
I wrote this in about 10 minutes, so i didnt get a change to do a progessbar, however if this is what you are looking for, then i am happy to help you add one to your program. Happy Coding!
UPDATE - BASED OFF YOUR NEW QUESTION
Public Class Form1
Dim NumberofFILEs As Integer = 0
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim Location1 = "C:\Backup Folder\TESTING\FOLDER"
Dim source As String = "C:\TESTING\FOLDER"
Dim source1 As String = "C:\TESTING1\FOLDER"
Dim Location2 = "C:\Backup Folder\TESTING1\FOLDER"
IO.Directory.CreateDirectory("C:\Backup Folder\TESTING\FOLDER")
IO.Directory.CreateDirectory("C:\Backup Folder\TESTING1\FOLDER")
For Each item In source
My.Computer.FileSystem.CopyDirectory(source, Location1, True)
Next
For Each item In source1
My.Computer.FileSystem.CopyDirectory(source1, Location2, True)
Next
MessageBox.Show("Completed")
For Each file In source1.Count & source.Count
NumberofFILEs += 1
Next
Label1.Text = NumberofFILEs
End Sub
End Class
Edit the locations and destinations to what you need. Also the True at the end of the copydirectory means that it will overwrite any files with the same name, eg it will update them pretty much
You can copy each folder to the destination, one at a time. Loop through the source folders and copy each one to the target folder.

Get files one at a time from a folder in VB.NET

I am trying to read some text files path in a folder sequentially. However, I get only the first file.
I need to get the first file, execute a timer, get the next file path, execute a timer right up to the last file in the folder, and stop. How can I get around this?
Private zMailbox As String = "c:\Fold\"
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub
Thanks to the contributions below I got the code to work with the text box value. However, it gives the index count instead of the path which I want to retrieve.
Private zMailbox As String = "c:\Fold\"
Dim files As FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
If index >= files.Length Then
index = 0
End If
TextBox1.Text = (ListBox1.Items.Add(files(index)))
index += 1
End Sub
Your code loads all the files in the Timer event and assign them to the TextBox1.Text property inside the loop. Every loop overwrites the data that has been written in the previous loop.
At the end of the loop you see only the last value.
To show sequentially the files inside the Timer Tick event, you need to read the directory content before starting the Timer in a global FileInfo array. Another global variable will be used as indexer to show a particular file from this FileInfo array in your Timer.Tick event.
The index will be incremented and, at the next Tick, you could show the next file
Dim files as FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
index = 0
End If
TextBox1.Text = files(index)
index += 1
End Sub
EDIT
According to your comment, you need to set the MultiLine property of the TextBox to true (using the form designer) and then, at every Tick, instead of replacing the Text property, append to it
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
return ' Reached the end of the array. Stop the Timer???
End If
TextBox1.AppendText(files(index) & Environment.NewLine)
index += 1
End Sub
As a side note, if you want to show all file names together then it is not clear why you need a timer at all.
You could get the same result with code like this
Dim finfo As New IO.DirectoryInfo(zMailbox)
Dim files = finfo.EnumerateFiles("*.txt")
TextBox1.Text = string.Join(Environment.NewLine, files.Select(Function(x) x.FullName).ToArray())
On the original code you posted you where getting all files in the for loop each time the timer clicks.
After reading steve answer, and your comments, probably you always got all the files, but you override the textbox.text value.
TextBox1.Text += < String > & vbNewLine
Where < String >, of course, is the string returned by DirectoryInfo.GetFiles()
I think steve answer works just fine, but you are not implementing it well.
I would try and make this as easy as possible for you. You Microsoft's Reactive Framework for this. Just NuGet "Rx-Main".
Here's what you can then do:
finfo.GetFiles("*.txt").ToObservable() _
.Zip(Observable.Interval(TimeSpan.FromSeconds(1.0)), Function(f, _) f.Name) _
.ObserveOn(TextBox1) _
.Subscribe(Function(n) textbox_text += n + Environment.NewLine)
That's it. No timers. No separate methods. No need for module-level variables. Just one line of code and you're done.
It's processed on a background thread and then marshalled back to the UI via the .ObserveOn(TextBox1) call.
You can even keep a reference to the IDisposable returned by the .Subscribe(...) call to terminate the observable (timer) early.
Simple.
This seems a bit Rube Goldberg-ish. Just get all the files and loop through them in your Button_Click method:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub