Reputation: 294
I am trying to make a program to organize folders full of random stuff. I want it to put each file type into a folder that describes what it is in it. I have arrays of file types inside another array so it can loop through.
It can move the file types specified in the array fine, but when I tried to make it put each type into a seperate folder, it says that the array index is out of bounds.
It works fine if you replace the index of Names to a number, but i can't get it to change it automatically.
Here is the code I am using:
Dim Extensions As Array = {Audio, Video, Image, Document, PlainText, Batch, Powershell, VB, DiskImage, Compressed, Excutable, Model, Code, Web, Registry}
Dim Names As String() = {"Audio", "Videos", "Pictures", "Documents", "Text Documents", "Batch", "Powershell", "Visual Basic", "DiskImages", "Compressed Files", "Excutables", "3d Models", "Code", "Web", "Registry"}
Dim number As Integer = 0
For Each type As String() In Extensions
number += 1
path = path + Names(number)
For Each extension As String In type
Label2.Text = extension
CopyMove(FolderBrowserDialog2.SelectedPath, path, extension, s)
Next
Next
Upvotes: 1
Views: 1970
Reputation: 656
You primarily have three issues:
MsgBox(4 + 5) ' output: 9
MsgBox(4 & 5) ' output: 45
A dictionary is basically like an array (it's a "collection") that instead of putting in a number as your key, you can put in a custom variable type of your choice (like a string!), so instead of trying to find the extensions number that matches a file extension, looking that up in an array then comparing that with another array, you can just say "give me the folderPath for an extension('.txt')", and it does all the pairing work for you.
On your form create a "TextBox" which should be named "TextBox1" by default.
Find the property "MultiLine" and set it to true.
Make it bigger.
Public Class Form1
' List of file types that I want to sort
Private fileFolders As New Dictionary(Of String, String) From {
{".txt", "documents"},
{".doc", "documents"},
{".docx", "documents"},
{".png", "images"},
{".jpg", "images"},
{".mp4", "videos"}
} ' TODO: Add more
Private Sub MoveFiles(Optional sourceDirectory As String = "")
TextBox1.Text = ""
If sourceDirectory = "" Then sourceDirectory = "source"
' list of files to sort
Dim files As String() = IO.Directory.GetFiles(sourceDirectory, "*.txt", IO.SearchOption.AllDirectories)
If files.Length = 0 Then
TextBox1.Text &= "No files were found in source directory!"
Exit Sub
End If
Dim fileName As String
Dim fileExtension As String
Dim folderName As String
For Each sourceFile As String In files
fileName = IO.Path.GetFileName(sourceFile)
fileExtension = IO.Path.GetExtension(sourceFile)
' set folderName to "misc" if I don't have an extension case in my dictionary to handle it:
If fileFolders.ContainsKey(fileExtension) Then
folderName = fileFolders(fileExtension) ' dictionary entry gets used here
Else
folderName = "misc"
End If
CheckCreateDirectory(folderName) ' creates folder if doesn't exist
' String interpolation is prettier than string concatenation and highly optimized, feel free to use it a lot,
' the syntax is dollar sign, opening quotes, literal string, insert variables in braces, closing quotes:
TextBox1.Text &= $"Moving file: [{sourceFile}] to folder: [{folderName}]{Environment.NewLine}"
IO.File.Move(sourceFile, fileFolders(folderName) & "\" & fileName)
Next
End Sub
Private Sub CheckCreateDirectory(directoryName As String)
If Not IO.Directory.Exists(directoryName) Then
TextBox1.Text &= $"Folder: [{directoryName}] does not exist, creating folder" & vbCrLf
IO.Directory.CreateDirectory(directoryName)
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MoveFiles("source")
End Sub
End Class
Upvotes: 0
Reputation: 415735
Paired arrays such as this are poor practice. Much better to create a class and then use a single array or List of that class:
Public Class FileType
Public Property Category As String
Public Property Extensions As List(Of String)
End Class
Dim Filetypes As New List(Of FileType) From {
New FileType() With {Category = "Audio", Extensions = Audio },
New FileType() With {Cateogry = "Video", Extensions = Video }
'...
}
For Each type As FileType In FileTypes
Dim thisPath As String = Path.Combine(path, type.Category)
For Each extension As String In type.Extensions
Label2.Text = extension ' this label won't update inside the method, but that's another question
CopyMove(FolderBrowserDialog2.SelectedPath, thisPath, extension, s)
Next
Next
Upvotes: 3