Check existing sheet in each checking excel file - excel

function in this macro checking only opened excel for exsiting Sheet "economy" , but i need to check for exsisting this Sheet in each excel file i checking in folder and subfolders.
How i can edit this to check sheet name in not current macro excel file but in all files that i opened in sub "ListFilesInFolder"?
Sub MainList()
Set folder = Application.FileDialog(msoFileDialogFolderPicker)
If folder.Show <> -1 Then Exit Sub
xDir = folder.SelectedItems(1)
Call ListFilesInFolder(xDir, True)
End Sub
Function WorksheetExists(shtName As String, Optional wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
WorksheetExists = Not sht Is Nothing
End Function
Sub ListFilesInFolder(ByVal xFolderName As String, ByVal xIsSubfolders As Boolean)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim rowIndex As Long
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
rowIndex = Application.ActiveSheet.Range("A65536").End(xlUp).Row + 1
For Each xFile In xFolder.Files
If WorksheetExists("economy") = True Then
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
Application.ActiveSheet.Cells(rowIndex, 2).Formula = xFile.Path
Application.ActiveSheet.Cells(rowIndex, 3).Formula = "Есть"
Else
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
Application.ActiveSheet.Cells(rowIndex, 2).Formula = xFile.Path
Application.ActiveSheet.Cells(rowIndex, 3).Formula = "Нет"
rowIndex = rowIndex + 1
End If
Next xFile
If xIsSubfolders Then
For Each xSubFolder In xFolder.SubFolders
ListFilesInFolder xSubFolder.Path, True
Next xSubFolder
End If
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
End Sub
Function GetFileOwner(ByVal xPath As String, ByVal xName As String)
Dim xFolder As Object
Dim xFolderItem As Object
Dim xShell As Object
xName = StrConv(xName, vbUnicode)
xPath = StrConv(xPath, vbUnicode)
Set xShell = CreateObject("Shell.Application")
Set xFolder = xShell.Namespace(StrConv(xPath, vbFromUnicode))
If Not xFolder Is Nothing Then
Set xFolderItem = xFolder.ParseName(StrConv(xName, vbFromUnicode))
End If
If Not xFolderItem Is Nothing Then
GetFileOwner = xFolder.GetDetailsOf(xFolderItem, 8)
Else
GetFileOwner = ""
End If
Set xShell = Nothing
Set xFolder = Nothing
Set xFolderItem = Nothing
End Function
Thank you

I'd recommend to use Option explicit but leave that to you. I tweaked your code like that
Sub ListFilesInFolder(ByVal xFolderName As String, ByVal xIsSubfolders As Boolean)
Dim xFileSystemObject As Object
Dim xFolder As Object
Dim xSubFolder As Object
Dim xFile As Object
Dim rowIndex As Long
Set xFileSystemObject = CreateObject("Scripting.FileSystemObject")
Set xFolder = xFileSystemObject.GetFolder(xFolderName)
rowIndex = Application.ActiveSheet.Range("A65536").End(xlUp).Row + 1
For Each xFile In xFolder.Files
If HasSheet(xFile.ParentFolder & "\", xFile.Name, "economy") Then
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
Application.ActiveSheet.Cells(rowIndex, 2).Formula = xFile.path
Application.ActiveSheet.Cells(rowIndex, 3).Formula = "Sheet exists"
Else
Application.ActiveSheet.Cells(rowIndex, 1).Formula = xFile.Name
Application.ActiveSheet.Cells(rowIndex, 2).Formula = xFile.path
Application.ActiveSheet.Cells(rowIndex, 3).Formula = "Sheet does not exist"
End If
rowIndex = rowIndex + 1
Next xFile
If xIsSubfolders Then
For Each xSubFolder In xFolder.SubFolders
ListFilesInFolder xSubFolder.path, True
Next xSubFolder
End If
Set xFile = Nothing
Set xFolder = Nothing
Set xFileSystemObject = Nothing
End Sub
Note that I moved the line rowIndex = rowIndex + 1out of the ifcondition and I use another function for checking if the workbook in question contains the worksheet you are looking for. The reason is that I want to avoid to open the workbook with Workbooks.open which could lead to trouble as Auto_open code would run.
Here is the function HasSheet I used
Function HasSheet(fPath As String, fName As String, sheetName As String) As Boolean
Dim f As String
Dim res As Variant
On Error GoTo EH
f = "'" & fPath & "[" & fName & "]" & sheetName & "'!R1C1"
res = ExecuteExcel4Macro(f)
If IsError(res) Then
HasSheet = False
Else
HasSheet = True
End If
Exit Function
EH:
HasSheet = False
End Function
Function HasSheet is based on this answer

Related

VBA Optional Arguments - Return PDF Name When It Contains Certain Text?

I am currently trying to write VBA code that looks through a folder for a document and then returns the name of that document when it is found. I've scoured the internet and can't find much. I am doing this by using a code for returning existence and trying to add optional arguments to then use a function to return the file name.
The original code for the test of existence is:
Private Sub tester()
Dim FSO As Object, FolDir As Object, FileNm As Object, LastRow As Integer
Dim Flag As Boolean, WS As Worksheet, Cnt As Integer
Set FSO = CreateObject("scripting.filesystemobject")
Set FolDir = FSO.GetFolder("FILE PATH")
Set WS = Sheets("SHEET NAME")
With WS
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
For Cnt = 1 To LastRow
Flag = False
For Each FileNm In FolDir.Files
If FileNm.Name Like "*" & ".pdf" Then
If InStr(FileNm.Name, CStr(WS.Cells(Cnt, "A"))) Then
WS.Cells(Cnt, "B") = "YES"
Flag = True
Exit For
End If
End If
Next FileNm
If Not Flag Then
WS.Cells(Cnt, "B") = "NO"
End If
Next Cnt
Set FolDir = Nothing
Set FSO = Nothing
End Sub
It works perfectly well. I then tried some optional arguments but I can't figure out how to adapt this and I don't think I really understand how optional arguments work. Right now I have:
Private Function GetPdfName( _
ByRef File As String, _
Optional ByRef Flag As Variant) As String
Dim FSO As Object, FolDir As Object, FileNm As Object, LastRow As Integer
Dim Flag As Boolean, WS As Worksheet, Cnt As Integer
Set FolDir = FSO.GetFolder("FILE PATH")
Dim FileName As String
Dim FSO As New FileSystemObject
Set FSO = CreateObject("scripting.filesystemobject")
Flag = False
Set WS = Sheets("sheet4")
For Each FileNm In FolDir.Files
If FileNm.Name Like "*" & ".pdf" Then
If InStr(FileNm.Name, CStr(WS.Cells(Cnt, "A"))) Then
WS.Cells(Cnt, "B") = FileName
Flag = True
Exit For
End If
End If
Next FileNm
If Not Flag Then
WS.Cells(Cnt, "B") = "NO"
End If
Next Cnt
Set FolDir = Nothing
Set FSO = Nothing
FileName = FSO.GetFileName("FILE PATH")
End Function
Private Sub FSOGetFileName()
GetPdfName( _
With WS
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
For Cnt = 1 To LastRow)
End Sub
The Sub is returning an error on expected expression and I can't figure out how to fix this. Can someone please help me or explain optional arguments and how to best format them in code?
Not sure what optional parameter you need. Only 2 parameters are required, the folder to search and the target range for the results.
Option Explicit
Sub tester()
Const FILE_PATH = "c:\temp\"
Const SHEET_NAME = "Sheet1"
Dim FSO As Object, FolDir As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FolDir = FSO.GetFolder(FILE_PATH)
Dim ws As Worksheet, r As Long, lastrow As Long
Set ws = Sheets(SHEET_NAME)
With ws
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
For r = 1 To lastrow
Call GetPdfName(FolDir, .Cells(r, "A"))
Next
End With
End Sub
Function GetPdfName(oFolder As Object, rng As Range)
Dim oFile As Object, fname As String, s As String
For Each oFile In oFolder.Files
fname = oFile.Name
If fname Like "*.pdf" Then
s = Left(fname, Len(fname) - 4) ' remove .pdf
If InStr(1, s, CStr(rng), vbTextCompare) Then
rng.Offset(0, 1) = oFile.Name
rng.Offset(0, 2) = True
Exit Function
End If
End If
Next
rng.Offset(0, 1) = ""
rng.Offset(0, 2) = False
End Function
for 2 criteria
Function GetPdfName2(oFolder As Object, rng As Range)
Dim oFile As Object, fname As String, s As String
For Each oFile In oFolder.Files
fname = oFile.Name
If fname Like "*.pdf" Then
s = Left(fname, Len(fname) - 4) ' remove .pdf
If InStr(1, s, CStr(rng), vbTextCompare) or _
InStr(1, s, CStr(rng.offset(0,1)), vbTextCompare) Then
rng.Offset(0, 2) = oFile.Name
rng.Offset(0, 3) = True
Exit Function
End If
End If
Next
rng.Offset(0, 2) = ""
rng.Offset(0, 3) = False
End Function

quickly search value for multiple workbooks with specified sheets

Following the question:
VBA Excel - search multipe terms in workbooks with values matching to them
I would like to make a search for multiple workbooks across the directory, but with specified, repeatable sheets.
The full code:
Sub SearchFolders()
Dim xFso As Object
Dim xFld As Object
Dim xStrSearch As String
Dim xStrPath As String
Dim xStrFile As String
Dim xOut As Worksheet
Dim xWb As Workbook
Dim xWk As Worksheet
Dim xRow As Long
Dim xCol As Long
Dim i As Long
Dim xFound As Range
Dim xStrAddress As String
Dim xFileDialog As FileDialog
Dim xUpdate As Boolean
Dim xCount As Long
Dim xAWB As Workbook
Dim xAWBStrPath As String
Dim xBol As Boolean
Set xAWB = ActiveWorkbook
'Set xWk = ActiveWorkbook.Worksheets("Civils*")
xAWBStrPath = xAWB.Path & "\" & xAWB.Name
On Error GoTo ErrHandler
Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
xFileDialog.AllowMultiSelect = False
xFileDialog.Title = "Select a folder"
If xFileDialog.Show = -1 Then
xStrPath = xFileDialog.SelectedItems(1)
End If
If xStrPath = "" Then Exit Sub
'xStrSearch = "1366P"
xStrSearch = InputBox("Please provide the BoM Code")
xUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
Set xOut = Worksheets("SUMMARY")
xRow = 1
With xOut
.Cells(xRow, 1) = "Workbook"
.Cells(xRow, 2) = "Worksheet"
.Cells(xRow, 3) = "Cell"
.Cells(xRow, 4) = "Text in Cell"
.Cells(xRow, 5) = "Values corresponding"
Set xFso = CreateObject("Scripting.FileSystemObject")
Set xFld = xFso.GetFolder(xStrPath)
xStrFile = Dir(xStrPath & "\*.xls*")
Do While xStrFile <> ""
xBol = False
If (xStrPath & "\" & xStrFile) = xAWBStrPath Then
xBol = True
Set xWb = xAWB
Else
Set xWb = Workbooks.Open(Filename:=xStrPath & "\" & xStrFile, UpdateLinks:=0, ReadOnly:=True, AddToMRU:=False)
'Set xWk = Worksheets.Open("Civils Job Order")
End If
'For Each xWk In xWb.Worksheets("Civils Work Order")
For Each xWk In xWb.Worksheets
If xBol And (xWk.Name = .Name) Then
'If xBol And (xWk.Name = "Civils Work Order" Or xWk.Name = "Cable Works Order") Then
Else
Set xFound = xWk.UsedRange.Find(xStrSearch)
If Not xFound Is Nothing Then
xStrAddress = xFound.Address
End If
Do
If xFound Is Nothing Then
Exit Do
Else
xCount = xCount + 1
xRow = xRow + 1
.Cells(xRow, 1) = xWb.Name
.Cells(xRow, 2) = xWk.Name
.Cells(xRow, 3) = xFound.Address
.Cells(xRow, 4) = xFound.Value
.Cells(xRow, 5).Range("A1").Value = xFound.EntireRow.Range("F1").Value
End If
Set xFound = xWk.Cells.FindNext(After:=xFound)
Loop While xStrAddress <> xFound.Address
End If
Next
If Not xBol Then
xWb.Close (False)
End If
xStrFile = Dir
Loop
.Columns("A:E").EntireColumn.AutoFit
End With
MsgBox xCount & " cells have been found", , "BoM Calculator for VM Greenfield"
ExitHandler:
Set xOut = Nothing
Set xWk = Nothing
Set xWb = Nothing
Set xFld = Nothing
Set xFso = Nothing
Application.ScreenUpdating = xUpdate
Exit Sub
ErrHandler:
MsgBox Err.Description, vbExclamation
Resume ExitHandler
End Sub
There is no error coming in, but the Excel is frozen indefinitely.
Is it some solution for making this kind of search for the specified worksheet names, which occur regularly across all workbooks in the directory?
This is a bit lengthy, but a lot of the bulk is re-useable functions, so it lets you focus on the logic in the main method.
I'm guessing that the summary sheet is in the same workbook as this code, and that you're scanning a folder for files to summarize, one of which may already be open in Excel (so you don't want to open that again).
Compiles but not tested...
Sub SearchFolders()
Dim wbAct As Workbook, pathMainWb As String, fldrPath As String
Dim bom As String, scrUpdt, wsOut As Worksheet, colFiles As Collection, f As Object
Dim xBol As Boolean, wb As Workbook, ws As Worksheet, arrWs
Dim matchedCells As Collection, cell, numHits As Long, summRow As Long
Set wbAct = ActiveWorkbook
pathMainWb = wbAct.FullName '<<<<
On Error GoTo ErrHandler
fldrPath = UserSelectFolder("Select a folder")
If Len(fldrPath) = 0 Then Exit Sub
'get all files in the selected folder
Set colFiles = GetFileMatches(fldrPath, "*.xls*", False) 'False=no subfolders
If colFiles.Count = 0 Then
MsgBox "No Excel files found in selected folder"
Exit Sub
End If
bom = InputBox("Please provide the BoM Code")
scrUpdt = Application.ScreenUpdating
Application.ScreenUpdating = False
Set wsOut = ThisWorkbook.Worksheets("SUMMARY")
summRow = 1
'sheet names to scan
arrWs = Array("Civils Job Order", "Civils Work Order", "Cable Works Order")
wsOut.Cells(summRow, 1).Resize(1, 5).Value = Array("Workbook", "Worksheet", _
"Cell", "Text in Cell", "Values corresponding")
For Each f In colFiles
xBol = (f.Path = pathMainWb) 'file already open?
If xBol Then
Set wb = wbAct
Else
Set wb = Workbooks.Open(Filename:=f.Path, UpdateLinks:=0, _
ReadOnly:=True, AddToMRU:=False)
End If
For Each ws In wb.Worksheets
'are we interested in this sheet?
If Not IsError(Application.Match(ws.Name, arrWs, 0)) Then
Set matchedCells = FindAll(ws.UsedRange, bom) 'get all cells with bom
If matchedCells.Count > 0 Then
For Each cell In matchedCells
summRow = summRow + 1
wsOut.Cells(summRow, 1).Resize(1, 5).Value = _
Array(wb.Name, ws.Name, cell.Address, cell.Value, _
cell.EntireRow.Range("F1").Value)
numHits = numHits + 1
Next cell 'next match
End If 'any bom matches
End If 'matched sheet name
Next ws
If Not xBol Then wb.Close False 'need to close this workbook?
Next f
wsOut.Columns("A:E").EntireColumn.AutoFit
MsgBox numHits & " cells have been found", , "BoM Calculator for VM Greenfield"
ExitHandler:
Application.ScreenUpdating = scrUpdt
Exit Sub
ErrHandler:
MsgBox Err.Description, vbExclamation
Resume ExitHandler
End Sub
'ask the user to select a folder
Function UserSelectFolder(msgPrompt As String) As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Title = msgPrompt
If .Show = -1 Then UserSelectFolder = .SelectedItems(1) & "\"
End With
End Function
'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 GetFileMatches(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
fpath = fldr.Path
If Right(fpath, 1) <> "\" Then fpath = fpath & "\"
f = Dir(fpath & filePattern) 'Dir is faster...
Do While Len(f) > 0
colFiles.Add fso.getfile(fpath & f)
f = Dir()
Loop
Loop
Set GetFileMatches = colFiles
End Function
'search range `rng` for all matches to `val` and return
' as a Collection of ranges (cells)
Public Function FindAll(rng As Range, val As String) As Collection
Dim rv As New Collection, f As Range
Dim addr As String
Set f = rng.Find(what:=val, after:=rng.Cells(rng.Cells.Count), _
LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not f Is Nothing Then addr = f.Address()
Do Until f Is Nothing
rv.Add f
Set f = rng.FindNext(after:=f)
If f.Address() = addr Then Exit Do
Loop
Set FindAll = rv
End Function

Find String and extract in vba using fso

so my code currently goes through a folder and extracts Ranges of data from every file in the folder into a format set by me, it also extracts the filename.
Now i need to use fso to search for certain string inside the file not the filename, lets say "Smart", and in the file "Smart" appears quite a few times, but i only want to extract it once.
Thank you so much to anyone who is able to provide me the small part of the code or some advices to help me continue on!
Option Explicit
Sub ScanFiles()
Application.ScreenUpdating = False
Dim wks As Worksheet
Set wks = Worksheets.Add
' New worksheet for question 2
Dim wksFSO As Worksheet
' Add headers data
With wks
.Range("A1:E1") = Array("Test", "Temp", "Start", "Type", "FileName", "Test", "EndDate", "Smart", "Er")
End With
' Set your copy ranges
Dim CopyRange(1 To 4) As String
CopyRange(1) = "A18"
CopyRange(2) = "A19"
CopyRange(3) = "A14"
CopyRange(4) = "A19"
' Early Binding - Add "Microsoft Scripting Runtime" Reference
Dim FSO As New Scripting.FileSystemObject
' Set FolderPath
Dim FolderPath As String
FolderPath = "c:\Users\Desktop\Tryout\"
' Set Folder FSO
Dim Folder As Scripting.Folder
Set Folder = FSO.GetFolder(FolderPath)
' Loop thru each file -> Assuming only 6 files
Dim File As Scripting.File
For Each File In Folder.Files
' If loop looking for specific files and copy to new FSOWorksheet
If File.Name Like "ReportFile" Then
wksFSO.Cells(1, 1) = File.Name
End If
Dim wkbData As Workbook
Set wkbData = Workbooks.Open(File.Path)
Dim wksData As Worksheet
ActiveSheet.Name = "Sheet1"
Set wksData = wkbData.Worksheets("Sheet1") ' -> Assume this file has only 1 worksheet
Dim BlankRow As Long
BlankRow = wks.Range("A" & wks.Rows.Count).End(xlUp).Row + 1
Dim i As Long
For i = 1 To 4
wks.Cells(BlankRow, i).Value = wksData.Range(CopyRange(i)).Value
Next i
' Write filename in col E
wks.Cells(BlankRow, 5).Value = File.Name
wkbData.Close False
Next File
Range("A:I").EntireColumn.AutoFit
Application.ScreenUpdating = True
End Sub
This could help you, what it does is it search through the path's folders and each excel file that is inside it for the word that you are going to put in the input box.
Sub SearchFolders()
Dim fso As Object
Dim fld As Object
Dim strSearch As String
Dim strPath As String
Dim strFile As String
Dim wOut As Worksheet
Dim wbk As Workbook
Dim wks As Worksheet
Dim lRow As Long
Dim rFound As Range
Dim strFirstAddress As String
On Error GoTo ErrHandler
Application.ScreenUpdating = False
'Change as desired
strPath = "c:\MyFolder"
'You can enter your smart word here
strSearch = inputbox("Please enter a word to be searched.","Search for a word")
Set wOut = Worksheets.Add
lRow = 1
With wOut
.Cells(lRow, 1) = "Workbook"
.Cells(lRow, 2) = "Worksheet"
.Cells(lRow, 3) = "Cell"
.Cells(lRow, 4) = "Text in Cell"
Set fso = CreateObject("Scripting.FileSystemObject")
Set fld = fso.GetFolder(strPath)
strFile = Dir(strPath & "\*.xls*")
Do While strFile <> ""
Set wbk = Workbooks.Open _
(Filename:=strPath & "\" & strFile, _
UpdateLinks:=0, _
ReadOnly:=True, _
AddToMRU:=False)
For Each wks In wbk.Worksheets
Set rFound = wks.UsedRange.Find(strSearch)
If Not rFound Is Nothing Then
strFirstAddress = rFound.Address
End If
Do
If rFound Is Nothing Then
Exit Do
Else
lRow = lRow + 1
.Cells(lRow, 1) = wbk.Name
.Cells(lRow, 2) = wks.Name
.Cells(lRow, 3) = rFound.Address
.Cells(lRow, 4) = rFound.Value
End If
Set rFound = wks.Cells.FindNext(After:=rFound)
Loop While strFirstAddress <> rFound.Address
Next
wbk.Close (False)
strFile = Dir
Loop
.Columns("A:D").EntireColumn.AutoFit
End With
MsgBox "Done"
ExitHandler:
Set wOut = Nothing
Set wks = Nothing
Set wbk = Nothing
Set fld = Nothing
Set fso = Nothing
Application.ScreenUpdating = True
Exit Sub
ErrHandler:
MsgBox Err.Description, vbExclamation
Resume ExitHandler
End Sub

How to iterate through all sub-folders and their sub-sub-folders and so on using vba to check a folder if it exist?

I have below code to check if a folder exist on the predefined directory.
Option Explicit
Public xStatus As String
Sub Status()
Application.ScreenUpdating = False
Dim fso As Object
Dim folder As Object
Dim subfolders As Object
Dim subfolder1 As Object
Dim Rg As Range
Dim xCell As Range
Dim xTxt As String
xTxt = ActiveWindow.RangeSelection.Address
Set Rg = Application.InputBox("Please select city/cities to check production status!!! ", "Lmtools", xTxt, , , , , 8)
If Rg Is Nothing Then
MsgBox ("No cities selected!!!")
Exit Sub
End If
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("D:\")
Set subfolders = folder.subfolders
For Each xCell In Rg
If xCell.Value <> "" Then
For Each subfolder1 In subfolders
xStatus = subfolder1.path
If xStatus Like "*?\" & xCell.Value Then
Cells(xCell.Row, xCell.Column + 1).Value = "Completed"
Cells(xCell.Row, xCell.Column + 2).Value = xStatus
GoTo nextiteration
Else
Cells(xCell.Row, xCell.Column + 1).Value = "Ongoing"
End If
Next
End If
nextiteration:
Next
Application.ScreenUpdating = True
End Sub
It works fine but only checks the sub-folders of "D:\" and not beyond that.
My folder could be present anywhere (either inside the sub-folders or their sub-folders or alongside "D:\"'s sub-folders.
my concern is how to iterate through all the folders.
I creted this a while back. Basically i used this to rename file in folders and sub-folders,
Option Explicit
Sub VersionRename()
Dim SelectedFolder As FileDialog
Dim T_Str As String
Dim FSO As Object
Dim RenamingFolder As Object, SubFolder As Object
Dim T_Name As String
Set SelectedFolder = Application.FileDialog(msoFileDialogFolderPicker)
SelectedFolder.Title = "Select folder:"
SelectedFolder.ButtonName = "Select Folder"
If SelectedFolder.Show = -1 Then
T_Str = SelectedFolder.SelectedItems(1)
Else
'MsgBox "Cancelled by user.", vbInformation
Set SelectedFolder = Nothing
Exit Sub
End If
Set SelectedFolder = Nothing
Set FSO = CreateObject("Scripting.FileSystemObject")
Set RenamingFolder = FSO.GetFolder(T_Str)
File_Renamer RenamingFolder
For Each SubFolder In RenamingFolder.SubFolders
File_Renamer SubFolder
Next
Set SubFolder = Nothing
Set RenamingFolder = Nothing
Set FSO = Nothing
MsgBox "Process completed!", vbInformation, Title:="Renaming Files"
End Sub
Private Sub File_Renamer(Folder As Object)
Dim File As Object
Dim T_Str As String
Dim T_Name As String
Dim PreVersionID As Variant
Dim NextVersionID As Variant
Dim StringReplace As String
PreVersionID = Application.InputBox("Input 1 if no version number otherwise input existing version number:", Type:=1)
If PreVersionID = False Then Exit Sub
NextVersionID = Application.InputBox("Input your next version number:", Type:=1)
If NextVersionID = False Then Exit Sub
T_Str = Format("_V" & NextVersionID)
For Each File In Folder.Files
T_Name = File.Name
'Debug.Print T_Name
If NextVersionID > 1 Then
StringReplace = Replace(T_Name, "_V" & PreVersionID, "", 1, 3)
'Debug.Print StringReplace
File.Name = Left(StringReplace, InStrRev(StringReplace, ".") - 1) & T_Str & Right(StringReplace, Len(StringReplace) - (InStrRev(StringReplace, ".") - 1))
Else
File.Name = Left(T_Name, InStrRev(T_Name, ".") - 1) & T_Str & Right(T_Name, Len(T_Name) - (InStrRev(T_Name, ".") - 1))
End If
Next
End Sub

Export in tilde delimited

I first create files in Excel. This macro saves all sheets into separate tab delimited text files.
How can I save with a tilde "~" instead of a tab?
Sub newworkbooks()
Dim Sheet As Worksheet, SheetName$, MyFilePath$, N&
MyFilePath$ = ActiveWorkbook.Path & "\" & _
Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 4)
With Application
.ScreenUpdating = False
.DisplayAlerts = False
' End With
On Error Resume Next '<< a folder exists
MkDir MyFilePath '<< create a folder
For N = 1 To Sheets.Count
Sheets(N).Activate
SheetName = ActiveSheet.Name
Cells.Copy
Workbooks.Add (xlWBATWorksheet)
With ActiveWorkbook
With .ActiveSheet
.Paste
.Name = SheetName
[A1].Select
End With
'save book in this folder
.saveas Filename:=MyFilePath _
& "\PO" & SheetName & ".txt", FileFormat:=xlTextWindows
.Close SaveChanges:=True
End With
.CutCopyMode = False
Next
End With
Sheet1.Activate
End Sub
Instead of looking like the following
this is a test
it should look like this
this~is~a~test
Here's one approach, which would be easy to modify to suit - this gives you control over the character set and the delimiter:
https://excel.solutions/2014/04/using-vba-write-excel-data-to-text-file/
Sub WriteTextFile()
Dim rng As Range, lRow As Long
Dim stOutput As String, stNextLine As String, stSeparator As String
Dim stFilename As String, stEncoding As String
Dim fso As Object
'-------------------------------------------------------------------------------------
'CHANGE THESE PARAMETERS TO SUIT
Set rng = ActiveSheet.UsedRange 'this is the range which will be written to text file
stFilename = "C:\Temp\TextOutput.txt" 'this is the text file path / name
stSeparator = vbTab 'e.g. for comma seperated value, change this to ","
stEncoding = "UTF-8" 'e.g. "UTF-8", "ASCII"
'-------------------------------------------------------------------------------------
For lRow = 1 To rng.Rows.Count
If rng.Columns.Count = 1 Then
stNextLine = rng.Rows(lRow).Value
Else
stNextLine = Join$(Application.Transpose(Application.Transpose(rng.Rows(lRow).Value)), stSeparator)
End If
If stOutput = "" Then
stOutput = stNextLine
Else
stOutput = stOutput & vbCrLf & stNextLine
End If
Next lRow
Set fso = CreateObject("ADODB.Stream")
With fso
.Type = 2
.Charset = stEncoding
.Open
.WriteText stOutput
.SaveToFile stFilename, 2
End With
Set fso = Nothing
End Sub
I'm sure you could adapt that to loop through your worksheets, and output the UsedRange of each.
EDIT:
Here's how to adapt it to use tilde as separator, and loop through each worksheet;
Sub OutputAllSheetsTildeSeparated()
Dim rng As Range, lRow As Long
Dim stOutput As String, stNextLine As String, stSeparator As String
Dim stFilepath As String, stFilename As String, stEncoding As String
Dim ws As Worksheet
Dim fso As Object
stFilepath = ThisWorkbook.Path & "\" & Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 4)
stSeparator = "~"
stEncoding = "UTF-8"
If Dir(stFilepath, vbDirectory) = vbNullString Then MkDir stFilepath
For Each ws In ThisWorkbook.Worksheets
Set rng = ws.UsedRange
stFilename = stFilepath & "\PO" & ws.Name & ".txt"
For lRow = 1 To rng.Rows.Count
If rng.Columns.Count = 1 Then
stNextLine = rng.Rows(lRow).Value
Else
stNextLine = Join$(Application.Transpose(Application.Transpose(rng.Rows(lRow).Value)), stSeparator)
End If
If stOutput = "" Then
stOutput = stNextLine
Else
stOutput = stOutput & vbCrLf & stNextLine
End If
Next lRow
Set fso = CreateObject("ADODB.Stream")
With fso
.Type = 2
.Charset = stEncoding
.Open
.WriteText stOutput
.SaveToFile stFilename, 2
End With
Set fso = Nothing
Next ws
End Sub

Resources