Below is code that should let me select a folder, then find and replace periods in the word documents within the folder and replace them with a space.
I got the code to work, my computer crashed, and now I don't remember what I did, and I'm getting a 'user-defined type' error.
I'm not quite sure how to fix this.
I'm also trying to get this to work from excel (not just from word) so any help there would be appreciated.
Sub Step_1() 'select folder with raw files to clean up
Dim wordApp As Word.Application
Dim objDocument As Word.Document
Dim intResult As Integer
Dim strPath As String
Dim arrFiles() As String
Dim i As Integer
'box will open where user can pick folder with raw files
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
'checks if user has cancelled the dialog
If intResult <> 0 Then
'display folder search box
strPath = Application.FileDialog( _
msoFileDialogFolderPicker).SelectedItems(1)
arrFiles() = GetAllFilePaths(strPath)
For i = LBound(arrFiles) To UBound(arrFiles)
Call ModifyFile(arrFiles(i))
Next i
End If
End Sub
Private Sub ModifyFile(ByVal strPath As String)
Dim wordApp As Word.Application
Dim objDocument As Word.Document
Set objDocument = wordApp.Documents.Open(strPath)
objDocument.Activate
For Each objDocument In strPath
With Selection.Find
.Text = "."
.Replacement.Text = " "
.Find.Execute Replace:=wdReplaceAll
'there's a much longer list of things to replace
End With
objDocument.Close (True)
Next
Next
End Sub
Private Function GetAllFilePaths(ByVal strPath As String) _
As String()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Dim arrOutput() As String
ReDim arrOutput(1 To 1)
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(strPath)
i = 1
'loops through each file in the directory and
'prints their names and path
For Each objFile In objFolder.Files
ReDim Preserve arrOutput(1 To i)
'print file path
arrOutput(i) = objFile.Path
i = i + 1
Next objFile
GetAllFilePaths = arrOutput
End Function
Cleaned up:
Sub ProcessFiles()
Dim wordApp As Word.Application
Dim wdDoc As Word.document
Dim strPath As String, allfiles As Collection, fPath
strPath = GetFolderPath()
If Len(strPath) = 0 Then Exit Sub
Set allfiles = GetAllFiles(strPath, "*.doc*")
If allfiles.Count = 0 Then
MsgBox "No Word files found"
Exit Sub
End If
Set wordApp = New Word.Application
wordApp.Visible = True
'loop over found files
For Each fPath In allfiles
Debug.Print "Processing " & fPath
Set wdDoc = wordApp.documents.Open(fPath)
ReplaceDocContent wdDoc, ".", " "
ReplaceDocContent wdDoc, ",", " "
ReplaceDocContent wdDoc, "~", " "
'etc.....
wdDoc.Close True 'close and save changes
Next fPath
MsgBox "done"
End Sub
'replace text in a Word document with some other text
Private Sub ReplaceDocContent(doc As Word.document, findWhat, replaceWith)
With doc.Range.Find
.Text = findWhat
.Replacement.Text = replaceWith
.Execute Replace:=wdReplaceAll
End With
End Sub
'collect all files under folder `strPath` which match `pattern`
Private Function GetAllFiles(ByVal strPath As String, pattern As String) As Collection
Dim objFile As Object, col As New Collection
'Create an instance of the FileSystemObject and list all files
For Each objFile In CreateObject("Scripting.FileSystemObject").GetFolder(strPath).Files
If objFile.Path Like pattern Then col.Add objFile.Path
Next objFile
Set GetAllFiles = col
End Function
'return selected folder path or empty string
Function GetFolderPath() As String
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show <> 0 Then GetFolderPath = .SelectedItems(1)
End With
End Function
Related
I am trying to Loop through all files and sub folders but my code is just works for single folder.
I want to apply this code on all Folders and subfolder which have workbooks.
Any help will be appreciated.
Sub KeepColor()
Dim strFolder As String
Dim strFile As String
Dim wbk As Workbook
Dim wsh As Worksheet
Dim I As Long
Dim xRg As Range
With Application.FileDialog(4)
If .Show Then
strFolder = .SelectedItems(1)
Else
MsgBox "You 't selected a folder!", vbExclamation
Exit Sub
End If
End With
If Right(strFolder, 1) <> "\" Then
strFolder = strFolder & "\"
End If
Application.ScreenUpdating = FALSE
strFile = Dir(strFolder & "*.xls*")
Do While strFile <> ""
Set wbk = Workbooks.Open(strFolder & strFile)
For Each wsh In wbk.Worksheets
For Each xRg In wsh.UsedRange
If xRg.DisplayFormat.Interior.ColorIndex = xlColorIndexNone Then
xRg.Interior.ColorIndex = xlColorIndexNone
Else
xRg.Interior.Color = xRg.DisplayFormat.Interior.Color
End If
Next xRg
wsh.UsedRange.FormatConditions.Delete
Next wsh
wbk.Close SaveChanges:=True
strFile = Dir
Loop
Application.ScreenUpdating = TRUE
End Sub
Dir is much faster than FileSystemObject if you have a filename pattern, so here's a function which mixes both:
Sub Tester()
Dim col As Collection, t
t = Timer
Set col = GetMatches("C:\Tester", "*.xls*")
Debug.Print Timer - t, col.Count
End Sub
'Return a collection of file objects given a starting folder and a file pattern
' e.g. "*.txt"
'Pass False for last parameter if don't want to check subfolders
Function GetMatches(startFolder As String, filePattern As String, _
Optional subFolders As Boolean = True) As Collection
Dim fso, fldr, f, subFldr, fpath
Dim colFiles As New Collection
Dim colSub As New Collection
Set fso = CreateObject("scripting.filesystemobject")
colSub.Add startFolder
Do While colSub.Count > 0
Set fldr = fso.getfolder(colSub(1))
colSub.Remove 1
If subFolders Then
For Each subFldr In fldr.subFolders
colSub.Add subFldr.Path
Next subFldr
End If
'this is faster...
fpath = fldr.Path
If Right(fpath, 1) <> "\" Then fpath = fpath & "\"
f = Dir(fpath & filePattern)
Do While Len(f) > 0
colFiles.Add fso.getfile(fpath & f)
f = Dir()
Loop
'this is slower...
'For Each f In fldr.Files
' If UCase(f.Name) Like filePattern Then colFiles.Add f
'Next f
Loop
Set GetMatches = colFiles
End Function
Please, try the next code:
Sub KeepColor()
Dim strFolder As String, fso As Object, parentFolder As Object, folder As Object
With Application.FileDialog(4)
If .Show Then
strFolder = .SelectedItems(1)
Else
MsgBox "You didn't select a folder!", vbExclamation
Exit Sub
End If
End With
Set fso = CreateObject("scripting.filesystemobject")
Set parentFolder = fso.GetFolder(strFolder)
Application.ScreenUpdating = False
ProcessAllFiles parentFolder, "xls*"
For Each folder In parentFolder.SubFolders
ProcessAllFiles folder, "xls*"
Next
Application.ScreenUpdating = True
End Sub
Sub ProcessAllFiles(strFold As Object, fileExt As String)
Dim fso As Object, objFile As Object, xRg As Range, wbk As Workbook, wsh As Worksheet
Set fso = CreateObject("scripting.filesystemobject")
For Each objFile In strFold.files
If fso.GetExtensionName(objFile.Name) Like fileExt Then
Set wbk = Workbooks.Open(objFile.path)
For Each wsh In wbk.Worksheets
For Each xRg In wsh.UsedRange
If xRg.DisplayFormat.Interior.ColorIndex = xlColorIndexNone Then
xRg.Interior.ColorIndex = xlColorIndexNone
Else
xRg.Interior.color = xRg.DisplayFormat.Interior.color
End If
Next xRg
wsh.UsedRange.FormatConditions.Delete
Next wsh
wbk.Close SaveChanges:=True
End If
Next
End Sub
This is a recursion job.
I am using a generic function, that returns a collection of all files (could be changed to array as well) - either for the folder or for all subfolders.
You need to add a reference to "Microsoft Scripting runtime"
Option Explicit
Sub testFindAllFiles()
Dim strFolder As String: strFolder = "XXXX" 'adjust to your needs
Dim colFiles As Collection
Set colFiles = findAllFilesByExtension(strFolder, "xls*", True)
Dim strFile As Variant
For Each strFile In colFiles
Debug.Print strFile
'do what you need with the file
Next
End Sub
Public Function findAllFilesByExtension(ByVal targetFolder As String, ByVal extension As String, _
Optional fWithSubfolders As Boolean = True) As Collection
Dim fso As FileSystemObject: Set fso = New FileSystemObject
Dim colFiles As Collection: Set colFiles = New Collection
findFilesByExtension targetFolder, colFiles, extension, fso, fWithSubfolders
Set findAllFilesByExtension = colFiles
End Function
Private Sub findFilesByExtension(ByVal targetFolder As String, ByRef colFiles As Collection, _
extension As String, fso As FileSystemObject, fWithSubfolders As Boolean)
Dim objFolder As Folder, objFile As File
Dim subFolders As Folders
Set objFolder = fso.GetFolder(targetFolder)
For Each objFile In objFolder.Files
If Not objFile.Name Like "~*" Then
If objFile.Name Like "*." & extension Then
colFiles.Add objFile.Path
End If
End If
Next
If fWithSubfolders = True Then
Set subFolders = objFolder.subFolders
For Each objFolder In subFolders
findFilesByExtension objFolder.Path, colFiles, extension, fso, fWithSubfolders
Next
End If
End Sub
I need to open a specified workbook using a text box entry and using a list command to open it.
I used a cell value before and it worked but I would like to use a textbox value to make it easier for the operator.
So when I click on the listbox value it takes the textbox value then finds the workbook and opens it
I`ve also asked Mr. Excel see below
https://www.mrexcel.com/board/threads/opening-workbook-from-user-form.1161913/
Private Sub Worksheet_Change(ByVal Target As Object)
If Target.Me.Jobcard_Demands = ("Open Old JobCard") Then
Me.Old_JobCard_No.Value
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Object)
Dim PID As Double
Dim strRootPath As String
Dim objFile As Scripting.File
Dim wb As Workbook
Dim myfilename As String
Dim Test As String
Dim objFSO As Scripting.FileSystemObject
Dim objFolder As Scripting.Folder
If Target.Me.Jobcard_Demands = ("Open Old JobCard") Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("\\TGS-SRV01\Share\ShopFloor\PRODUCTION\JOB CARDS\1 - ARCHIVED JOB CARDS\" & Int((ActiveSheet.Range("C1") - 1) / 50) * 50 + 1 & "-" & Int((ActiveSheet.Range("C1") - 1) / 50 + 1) * 50 & "\" & ActiveSheet.Range("C1"))
For Each objFile In objFolder.Files
If Left(objFile.Name, 5) = CStr(ActiveSheet.Range("C1")) And Right(objFile.Name, 4) = "xlsm" Then
myfilename = objFile.Path
End If
Next objFile
Set wb = Workbooks.Open(myfilename)
End If
End Sub
Private Sub JobCardOpen(ByVal Target As Object)
Dim objFile As Scripting.File
Dim wb As Workbook
Dim myfilename As String
Dim objFSO As Scripting.FileSystemObject
Dim objFolder As Scripting.Folder
If Target.Me.Jobcard_Demands = ("Open Old JobCard") Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("\\TGS-SRV01\Share\ShopFloor\PRODUCTION\JOB CARDS\1 - ARCHIVED JOB CARDS\" & Int((ActiveSheet.Range("C1") - 1) / 50) * 50 + 1 & "-" & Int((ActiveSheet.Range("C1") - 1) / 50 + 1) * 50 & "\" & ActiveSheet.Range("C1"))
For Each objFile In objFolder.Files
If Left(objFile.Name, 5) = ActiveSheet.Range("C1") Then
myfilename = objFile.Path & objFile.Name
End If
Next objFile
Set wb = Workbooks.Open(myfilename)
End Sub
I don't understand what you are using the Worksheet_Change and Worksheet_SelectionChange events for, I would suggest using a button to trigger the event and an InputBox for the user to enter the number.
Option Explicit
Sub JobCardOpen() ' assign to button
Dim wb As Workbook, jobno As Long
jobno = InputBox("Enter Job No")
Set wb = OpenJobCard(jobno)
' process wb
If wb Is Nothing Then
Else
MsgBox wb.Name & " workbook is open", vbInformation
wb.Close
End If
End Sub
Function OpenJobCard(jobno As Long) As Workbook
Const ROOT = "\\TGS-SRV01\Share\ShopFloor\PRODUCTION\JOB CARDS\1 - ARCHIVED JOB CARDS\"
Dim objFSO, objFolder, objFile
Dim n As Long, sFolderName As String, bFound As Boolean
n = 50 * Int((jobno - 1) / 50)
sFolderName = ROOT & CStr(n + 1) & "-" & CStr(n + 50) & "\" & CStr(jobno)
Set objFSO = CreateObject("Scripting.FileSystemObject")
' check folder exists
If objFSO.FolderExists(sFolderName) Then
Set objFolder = objFSO.GetFolder(sFolderName)
Else
MsgBox sFolderName & "\ not found", vbCritical, "Folder not found"
Exit Function
End If
bFound = False
For Each objFile In objFolder.Files
If objFile.Name Like CStr(jobno) & "*.xlsm" Then
Set OpenJobCard = Workbooks.Open(objFile.Path)
bFound = True
End If
Next objFile
If bFound = False Then
MsgBox "No File found in " & sFolderName, vbCritical, "File not found"
Exit Function
End If
End Function
I want to select where to save the PDFs instead of saving them to the folder where the excel files live.
I also want to only print the first worksheet.
The Dims ending with a 2 is what I added to try and make this work. I get both pop ups to appear but after I select where I want to save the PDFs then it fails at Set objFolder2 = objFileSystem2.GetFolder(strPath2)
Any help is much appreciated.
Sub ExcelPlot()
Dim objShell As Object
Dim objWindowsFolder As Object
Dim objWindowsFolder2 As Object
Dim strWindowsFolder As String
'Select the specific Windows folder
Set objShell = CreateObject("Shell.Application")
Set objWindowsFolder = objShell.BrowseForFolder(0, "Locate the Excel files", 0, "")
'Select where to save to
Set objShell = CreateObject("Shell.Application")
Set objWindowsFolder2 = objShell.BrowseForFolder(0, "Where would you like to save the PDFs?", 0, "")
If Not objWindowsFolder Is Nothing Then
strWindowsFolder = objWindowsFolder.self.Path & "\"
Call ProcessFolders(strWindowsFolder)
'Open the windows folder
Shell "Explorer.exe" & " " & strWindowsFolder, vbNormalFocus
End If
End Sub
Sub ProcessFolders(strPath As String)
Dim strPath2 As String
Dim objFileSystem As Object
Dim objFileSystem2 As Object
Dim objFolder As Object
Dim objFolder2 As Object
Dim objFile As Object
Dim objExcelFile As Object
Dim objWorkbook As Excel.Workbook
Dim strWorkbookName As String
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFileSystem.GetFolder(strPath)
Set objFolder2 = objFileSystem2.GetFolder(strPath2)
For Each objFile In objFolder.Files
strFileExtension = objFileSystem.GetExtensionName(objFile)
If LCase(strFileExtension) = "xls" Or LCase(strFileExtension) = "xlsx" Then
Set objExcelFile = objFile
Set objWorkbook = Application.Workbooks.Open(objExcelFile.Path)
strWorkbookName = Left(objWorkbook.Name, (Len(objWorkbook.Name) - Len(strFileExtension)) - 1)
objWorkbook.ExportAsFixedFormat Type:=xlTypePDF, fileName:=strPath2 & strWorkbookName & ".pdf"
objWorkbook.Close False
End If
Next
'Process all folders and subfolders
If objFolder.SubFolders.Count > 0 Then
For Each objSubFolder In objFolder.SubFolders
If ((objSubFolder.Attributes And 2) = 0) And ((objSubFolder.Attributes And 4) = 0) Then
ProcessFolders (objSubFolder.Path)
End If
Next
End If
End Sub
Thanks
You can do something like this - you need to pass both of the paths to ProcessFolders
Sub ExcelPlot()
Dim sourceFolder As String, destFolder As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Title = "Locate the Excel files"
If .Show = -1 Then
sourceFolder = .SelectedItems(1)
.Title = "Where would you like to save the PDFs?"
If .Show = -1 Then
destFolder = .SelectedItems(1)
ProcessFolders sourceFolder, destFolder
Shell "Explorer.exe" & " " & destFolder, vbNormalFocus
End If
End If
End With
End Sub
EDIT: Here's an updated (non-recursive) version of your folder processing sub:
Sub ProcessFolders(sourceFolder As String, destFolder As String)
Dim objFileSystem As Object
Dim objFolder As Object
Dim objSubFolder As Object
Dim objFile As Object
Dim objWorkbook As Excel.Workbook
Dim strWorkbookName As String, strFileExtension As String
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Dim colFolders As New Collection
colFolders.Add sourceFolder
Do While colFolders.Count > 0
Set objFolder = objFileSystem.GetFolder(colFolders(1)) 'get the first path
colFolders.Remove 1 'remove from listing
'Process files in this folder
For Each objFile In objFolder.Files
strFileExtension = objFileSystem.GetExtensionName(objFile)
If LCase(strFileExtension) = "xls" Or LCase(strFileExtension) = "xlsx" Then
Set objWorkbook = Application.Workbooks.Open(objFile.Path)
strWorkbookName = Left(objWorkbook.Name, _
(Len(objWorkbook.Name) - Len(strFileExtension)) - 1)
objWorkbook.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=objFileSystem.buildpath(destFolder, strWorkbookName & ".pdf")
objWorkbook.Close False
End If
Next
'Process subfolders
For Each objSubFolder In objFolder.SubFolders
If ((objSubFolder.Attributes And 2) = 0) And ((objSubFolder.Attributes And 4) = 0) Then
colFolders.Add objSubFolder.Path 'add this to the collection for processing
End If
Next
Loop
End Sub
This question already has answers here:
Get list of sub-directories in VBA
(5 answers)
Closed 2 years ago.
I have a folder where I have many sub-folders and inside of them more than 1000 Excel files.
I want to run a specific macro (that changes a workbook) on all these files.
Already saw the following answer.
Sub ProcessFiles()
Dim Filename, Pathname As String
Dim wb As Workbook
Pathname = ActiveWorkbook.Path & "\C:\...\EXCL\"
Filename = Dir(Pathname & "*.xlsx")
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & Filename)
DoWork wb
wb.Close SaveChanges:=True
Filename = Dir()
Loop
End Sub
Sub DoWork(wb As Workbook)
With wb
'Do your work here
......
End With
End Sub
There are two problems:
1. this will be extremely slow. Is there a faster way?
2. this will only run on the files in the matching folder and not the files in all sub-folders. Is there way to do that for files in sub-folders as well?
As far as I know, VBA can't edit closet workbook. If you want to do work for every workbook in every subfolder, subfolder of subfolder etc. you can use the following code. I added condition, that it have to be .xlsx file, you can change it on .xls, .xlsb or whatever you want.
Sub ProcessFiles()
Dim objFolder As Object
Dim objFile As Object
Dim objFSO As Object
Dim MyPath As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo EmptyEnd
MyPath = .SelectedItems(1)
End With
Application.ScreenUpdating = False
Set objFSO = CreateObject("Scripting.FileSystemObject")
Call GetAllFiles(MyPath, objFSO)
Call GetAllFolders(MyPath, objFSO)
Application.ScreenUpdating = True
MsgBox "Complete."
EmptyEnd:
End Sub
Sub GetAllFiles(ByVal strPath As String, ByRef objFSO As Object)
Dim objFolder As Object
Dim objFile As Object
Set objFolder = objFSO.GetFolder(strPath)
For Each objFile In objFolder.Files
DoWork objFile.Path
Next objFile
End Sub
Sub GetAllFolders(ByVal strFolder As String, ByRef objFSO As Object)
Dim objFolder As Object
Dim objSubFolder As Object
Set objFolder = objFSO.GetFolder(strFolder)
For Each objSubFolder In objFolder.subfolders
Call GetAllFiles(objSubFolder.Path, objFSO)
Call GetAllFolders(objSubFolder.Path, objFSO)
Next objSubFolder
End Sub
Sub DoWork(strFile As String)
Dim wb As Workbook
If Right(strFile, 4) = "xlsx" Then
Set wb = Workbooks.Open(Filename:=strFile)
With wb
'Do your work here
......
.Close True
End With
End If
End Sub
If I get this right you need a function which collects all xl files in a directory and subdirs. This function will do that:
Public Function RecursiveDir(colFiles As Collection, _
strFolder As String, _
strFileSpec As String, _
bIncludeSubfolders As Boolean)
Dim strTemp As String
Dim colFolders As New Collection
Dim vFolderName As Variant
'Add files in strFolder matching strFileSpec to colFiles
strFolder = TrailingSlash(strFolder)
strTemp = Dir(strFolder & strFileSpec)
Do While strTemp <> vbNullString
colFiles.Add strFolder & strTemp
strTemp = Dir
Loop
If bIncludeSubfolders Then
'Fill colFolders with list of subdirectories of strFolder
strTemp = Dir(strFolder, vbDirectory)
Do While strTemp <> vbNullString
If (strTemp <> ".") And (strTemp <> "..") Then
If (GetAttr(strFolder & strTemp) And vbDirectory) <> 0 Then
colFolders.Add strTemp
End If
End If
strTemp = Dir
Loop
'Call RecursiveDir for each subfolder in colFolders
For Each vFolderName In colFolders
Call RecursiveDir(colFiles, strFolder & vFolderName, strFileSpec, True)
Next vFolderName
End If
End Function
Public Function TrailingSlash(strFolder As String) As String
If Len(strFolder) > 0 Then
If Right(strFolder, 1) = "\" Then
TrailingSlash = strFolder
Else
TrailingSlash = strFolder & "\"
End If
End If
End Function
And this shows how to use it
Sub TesterFiles()
Dim colFiles As New Collection
RecursiveDir colFiles, "Your Dir goes here...", "*.XLS*", True
Dim vFile As Variant
For Each vFile In colFiles
' Do sth with the file
Debug.Print vFile
Next vFile
End Sub
Nice one Storax! I would use the script that Storax posted, and modify it just a tad.
i = 1
Dim vFile As Variant
For Each vFile In colFiles
' Do sth with the file
Range("A" & i).Value = vFile
i = i + 1
Next vFile
I think it's just easier to work with a list. Anyway, once you have the file structure, you can run through those elements in the array you just created. Use the script below to do that.
Sub LoopThroughRange()
Dim rng As Range, cell As Range
Set rng = Range("A1:A13")
For Each cell In rng
'For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(cell)
On Error GoTo 0
If Not mybook Is Nothing Then
'Change cell value(s) in one worksheet in mybook
On Error Resume Next
With mybook.Worksheets(1)
If .ProtectContents = False Then
.Range("A1").Value = "My New Header"
Else
ErrorYes = True
End If
End With
If Err.Number > 0 Then
ErrorYes = True
Err.Clear
'Close mybook without saving
mybook.Close savechanges:=False
Else
'Save and close mybook
mybook.Close savechanges:=True
End If
On Error GoTo 0
Else
'Not possible to open the workbook
ErrorYes = True
End If
'Next Fnum
Next cell
End Sub
The idea comes straight from here.
http://www.rondebruin.nl/win/s3/win010.htm
Pay attention to this part:
'Change cell value(s) in one worksheet in mybook
That's where you want to put specific your code to do exactly what you want to do.
I just modified my OP. It's a lot easier, and a little different, than I initially made it out to be. I've adjusted the script accordingly.
I have a ton of files that have a common string in the name "mch". Within one folder there are hundreds of subfolders named with this common string, then within those there are 5 pictures named similar; example picfront1234mch. I need to get rid of the mch at the end of all the names of picture files and the folders they are in. I was attempting a couple different examples from the web but non to work. I wrote this code to find the file names in the subfolders and to delete the last 3 characters of the name but its deleting the extensions instead. I have used the move/copy/ rename method in the past but I lost some of my old code and can’t figure out how use it again. Any suggestions on how to do this better?
Code ive been trying
Option Explicit
Sub ListFiles()
'Declare the variables
Dim objFSO As Scripting.FileSystemObject
Dim objTopFolder As Scripting.Folder
Dim strTopFolderName As String
'Assign the top folder to a variable
strTopFolderName = "C:\Users\aholiday\Desktop\Test"
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the top folder
Set objTopFolder = objFSO.GetFolder(strTopFolderName)
'Call the RecursiveFolder routine
Call RecursiveFolder(objTopFolder, True)
End Sub
Sub RecursiveFolder(objFolder As Scripting.Folder, IncludeSubFolders As Boolean)
'Declare the variables
Dim objFile As Scripting.File
Dim objSubFolder As Scripting.Folder
Dim str As String
Debug.Print Now
Application.SendKeys "^g ^a {DEL}"
Application.ScreenUpdating = False
'Loop through each folder in the Topfolder
For Each objFile In objFolder.Files
str = objFile.Name
Debug.Print str
'delete last 3 chara of string
str = Left(str, Len(str) - 3)
Debug.Print str
Next objFile
If IncludeSubFolders Then
For Each objSubFolder In objFolder.SubFolders
Call RecursiveFolder(objSubFolder, True)
Next objSubFolder
End If
Application.ScreenUpdating = True
End Sub
Usage:
RemoveTextFromFileName "mch", "I:\stackoverflow\temp"
Sub RemoveTextFromFileName(txt As String, FolderName As String)
Dim file
If Not Right(FolderName, 1) = "\" Then FolderName = FolderName & "\"
file = Dir(FolderName)
While (file "")
If InStr(file, txt) > 0 Then
FileCopy FolderName & file, FolderName & Replace(file, txt, "")
Kill FolderName & file
End If
file = Dir
Wend
End Sub
Update: Remove string from folder, sub folders, and file names.
These functions will recursively search the root folder and all it's subfolders to rename files and folders.
Usage:
Public Sub ProcessFoldersAndFiles()
ReplaceStringFileNames "C:\Data Files\mch files\", "mch"
ReplaceStringDirectories"C:\Data Files\mch files\", "mch"
End Sub
Here are the functions:
Sub ReplaceStringDirectories(FolderPath As String, SearchString As String, Optional ReplacementString As String = "", Optional fso As Object)
Dim fld, thisFolder
Dim NewName As String, PathOnly As String
If fso Is Nothing Then
Set fso = CreateObject("Scripting.FileSystemObject")
End If
Set thisFolder = fso.getFolder(FolderPath)
For Each fld In thisFolder.Subfolders
ReplaceStringDirectories fld.Path, SearchString, ReplacementString
Next
If InStr(thisFolder.Name, SearchString) Then
NewName = Replace(thisFolder.Name, SearchString, ReplacementString, , , vbTextCompare)
PathOnly = Left(thisFolder.Path, InStrRev(thisFolder.Path, "\"))
Do Until Not fso.FolderExists(PathOnly & NewName)
NewName = "_" & NewName
Loop
thisFolder.Name = NewName
End If
End Sub
Sub ReplaceStringFileNames(FolderPath As String, SearchString As String, Optional ReplacementString As String = "", Optional fso As Object)
Dim f, fld, thisFolder
Dim NewName As String, PathOnly As String
If fso Is Nothing Then
Set fso = CreateObject("Scripting.FileSystemObject")
End If
Set thisFolder = fso.getFolder(FolderPath)
For Each fld In thisFolder.Subfolders
ReplaceStringFileNames fld.Path, SearchString, ReplacementString
Next
For Each f In thisFolder.Files
If InStr(f.Name, SearchString) Then
NewName = Replace(f.Name, SearchString, ReplacementString, , , vbTextCompare)
PathOnly = Left(f.Path, InStrRev(thisFolder.Path, "\"))
Do Until Not fso.FolderExists(PathOnly & NewName)
NewName = "_" & NewName
Loop
f.Name = NewName
End If
Next
End Sub