I am attempting to rename files found in a main folder, but then put the renamed files in the same directory as the files to be copied. This is my original folder structure:
Main Folder
|
|____file1.txt
|____file2.txt
|____file1.txt
I want to now create a folder under the Main Folder called "Renamed" and place the renamed files in there. The new folder structure should look like this after successfully executing the code:
Main Folder
|
|____Renamed
| |
| |____renamed-file1.txt
| |____renamed-file2.txt
| |____renamed-file3.txt
|
|____file1.txt
|____file2.txt
|____file1.txt
However, in the code that I have so far, I cannot create the "Renamed" folder under the Main Folder as I get the error message Run-time error '5': Invalid procedure call or argument that seem to occur at the line fso.CopyFolder sItem, strPath2. Can you help me create the folder structure with the renamed folder and files.
Here is my code:
Sub RenameFile()
Dim fldr As FileDialog
Dim sItem As String
Dim strPath As String
Dim strPath1 As String
Dim strPath2 As String
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
Dim z As String
Dim s As String
Dim V As Integer
Dim TotalRow As Integer
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
TotalRow = ActiveSheet.UsedRange.Rows.Count
NextCode:
strPath = sItem
strPath2 = fso.BuildPath(sItem, "Renamed")
' Create the folder "Renamed"
fso.CopyFolder sItem, strPath2
For V = 1 To TotalRow
' Get value of each row in columns 1 start at row 2
z = Cells(V + 1, 1).Value
' Get value of each row in columns 2 start at row 2
s = Cells(V + 1, 2).Value
Dim sOldPathName As String
sOldPathName = fso.BuildPath(strPath2, z)
sNewPathName = fso.BuildPath(strPath2, s)
Name sOldPathName As sNewPathName
On Error Resume Next
Name sOldPathName As s
Next V
MsgBox "Congratulations! You have successfully renamed all the files"
End Sub
Copy and Rename Files Using Dir and FileCopy
Using FileCopy is much faster, simpler, and more straightforward: it copies and renames in one go.
This is a simplified example to get you familiar with Dir and FileCopy. In your case, you would 'Dir' each name in column A and if the length of the filename is greater than 0 (confirming that the file exists), you would 'FileCopy the source path to the destination path (using the names in column B)'.
Sub RenameFiles()
' Source
Const sFilePattern As String = "*.*"
Dim sInitPath As String: sInitPath = Application.DefaultFilePath & "\"
' Destination
Const dSubFolderName As String = "Renamed"
Const dPrefix As String = "renamed-"
Dim sFolderPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a Folder"
.InitialFileName = sInitPath
If .Show <> -1 Then
MsgBox "You canceled.", vbExclamation
Exit Sub
End If
sFolderPath = .SelectedItems(1) & "\"
End With
Dim dFolderPath As String: dFolderPath = sFolderPath & dSubFolderName & "\"
If Len(Dir(dFolderPath, vbDirectory)) = 0 Then MkDir dFolderPath
Dim sFileName As String: sFileName = Dir(sFolderPath & sFilePattern)
If Len(sFileName) = 0 Then
MsgBox "No files found.", vbExclamation
Exit Sub
End If
On Error GoTo FileCopyError
Do Until Len(sFileName) = 0
FileCopy sFolderPath & sFileName, dFolderPath & dPrefix & sFileName
sFileName = Dir
Loop
On Error GoTo 0
MsgBox "Congratulations! You have successfully renamed all the files.", _
vbInformation
Exit Sub
FileCopyError:
Debug.Print "Run-time error '" & Err.Number & "': " & Err.Description _
& vbLf & "Could not copy '" & sFileName & "'."
Resume Next
End Sub
Related
The goal is to combine two functions or make them compatible with each other. There is errors when it comes to the part when the path of the chosen file is not refer to in the same manner as the path of the found file within the loop if available in the folder.
I get an error. See "HERE IS WHERE I GET THE ERROR" at
Dim closedBook As Workbook: Set closedBook = Workbooks.Open(sFilePath)
'main code that run is doing something like search for file within folder,
'loop and get the latest file and generates a path and name for next
'function which is to copy a sheet from the found file over to the main
'workbook and so.
'What I'm trying to to is to build a failsafe, lets say file is not pushed
'or placed whin this predestinated folder, then instead of doing nothing,
'dialog box opens up and files gets chosen instead.
Option Explicit
Sub ImportAndFormatData()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Const sFolderPath As String = "C:\Temp\"
'Search for newest file
Dim sFileName As String: sFileName = Dir(sFolderPath & "_pr11*.xlsx")
If Len(sFileName) = 0 Then Call OpenDialogBox
Dim cuDate As Date, sFileDate As Date, cuPath As String, sFilePath As String
Do Until Len(sFileName) = 0
cuPath = sFolderPath & sFileName
cuDate = FileDateTime(cuPath)
'Debug.Print "Current: " & cuDate & " " & cuPath ' print current
If cuDate > sFileDate Then
sFileDate = cuDate
sFilePath = cuPath
End If
sFileName = Dir
Loop
'Debug.Print "Result: " & sFileDate & " " & sFilePath ' print result
'Open newest file - HERE IS WHERE I GET THE ERROR
Dim closedBook As Workbook: Set closedBook = Workbooks.Open(sFilePath)
closedBook.Sheets("Analyse").Copy After:=ThisWorkbook.Sheets("PR11_P3")
closedBook.Close SaveChanges:=False
'code dose not end here but that part don't need to be included here since
'its just formatting
End Sub
In OpenDialogBox, I'm tying to enforce a specific title (only this file/report is correct source for the entire code or rather rest of the code).
See "GIVES ERROR DOSENT WORK" at
.Filters.Add "Excel filer", "_pr11*.xlsx?", 1
Sub OpenDialogBox()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Filters.Clear
.Title = "Välj valfri PR11"
.Filters.Add "Excel filer", "_pr11*.xlsx?", 1 'GIVES ERROR DOSENT WORK
.AllowMultiSelect = False
If .Show = True Then
Debug.Print .SelectedItems(1)
Debug.Print Dir(.SelectedItems(1))
End If
End With
End Sub
This combines both the Dir() and FileDialog approaches:
Sub ImportAndFormatData()
Dim fSelected As String, wb As Workbook
fSelected = InputFile()
If Len(fSelected) > 0 Then
Set wb = Workbooks.Open(fSelected)
wb.Sheets("Analyse").Copy After:=ThisWorkbook.Sheets("PR11_P3")
wb.Close False
End If
End Sub
Function InputFile() As String
Const SRC_FOLDER As String = "C:\Temp\"
Dim f, fSelected As String, latestDate As Date, fdt
f = Dir(SRC_FOLDER & "*_pr11*.xlsx") 'first check the configured folder for a match
If Len(f) > 0 Then
'found matching file at specified path: loop for the newest file
Do While Len(f) > 0
fdt = FileDateTime(SRC_FOLDER & f)
If fdt > latestDate Then
fSelected = SRC_FOLDER & f
latestDate = fdt
End If
f = Dir()
Loop
InputFile = fSelected
Else
'no match at specified path - allow user selection
With Application.FileDialog(msoFileDialogFilePicker)
.Filters.Clear
.Title = "Välj valfri PR11"
.Filters.Add "Excel filer", "*.xlsx" 'filter only allows extension: no filename wildcards...
.AllowMultiSelect = False
If .Show Then InputFile = .SelectedItems(1)
End With
End If
End Function
I'm trying to use Excel VBA to find a string in a folder, but it seems the FINDSTR command line is not working.
I'm wondering if it could be a change in Windows (I'm using Win10), or if I don't have a have the correct "Reference" selected (I do have the Microsoft Scripting Runtime selected).
Sub ListFilesContainingString()
Dim myfile As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
wrd = InputBox("Word:", "Insert search word")
If wrd = "" Then
MsgBox "???"
Exit Sub
End If
myfile = FindFiles(GetFolder, wrd)
If (myfile <> "") Then MsgBox file
End Sub
Function FindFiles(ByVal path As String, ByVal target As String) As String
' Run The Shell Command And Get Output
Dim files As String
files = CreateObject("Wscript.Shell").Exec("FINDSTR /M """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
FindFiles = ""
If (files <> "") Then
Dim idx As Integer
idx = InStr(files, vbCrLf)
FindFiles = Left(files, idx - 1)
End If
I fixed the typo but FINDSTR is still not working correctly. My current code is below. Note that there are several instances of FINDSTR and FIND so I can see what is being returned (the "If, Then x=x" code is only to place a breakpoint). FINDSTR returns "", FIND returns a file but it isn't a correct file.
FINDSTR does work using a dos/powershell window.
Sub ListFilesContainingString()
'this macro finds vendor information on the chosen file for each part in the origin file
Dim myfile As String
Dim fldr As FileDialog
Dim sItem As String
Dim wrd As String
''''''''''''''''''''''''''''''''''''''
Dim objFSO As Object
Dim objFolders As Object
Dim objFolder As Object
Dim DirFolderRename As String
Dim arrFolders() As String
Dim FolderCount As Long
Dim FolderIndex As Long
''''''''''''''''''''''''''''''''''''''
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
''''''''''''''''''''''''''''''''''''''
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolders = objFSO.GetFolder(sItem).SubFolders
FolderCount = objFolders.Count
If FolderCount > 0 Then
ReDim arrFolders(1 To FolderCount)
FolderIndex = 0
For Each objFolder In objFolders
FolderIndex = FolderIndex + 1
arrFolders(FolderIndex) = objFolder.Name
Next objFolder
Else
MsgBox "No folders found!", vbExclamation
End If
Set objFSO = Nothing
Set objFolders = Nothing
Set objFolder = Nothing
''''''''''''''''''''''''''''''''''''''
Set wrdAddr = Application.InputBox("Select First Word to Search For", "Obtain Range Object", Type:=8)
wrdCol = wrdAddr.Column
wrdRow = wrdAddr.Row
StartCell = Cells(wrdRow, wrdCol).Address
Range(StartCell).Activate
wrd = ActiveCell.Value
While (wrd <> "")
'wrd = InputBox("Word:", "Insert search word")
If wrd = "" Then
MsgBox "???"
Exit Sub
End If
For i = 1 To FolderCount
TheFolder = GetFolder & "\" & arrFolders(i)
myfile = FindFiles(TheFolder, wrd)
If (myfile <> "") Then
ActiveCell.Offset(0, 17).Value = ActiveCell.Offset(0, 17).Value & arrFolders(i) & ","
End If
Next i
ActiveCell.Offset(1, 0).Select
wrd = ActiveCell.Value
Wend
End Sub
Function FindFiles(ByVal path As String, ByVal target As String) As String
' Run The Shell Command And Get Output
Dim files1, files2, files3, files4 As String
Dim lines
'''' This works in the dos window
' findstr /M /S /I L298P C:\Users\Wm" "Boyd\Documents\Boyd" "Manufacturing\Customers\Inactive\*.xls?
''''
exec ("FINDSTR /M L298P C:\Users\Wm""Boyd\Documents\Boyd""Manufacturing\Customers\Inactive\*.xls?")
files1 = CreateObject("WScript.Shell").exec("FINDSTR /M """ & target & """ """ & path & "\*.xls?""").StdOut.Read
files2 = CreateObject("Wscript.Shell").exec("FINDSTR /M L298P C:\Users\Wm""Boyd\Documents\Boyd""Manufacturing\Customers\Inactive\*.xlsx").StdOut.ReadAll
If files1 <> "" Then
x = x
End If
files3 = CreateObject("Wscript.Shell").exec("FIND """ & target & """ """ & path & "\*.xls?""").StdOut.ReadAll
files4 = CreateObject("Wscript.Shell").exec("FIND """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
lines = Split(files1, vbCrLf)
Dim curFile As String
Dim line
For Each line In lines
If (Left(line, 11) = "---------- ") Then
curFile = Mid(line, 12)
End If
If (curFile <> "") Then
FindFiles = curFile
Exit Function
End If
Next
'files = CreateObject("Wscript.Shell").Exec("FINDSTR """ & target & """ """ & path & "\*.*""").StdOut.ReadAll
'If (files <> "") Then
'Dim idx As Integer
'idx = InStr(files, vbCrLf)
'FindFiles = Left(files, idx - 1)
'End If
FindFiles = ""
End Function
I have created a log file to record the command executed and the response. This is a first step, if it works the next step would be to parse the response for the information you want.
Option Explicit
Sub ListFilesContainingString()
Const qq = """"
' get first word from sheet
Dim wrdCell As Range
Set wrdCell = Application.InputBox("Select First Word to Search For", _
"Obtain Range Object", Type:=8)
If Len(wrdCell.Value2) = 0 Then
MsgBox "No word selected", vbCritical
Exit Sub
End If
' start logging
Dim Folder As String, FSO As Object, tsLog As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim logfile As String, cmd As String, n As Long
Dim msg As String, W As Object, s As String
logfile = ThisWorkbook.path & "\" & "Log_" _
& Format(Now(), "yyyymmdd_hhmmss") & ".txt"
Set tsLog = FSO.CreateTextFile(logfile)
Set W = CreateObject("Wscript.Shell")
' get folders
Folder = GetFolder("C:\") 'start in c:\
If Len(Folder) = 0 Then Exit Sub
' scan for each words
Do While Not IsEmpty(wrdCell)
' message box
msg = msg & vbLf & wrdCell.Address & " " & wrdCell
' build command
s = qq & wrdCell & qq & " " & qq & Folder
cmd = "FINDSTR /M /S " & s & "\*.*" & qq
tsLog.writeLine "Command" & vbCrLf & cmd & vbCrLf
' execute
s = W.exec(cmd).StdOut.ReadAll
tsLog.writeLine "Result" & vbCrLf & ">" & s & "<" & vbLf
' next
n = n + 1
Set wrdCell = wrdCell.Offset(1)
Loop
tsLog.Close
MsgBox "Words searched for " & msg, vbInformation, "See " & logfile
Shell "notepad.exe " & logfile
End Sub
Function GetFolder(strPath) As String
Dim fldr As FileDialog
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then
MsgBox "Cancelled", vbExclamation
Exit Function
End If
GetFolder = .SelectedItems(1)
End With
End Function
I am having 2 issues with the below code.
on the first loop it finds the same file, hence why I have it skip if the file is the same name. After that it will proceed as it should. On the 3rd loop instead of finding the 3rd file (fileName2 = Dir) becomes fileName2 = "".
When I want fileName to go to the second file (fileName = Dir) I get a run time 5 error.
*Note: I currently have 6 files in the folder that I am testing but I will want to use for folders that have 10,000 small files
Sub TestMD5()
Dim myfilepath As String
Dim myfilepath2 As String
Dim fileName As Variant
Dim fileName2 As Variant
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem & "\"
Set fldr = Nothing
fileName = Dir(GetFolder)
fileName2 = Dir(GetFolder)
Do While fileName <> ""
Do While fileName2 <> ""
myfilepath = GetFolder & fileName
myfilepath2 = GetFolder & fileName2
If myfilepath <> myfilepath2 Then
If FileToMD5Hex(myfilepath) = FileToMD5Hex2(myfilepath2) And FileToSHA1Hex(myfilepath) =
FileToSHA1Hex2(myfilepath2) Then
'Kill (myfilepath2)
Debug.Print "match - " & (fileName) & " & " & (fileName2)
Else
Debug.Print "no match - " & (fileName) & " & " & (fileName2)
End If
End If
fileName2 = Dir
Loop
'Set the fileName to the next file
fileName = Dir
Loop
End Sub
I mashed your code together with the "File system Object" approach, where we can do a For each loop on the files.
This at least gets you away from the whole run time 5 error. Maybe it could be of use.
Sub TestMD5()
Dim myfilepath As Variant, myfilepath2 As Variant
Dim sItem As String
Dim fso As Object
Dim fldr As Variant
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = fso.GetFolder(sItem & "\")
For Each myfilepath In fldr.Files
For Each myfilepath2 In fldr.Files
If Not myfilepath = myfilepath2 Then
If FileToMD5Hex(myfilepath) = FileToMD5Hex2(myfilepath2) And FileToSHA1Hex(myfilepath) = FileToSHA1Hex2(myfilepath2) Then
'Kill (myfilepath2)
Debug.Print "match - " & (myfilepath) & " & " & (myfilepath2)
Else
Debug.Print "no match - " & (myfilepath) & " & " & (myfilepath2)
End If
End If
Next myfilepath2
Next myfilepath
End Sub
I think FileDialog(msoFileDialogFilePicker) should be used instead of FileDialog(msoFileDialogFolderPicker)
The following code goes through all PDF files in a folder, gets the first word of the file name and checks excel spreadsheet if the word it exists in a range.If it does not exist, it renames the file and adds the word "uploaded". The issue is that once it goes through all the files in the folder in goes through them again and again. How can I prevent this from happening?
Sub checkmissing()
Dim MyFolder As String, MyFile As String,
Dim ioid As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
MyFolder = .SelectedItems(1)
Err.clear
End With
MyFile = Dir(MyFolder & "\" & "*.pdf")
Do While MyFile <> ""
DoEvents
On Error GoTo 0
ioid = Split(MyFile, " ")(0)
Range("G1").Activate
With ActiveSheet.Range("G1:G10000")
Set c = .Find(ioid, LookIn:=xlValues)
If c Is Nothing Then
Name MyFolder & "\" & MyFile As MyFolder & "\" & "Uploaded " & MyFile
End If
End With
ChDir MyFolder
0
MyFile = Dir
Loop
End Sub
I need to do the following:
Allow the user to select any number of files, in any format, and copy them to a new folder.
Create the destination folder if it doesn't exist. In this case, the folder name should be given by the content of the C2 & C3 cells (Range("C2").Value & Range("C3").Text & "\").
Private Sub CommandButton4_Click()
Dim strDirname As String
Dim strDefpath As String
Dim strPathname As String
Dim strFilename As String
Dim FSO
Dim sFile As FileDialog
Dim sSFolder As String
Dim sDFolder As String
strDirname = Range("C2").Value & Range("C3").Text
MkDir strDefpath & "\" & strDirname
strPathname = strDefpath & "\" & strDirname & "\" & strFilename
Set sFile = Application.FileDialog(msoFileDialogOpen)
sDFolder = strDirname & "\"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO = New FileSystemObject
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
If Not .Show Then Exit Sub
Set xFolder = FSO.GetFolder(.SelectedItems(1))
For Each xFile In xFolder.Files
On Error Resume Next
xRow = Application.Match(xFile.Name, Range("A:A"), 0)
On Error GoTo 0
Next
End With
End Sub
I know the error is here...
Set xFolder = FSO.GetFolder(.SelectedItems(1))
...because I'm asking it to get a file, not a folder.
It is not very clear to me what you are trying to do but, if you intend to select a folder, you have to use it
Application.FileDialog (msoFileDialogFolderPicker)
instead of
Application.FileDialog (msoFileDialogFilePicker)
Your posted code shows so little resemblance to what you Q asks for, I've disregarded it.
This code follows the description. You may need to alter certain details to fully match your needs
Sub Demo()
Dim FilePicker As FileDialog
Dim DefaultPath As String
Dim DestinationFolderName As String
Dim SelectedFile As Variant
Dim DestinationFolder As Folder
Dim FSO As FileSystemObject
DefaultPath = "C:\Data" ' <~~ update to suit, or get it from somewhere else
' Validate Default Path
If Right$(DefaultPath, 1) <> Application.PathSeparator Then
DefaultPath = DefaultPath & Application.PathSeparator
End If
If Not FSO.FolderExists(DefaultPath) Then Exit Sub
' Get Destination Folder, add trailing \ if required
DestinationFolderName = Range("C2").Value & Range("C3").Value
If Right$(DestinationFolderName, 1) <> Application.PathSeparator Then
DestinationFolderName = DestinationFolderName & Application.PathSeparator
End If
Set FSO = New FileSystemObject
' Get reference to Destination folder, create it if required
If FSO.FolderExists(DefaultPath & DestinationFolderName) Then
Set DestinationFolder = FSO.GetFolder(DefaultPath & DestinationFolderName)
Else
Set DestinationFolder = FSO.CreateFolder(DefaultPath & DestinationFolderName)
End If
' File Selection Dialog
Set FilePicker = Application.FileDialog(msoFileDialogFilePicker)
With FilePicker
.AllowMultiSelect = True ' allow user to select multiple files
.InitialFileName = DefaultPath ' set initial folder for dialog
If .Show = False Then Exit Sub ' check if user cancels
For Each SelectedFile In .SelectedItems ' loop over selected files
If SelectedFile Like DefaultPath & "*" Then 'Optional: disallow browsing higher than default folder
FSO.CopyFile SelectedFile, DefaultPath & DestinationFolderName, True ' Copy file, overwrite is it exists
End If
Next
End With
End Sub