How to run 2 modules in one file in VBA? - vba

I am doing a report in VBA that allows to insert a folder directory into cell “C7”.
Then Moduole1 will return hyperlink to all the files that are in a folder (“C7”), all the file names, files dimension and a date of the last modification.
Module1 script is:
Dim iRow
Sub IndiceFile()
If Range("C7").Value = "" Then
MsgBox "Insert the path into C7"
Range("B11:E1048576").Select
Selection.ClearContents
Range("C7").Select
Else
Range("B11:E1048576").Select
Selection.ClearContents
iRow = 11
Call ListMyFiles(Range("C7"), Range("C8"))
MsgBox "Path is detected"
End If
End Sub
Sub ListMyFiles(mySourcePath, IncludeSubfolders)
Set MyObject = New Scripting.FileSystemObject
Set mySource = MyObject.GetFolder(mySourcePath)
On Error Resume Next
For Each myFile In mySource.Files
iCol = 2
Cells(iRow, iCol).Value = myFile.Path
Cells(iRow, iCol).Select
iCol = iCol + 1
Cells(iRow, iCol).Value = myFile.Name
iCol = iCol + 1
Cells(iRow, iCol).Value = myFile.Size
iCol = iCol + 1
Cells(iRow, iCol).Value = myFile.DateLastModified
iRow = iRow + 1
Next
If IncludeSubfolders Then
For Each mySubFolder In mySource.SubFolders
Call ListMyFiles(mySubFolder.Path, True)
Next
End If
Range("B11:B1048576").Select
Dim Cell As Range
For Each Cell In Intersect(Selection, ActiveSheet.UsedRange)
If Cell <> "" Then
ActiveSheet.Hyperlinks.Add Cell, Cell.Value
Range("C10").Select
End If
Next
End Sub
The second Module will add another column to a report with a count of rows in each file.
Option Explicit
Sub CountRows()
Dim wbSource As Workbook, wbDest As Workbook
Dim wsSource As Worksheet, wsDest As Worksheet
Dim strFolder As String, strFile As String
Dim lngNextRow As Long, lngRowCount As Long
Application.ScreenUpdating = False
' Open a current workbook with one worksheet to list the results
Set wbDest = ActiveWorkbook
Set wsDest = wbDest.ActiveSheet
' Set the location of the folder for the source files
strFolder = Range("C7").Value
' Call the first file from the folder
strFile = Dir(strFolder & "*.*")
' Loop through each file in the folder
' Return the count of rows for each file in the destination file
lngNextRow = 11
Do While Len(strFile) > 0
Set wbSource = Workbooks.Open(Filename:=strFolder & strFile)
Set wsSource = wbSource.Worksheets(1)
lngRowCount = wsSource.UsedRange.Rows.Count
' wsDest.Cells(lngNextRow, "A").Value = strFile
wsDest.Cells(lngNextRow, "F").Value = lngRowCount
wbSource.Close savechanges:=False
lngNextRow = lngNextRow + 1
' Call the next file from the folder
strFile = Dir
Loop
Application.ScreenUpdating = True
End Sub
The goal is to create a Module3 that will run first Module1 then Module2.
The problem is that separately (in 2 different files) both modules work. But when I try to lunch Module1 and then Module2 (even manually) the Module2 does not return any result anymore.
Maybe someone can help to understand a reason of this problem?

Try this code:
Option Explicit
Sub CountRows()
Dim wbSource As Workbook, wbDest As Workbook
Dim wsSource As Worksheet, wsDest As Worksheet
Dim strFolder As String, strFile As String
Dim lngNextRow As Long, lngRowCount As Long
Dim MyObject As Scripting.FileSystemObject
Set MyObject = New Scripting.FileSystemObject
Dim mySource As Folder
Dim myFile As Scripting.File
Dim i As Integer
Dim strPath As String
Application.ScreenUpdating = False
' Open a current workbook with one worksheet to list the results
Set wbDest = ActiveWorkbook
Set wsDest = wbDest.ActiveSheet
' Set the location of the folder for the source files
strFolder = Range("C7").Value
' Call the first file from the folder
Set mySource = MyObject.GetFolder(strFolder)
' Loop through each file in the folder
' Return the count of rows for each file in the destination file
lngNextRow = 11
For Each myFile In mySource.Files
strPath = myFile.Path
Set wbSource = Workbooks.Open(strPath)
Set wsSource = wbSource.Worksheets(1)
lngRowCount = wsSource.UsedRange.Rows.Count
' wsDest.Cells(lngNextRow, "A").Value = strFile
wsDest.Cells(lngNextRow, "F").Value = lngRowCount
wbSource.Close savechanges:=False
lngNextRow = lngNextRow + 1
' Call the next file from the folder
Next
Application.ScreenUpdating = True
End Sub

Related

Open, copy, paste close and loop files in a folder

I have a folder with 50 excel files I need to open, copy, paste, close and open the next one.
The macro is working until the loop, but it is not opening the next file. It stops
Any suggestion?
Sub open_and_close()
Dim MyFolder As String
Dim MyFile As Variant
Dim LC3 As Long
Dim WB1 As Workbook
Dim WB2 As Workbook
Set WB1 = ThisWorkbook
MyFolder = "C:\Users\x\y\z\Test script\"
MyFile = Dir(MyFolder & "*.xlsx")
Do While MyFile <> ""
Workbooks.Open (MyFolder & MyFile)
Set WB2 = ActiveWorkbook
ActiveWorkbook.Sheets("Test Script Scenario 1").Range("J3:J99").Copy
WB1.Sheets("Test Script Scenario 1").Activate
LC3 = Cells(3, Columns.Count).End(xlToLeft).Column
Cells(3, LC3 + 1).PasteSpecial Paste:=xlPasteValues
Cells(1, LC3 + 1) = Dir(WB2.Name)
WB2.Close savechanges:=False
MyFile = Dir()
Loop
End Sub
I always avoid DIR as it behaves strange if called several times.
I assume that's your problem - as you call Dir(wb2.name).
Try using FilesystemObject.
You have to add a reference to your project:
Furthermore it's not necessary to copy/paste >> see sub copyRangeValues
Plus: consider using a table (Insert > table) than it is much easier to add new columns.
Option Explicit
Private Const pathToFiles As String = "C:\Users\x\y\z\Test script\"
Private Const SourceSheetname As String = "Test Script Scenario 1"
Private Const SourceAddressToCopy As String = "J3:J99"
Private Const TargetSheetname As String = "Test Script Scenario 1"
Private Const TargetStartRow As Long = 3
Sub readDataFromFiles()
Dim fso As FileSystemObject
Set fso = New FileSystemObject
Dim SourceFolder As Folder
Set SourceFolder = fso.GetFolder(pathToFiles)
Dim SourceFile As File, wbSource As Workbook
For Each SourceFile In SourceFolder.Files
If SourceFile.Name Like "*.xlsx" Then
Set wbSource = getWorkbook(pathToFiles & "\" & SourceFile.Name)
copyDataFromSource wbSource
wbSource.Close False
End If
Next
End Sub
Private Sub copyDataFromSource(wbSource As Workbook)
Dim rgSource As Range
Set rgSource = wbSource.Worksheets(SourceSheetname).Range(SourceAddressToCopy)
Dim rgTargetCell As Range
Set rgTargetCell = getTargetCell
copyRangeValues rgSource, rgTargetCell
'add filename to row 1
rgTargetCell.Offset(TargetStartRow - 2).Value = wbSource.Name
End Sub
Private Function getTargetCell() As Range
Dim wsTarget As Worksheet: Set wsTarget = ThisWorkbook.Worksheets(TargetSheetname)
'I copied your code - but it looks weird to me
'think of using a table and then your can work with the listobject to add a new column
Dim LC3 As Long
With wsTarget
LC3 = .Cells(3, .Columns.Count).End(xlToLeft).Column
End With
Set getTargetCell = wsTarget.Cells(TargetStartRow, LC3)
End Function
Public Sub copyRangeValues(rgSource As Range, rgTargetCell As Range)
'generic routine to copy one range to another
'rgTargetCell = top left corner of target range
Dim rgTarget As Range
'resize rgTarget according to dimensions of rgSource
With rgSource
Set rgTarget = rgTargetCell.Resize(.Rows.Count, .Columns.Count)
End With
'write values from rgSource to rgTarget - no copy/paste necessary!!!
'formats are not copied - only values
rgTarget.Value = rgSource.Value
End Sub
Private Function getWorkbook(FullFilename As String) As Workbook
Dim wb As Workbook
Set wb = Application.Workbooks.Open(FullFilename)
Set getWorkbook = wb
End Function
First collect the files in an array, then process the files.
Sub open_and_close()
Dim MyFolder As String
Dim MyFile As Variant, Files As Variant
Dim LC3 As Long, NumFiles As Long, Idx As Long
Dim WB1 As Workbook, WB2 As Workbook
Set WB1 = ThisWorkbook
MyFolder = "C:\Users\x\y\z\Test script\"
' First collect the files in an array
MyFile = Dir(MyFolder & "*.xlsx")
NumFiles = 0
Do While MyFile <> ""
NumFiles = NumFiles + 1
If NumFiles = 1 Then
ReDim Files(1 To 1)
Else
ReDim Preserve Files(1 To NumFiles)
End If
Files(NumFiles) = MyFile
MyFile = Dir()
Loop
' Then process the files
For Idx = 1 To NumFiles
MyFile = Files(Idx)
Set WB2 = Workbooks.Open(MyFolder & MyFile)
ActiveWorkbook.Sheets("Test Script Scenario 1").Range("J3:J99").Copy
WB1.Sheets("Test Script Scenario 1").Activate
LC3 = Cells(3, Columns.Count).End(xlToLeft).Column
Cells(3, LC3 + 1).PasteSpecial Paste:=xlPasteValues
Cells(1, LC3 + 1) = Dir(WB2.Name)
WB2.Close savechanges:=False
Next Idx
End Sub

VBA- Import Multiple CSV to a Sheet, Remove Certain Rows/Columns

I am completely new to VBA, but I have CSV files(same format for all of them), and I want to import them to a single sheet on Excel. I was able to read the CSV file according to this code:
Sub R_AnalysisMerger()
Dim WSA As Worksheet
Dim bookList As Workbook
Dim SelectedFiles() As Variant
Dim NFile As Long
Dim FileName As String
Dim ws As Worksheet, vDB As Variant, rngT As Range
Application.ScreenUpdating = False
'Selects the CSV files as SELECTED FILES
Set ws = ThisWorkbook.Sheets(1)
ws.UsedRange.Clear 'Clears current worksheet
SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.csv*), *.csv*", MultiSelect:=True) 'Selects csv files
For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
FileName = SelectedFiles(NFile)
Set bookList = Workbooks.Open(FileName, Format:=2)
Set WSA = bookList.Sheets(1)
With WSA
vDB = .UsedRange
Set rngT = ws.Range("a" & Rows.count).End(xlUp)(2)
If rngT.Row = 2 Then Set rngT = ws.Range("A1")
rngT.Resize(UBound(vDB, 1), UBound(vDB, 2)) = vDB
bookList.Close (0)
End With
Next
Application.ScreenUpdating = True
ws.Range("A1").Select
But I have additional requirements:
Skip the first column.
Skip the first four rows.
Remove a certain String from each word in the fifth row.
Im used to java, and usually I would read each line with a "for" loop and set "if" statements to skip the first row and four columns and remove the string from each string if it was present.
I don't know how to do this with this code. From what I understand it just copies the whole CSV file into the sheet?
This solution is based on reading CSV as textstream. I have tried to include feature that makes possible most all things like selecting columns, Rows and so on.
Sub ImportCSV()
Dim fso As New IWshRuntimeLibrary.FileSystemObject
Dim txtStream As IWshRuntimeLibrary.TextStream
Dim files As IWshRuntimeLibrary.files
Dim file As IWshRuntimeLibrary.file
Dim txtLine As String
Dim lineCount As Integer
Dim lastRow As Integer
Dim lineCol As Variant
Dim rng As Range
Application.ScreenUpdating = False
ThisWorkbook.Sheets(1).usedRange.Delete
Set rng = ThisWorkbook.Sheets(1).usedRange
lastRow = 1
Set files = fso.GetFolder("path\folder").files
For Each file In files
If file.Name Like "*.csv" Then
Set txtStream = file.OpenAsTextStream(ForReading, TristateUseDefault)
txtStream.SkipLine ' skip first line, since it containes headers
lineCount = 1
Do
txtLine = txtStream.ReadLine
If lineCount = 5 Then
txtLine = Replace(txtLine, "stringToReplace", "StringToReplcaeWith") ' replace certain string from words in 5'th row
End If
lineCount = lineCount + 1
lineCol = sliceStr(Split(txtLine, ";"), startIdx:=4) ' slice the array so to skip four first columns
For iCol = 0 To UBound(lineCol) ' write columns to last row
rng(lastRow, iCol + 1).Value = lineCol(iCol)
Next iCol
lastRow = lastRow + 1
'Debug.Print Join(lineCol, ";") ' debug
Loop Until txtStream.AtEndOfStream
End If
Next file
Application.ScreenUpdating = True
End Sub
This is the slicer function
Function sliceStr(arr As Variant, startIdx As Integer, Optional stopIdx As Integer = 0) As String()
If stopIdx = 0 Then
stopIdx = UBound(arr)
End If
Dim tempArrStr() As String
ReDim tempArrStr(stopIdx - startIdx)
Dim counter As Integer
counter = 0
For i = startIdx To stopIdx
tempArrStr(counter) = arr(i)
counter = counter + 1
Next
sliceStr = tempArrStr
End Function
I just did a simple test and the code below seems to work. Give it a go, and feedback.
Sub Demo()
Dim fso As Object 'FileSystemObject
Dim fldStart As Object 'Folder
Dim fld As Object 'Folder
Dim fl As Object 'File
Dim Mask As String
Application.ScreenUpdating = False
Dim newWS As Worksheet
Set newWS = Sheets.Add(before:=Sheets(1))
Set fso = CreateObject("scripting.FileSystemObject") ' late binding
'Set fso = New FileSystemObject 'or use early binding (also replace Object types)
Set fldStart = fso.GetFolder("C:\Users\ryans\OneDrive\Desktop\output\") ' <-- use your FileDialog code here
Mask = "*.csv"
'Debug.Print fldStart.Path & ""
ListFiles fldStart, Mask
For Each fld In fldStart.SubFolders
ListFiles fld, Mask
ListFolders fld, Mask
Next
Dim myWB As Workbook, WB As Workbook
Set myWB = ThisWorkbook
Dim L As Long, t As Long, i As Long
L = myWB.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
t = 1
For i = 1 To L
Workbooks.OpenText Filename:=myWB.Sheets(1).Cells(i, 1).Value, DataType:=xlDelimited, Tab:=True
Set WB = ActiveWorkbook
lrow = WB.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
WB.Sheets(1).Range("B4:E" & lrow).Copy newWS.Cells(t, 2)
t = myWB.Sheets(1).Cells(Rows.Count, "B").End(xlUp).Row + 1
WB.Close False
Next
myWB.Sheets(1).Columns(1).Delete
Application.ScreenUpdating = True
End Sub
Sub ListFolders(fldStart As Object, Mask As String)
Dim fld As Object 'Folder
For Each fld In fldStart.SubFolders
'Debug.Print fld.Path & ""
ListFiles fld, Mask
ListFolders fld, Mask
Next
End Sub
Sub ListFiles(fld As Object, Mask As String)
Dim t As Long
Dim fl As Object 'File
For Each fl In fld.Files
If fl.Name Like Mask Then
t = Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row + 1
'Debug.Print fld.Path & "" & fl.Name
If Sheets(1).Cells(1, 1) = "" Then
Sheets(1).Cells(1, 1) = fld.Path & "\" & fl.Name
Else
Sheets(1).Cells(t, 1) = fld.Path & "\" & fl.Name
End If
End If
Next
End Sub

Copying data from multiple workbooks to single work book sheet wise

I want to copy data available in multiple worksheets in multiple workbooks into another workbook but sheet wise and data should have one column of workbook name(from where it has been copied).
For example
Workbook1 name(Raju-can be any name) having 7 sheets with different name(sheet name are same in both workbook)
Workbook2 name(pappu-can be any name) having 7 sheets with different name
Copy in new workbook sheet wise ..in result workbook(first sheet should have all the data from first sheet of wkb 1 and wkb 2 and same thing for second sheet)...and in all the sheet workbook name should be there that from which workbook data is copied.
Thanks in advance for help..
Option Explicit
Const ROW_FIRST As Integer = 2
Const BREAK_SHEET = 100000
-----------------------------------------------------------------------------------------------
Private Sub getFiles_Click()
'Creating Variables
Dim intResult As Integer, i As Double, strPath As String, objFSO As Object, intCountRows As Integer
Dim fileMap As New Scripting.dictionary
Dim fileName As Variant, filePath As String, sheet As Worksheet, openWb As Workbook
Dim sourceRange As String, noOfRecordsCopied As Double, noOfFilesScanned As Double, wbSheet As Worksheet
Set fileMap = New dictionary
'Initializing variables
i = ROW_FIRST
noOfRecordsCopied = 0
noOfFilesScanned = 0
'Get location of files to be copied
Application.FileDialog(msoFileDialogFolderPicker).Title = "Select a Path"
intResult = Application.FileDialog(msoFileDialogFolderPicker).Show
'Get all excel files in the selected location
If intResult <> 0 Then
strPath = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
Set objFSO = CreateObject("Scripting.FileSystemObject")
intCountRows = GetAllFiles(strPath, ROW_FIRST, objFSO, fileMap)
Call GetAllFolders(strPath, objFSO, intCountRows, fileMap)
End If
'Add all the records to this excel
Dim sheetNo As Double
sheetNo = 1
For Each fileName In fileMap.Keys
'Get the Funds required for Equity from T-2 File
If (fileName Like "*.xl*") Then
Set openWb = Workbooks.Open(fileMap(fileName))
For Each sheet In openWb.Worksheets
If i = ROW_FIRST Or i + sheet.UsedRange.Rows.Count > BREAK_SHEET Then
Set wbSheet = ThisWorkbook.Worksheets.Add(After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
wbSheet.Name = "Sheet" & sheetNo
sheetNo = sheetNo + 1
sheet.Range("1:1").Copy Destination:=wbSheet.Range("1:1")
wbSheet.Range("A1").EntireColumn.Insert
wbSheet.Range("A1").Value = "Name of File"
i = ROW_FIRST
End If
sourceRange = "A2:" & ConvertToLetter(sheet.UsedRange.Columns.Count) & sheet.UsedRange.Rows.Count
sheet.Range(sourceRange).Copy Destination:=wbSheet.Range("B" & i)
wbSheet.Range("A" & i & ":A" & (i + sheet.UsedRange.Rows.Count - 2)).Value = fileName
i = i + sheet.UsedRange.Rows.Count - 1
noOfRecordsCopied = noOfRecordsCopied + sheet.UsedRange.Rows.Count - 1
noOfFilesScanned = noOfFilesScanned + 1
Next sheet
openWb.Close (False)
End If
Next fileName
'Enter statistics
Cells(4, 2) = noOfRecordsCopied
Cells(5, 2) = noOfFilesScanned
Sheets("Collator").Activate
End Sub
Private Function GetAllFiles(ByVal strPath As String, ByVal intRow As Integer, ByRef objFSO As Object, ByRef fileMap As Scripting.dictionary) As Integer
Dim objFolder As Object, objFile As Object, i As Integer
i = intRow - ROW_FIRST + 1
Set objFolder = objFSO.GetFolder(strPath)
For Each objFile In objFolder.Files
fileMap(objFile.Name) = objFile.Path
i = i + 1
Next objFile
GetAllFiles = i + ROW_FIRST - 1
End Function
-----------------------------------------------------------------------------------------------------------------------------------------
Private Sub GetAllFolders(ByVal strFolder As String, ByRef objFSO As Object, ByRef intRow As Integer, ByRef fileMap As Scripting.dictionary)
Dim objFolder As Object, objSubFolder As Object
Set objFolder = objFSO.GetFolder(strFolder)
For Each objSubFolder In objFolder.subFolders
intRow = GetAllFiles(objSubFolder.Path, intRow, objFSO, fileMap)
Call GetAllFolders(objSubFolder.Path, objFSO, intRow, fileMap)
Next objSubFolder
End Sub
Try the script below.
Sub Basic_Example_1()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, Fnum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
'Fill in the path\folder where the files are
MyPath = "C:\Users\Ron\test"
'Add a slash at the end if the user forget it
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
'If there are no Excel files in the folder exit the sub
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
'Fill the array(myFiles)with the list of Excel files in the folder
Fnum = 0
Do While FilesInPath <> ""
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = FilesInPath
FilesInPath = Dir()
Loop
'Change ScreenUpdating, Calculation and EnableEvents
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
'Add a new workbook with one sheet
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
'Loop through all files in the array(myFiles)
If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(Fnum))
On Error GoTo 0
If Not mybook Is Nothing Then
On Error Resume Next
With mybook.Worksheets(1)
Set sourceRange = .Range("A1:C1")
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
'if SourceRange use all columns then skip this file
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "Sorry there are not enough rows in the sheet"
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
'Copy the file name in column A
With sourceRange
BaseWks.cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(Fnum)
End With
'Set the destrange
Set destrange = BaseWks.Range("B" & rnum)
'we copy the values from the sourceRange to the destrange
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next Fnum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
'Restore ScreenUpdating, Calculation and EnableEvents
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Also, check out the AddIn from the URL below.
https://www.rondebruin.nl/win/addins/rdbmerge.htm

Macro to list all worksheets in a folder and subfolder

I have been trying to write some code that will dig in to each folder and subfolder in a directory to list the names of the worksheets in my workbooks. After much time and help from the posts on this forum, I have gotten this far but still do not have a working macro. I'm sure it's obvious, and I apologize for the gore, but does anyone have any idea why it is not working? Thanks!
Option Explicit
Sub marines()
Dim FileSystem As Object
Dim HostFolder As String
Dim OutputRow
OutputRow = 2
HostFolder = "G:\EP\Projects\"
Set FileSystem = CreateObject("Scripting.FileSystemObject")
DoFolder FileSystem.GetFolder(HostFolder)
End Sub
Sub DoFolder(Folder)
Dim SubFolder
Dim Workbook As Variant
Dim wb As Workbook
Dim ws As Worksheet
Dim HostFolder
Dim OutputRow
OutputRow = 2
FileType = "*.xls*"
For Each SubFolder In Folder.SubFolders
DoFolder SubFolder
Next
For Each Workbook In Folder.SubFolders
ThisWorkbook.ActiveSheet.Range("A" & OutputRow).Activate
OutputRow = OutputRow + 1
Curr_File = Dir(HostFolder & FileType)
Do Until Curr_File = ""
For wb = wb.Open(HostFolder & Curr_File, False, True)
ThisWorkbook.ActiveSheet.Range("A" & OutputRow) = ThisWorkbook.Name
ThisWorkbook.ActiveSheet.Range("B" & OutputRow).ClearContents
OutputRow = OutputRow + 1
Set Each ws In wb.Sheets
ThisWorkbook.ActiveSheet.Range("B" & OutputRow) = ws.Name
ThisWorkbook.ActiveSheet.Range("A" & OutputRow).ClearContents
OutputRow = OutputRow + 1
Next ws
wb.Close SaveChanges:=False
Next
End Sub
I see you have a reference to Microsoft Scripting Runtime so I'll skip that part.
Simple solution: A module to withdraw all the workbooks in a folder and subfolders recursively and add them to a collection:
Public Sub ExtractAllWorkbooks(ByVal Addr As String, ByRef coll As Collection)
DoEvents
Dim objFSO As New FileSystemObject
Dim objFile As File, objFolder As Folder, objSubFolder As Folder
Set objFolder = objFSO.GetFolder(Addr)
For Each objFile In objFolder.Files
If Right(objFile.Name, 5) = ".xlsx" And Left(objFile.Name, 1) <> "~" Then
Call addStringToCollection(objFile.Path, coll)
End If
Next
For Each objSubFolder In objFolder.SubFolders
Call ExtractAllWorkbooks(objSubFolder.Path, coll)
Next
End Function
Public Sub addStringToCollection(stringToAdd As String, coll As Collection)
Dim st As String
For i = 1 To coll.Count
st = coll.Item(i)
If st = stringToAdd Then Exit Sub
Next
coll.Add stringToAdd
End Sub
With that, you just need to run in your main module:
dim Coll as New Collection
Const Addr As String = "G:\EP\Projects\"
Call ExtractAllWorkbooks(Addr, Coll)
Now you should have all the workbooks listed in the collection Coll. Just got to open them up and withdraw the worksheets' names elsewhere. Something like this should do the trick, assuming you are exporting the results to the worksheet wsRef:
dim wb as Workbook, ws as Worksheet
i = 2
For each st in coll
Set wb = Workbooks.Open(st)
For Each ws in wb.Worksheets
wsRef.Cells(i, 1) = wb.Name
wsRef.Cells(i, 2) = ws.Name
i = i + 1
Next
Application.DisplayAlerts = False
wb.Close
Application.DisplayAlerts = True
Next

Transferring Data from multiple workbooks

Objective - extracting data from multiple workbooks (5 in total); pasting the data into a new workbook.
Problem/Issue:
1) After running the below VBA code it's able to copy data from all the 5 workbooks but while pasting it's pasting data for only one of them.
2) Pop-up window for Clipboard is full. I've written a code to clear the clipboard but it doesn't seem to function as I still get the pop-up window.
VBA Code:
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow
Dim MyPath As String
MyPath = "Directory path"
MyFile = Dir(MyPath)
Do While Len(MyFile) > 0
If MyFile = "filename.xlsb" Then
End If
Workbooks.Open (MyPath & MyFile)
Range("A3:CP10000").Copy
ActiveWorkbook.Close
'calculating the empty row
erow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
a = ActiveWorkbook.Name
b = ActiveSheet.Name
Worksheets("Raw Data").Paste Range("A2")
Application.CutCopyMode = False ' for clearing clipboard
MyFile = Dir
Loop
End Sub
I tried two other commands below as well, but they seem to just return no data at all.
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow + 1, 1), Cells(erow + 1, 30)) `pasting the data`
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range("A2")`pasting the data`
Update.
Here is the current code:
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow As Long
Dim MyPath As String
Dim wb As Workbook
MyPath = "C:\Users\username\Downloads\PROJECTS\Project Name\Input file\"
MyFile = Dir(MyPath)
Do While Len(MyFile) > 0
If InStr(MyFile, "post_level.xlsb") > 0 Then
Set wb = Workbooks.Open(MyPath & MyFile)
Range("A3:CP10000").Copy
'calculating the empty row
erow = ThisWorkbook.Worksheets("Raw Data").Cells(Rows.Count, "A").End(xlUp).Row
ThisWorkbook.Worksheets("Raw Data").Paste (ThisWorkbook.Worksheets("Raw Data").Range("A" & erow + 2))
Application.DisplayAlerts = False
wb.Close False
Application.DisplayAlerts = True
End If
MyFile = Dir
Loop
ActiveWindow.Zoom = 90
End Sub
Update2.
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow As Long
Dim MyPath As String
Dim wb As Workbook
MyPath = "C:\Users\username\Downloads\PROJECTS\ProjectNameFolder\SubFolder\MainFolder\Input file"
MyFile = Dir("C:\Users\username\Downloads\PROJECTS\ProjectNameFolder\SubFolder\MainFolder\Input file\*.*")
Do While Len(MyFile) > 0
If InStr(MyFile, ".csv") > 0 Then
Set wb = Workbooks.Open(MyPath & MyFile)
Range("A3:CP10000").Copy
'calculating the empty row
erow = ThisWorkbook.Worksheets("Raw Data").Cells(Rows.Count, "A").End(xlUp).Row
ThisWorkbook.Worksheets("Raw Data").Paste (ThisWorkbook.Worksheets("Raw Data").Range("A" & erow + 2))
Application.DisplayAlerts = False
wb.Close False
Application.DisplayAlerts = True
End If
MyFile = Dir
Loop
End Sub
I hope I can help... There are multiple errors in your code, and I am not sure if I fixed them the way you'd want.
It would be useful to mention just one main mistake. You cannot have these 2 lines together:
If MyFile = "filename.xlsb" Then
End If
Between these lines you must put every procedure that you want to do IF he If condition is met. In the original case, if there was a file named "filename.xlsb", nothing would have happened, as you immediately closed the code block...
Try something similar to the following code. It worked for me to import data from all the files in the directory C:\Temp\ which have the extension of .xlsb
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow As Long
Dim MyPath As String
Dim wb As Workbook
MyPath = "C:\Temp\"
MyFile = Dir(MyPath)
Do While Len(MyFile) > 0
If InStr(MyFile, ".xlsb") > 0 Then
Set wb = Workbooks.Open(MyPath & MyFile)
Range("A3:CP10000").Copy
'calculating the empty row
erow = ThisWorkbook.Worksheets("Raw Data").Cells(Rows.Count, "A").End(xlUp).Row
ThisWorkbook.Worksheets("Raw Data").Paste (ThisWorkbook.Worksheets("Raw Data").Range("A" & erow + 2))
Application.DisplayAlerts = False
wb.Close False
Application.DisplayAlerts = True
End If
MyFile = Dir
Loop
End Sub