Compile sheets and file names into workbook - excel

I have a master Excel file which will be used as a reference to get the data from different sheet names from different Excel files in a folder,
I've searched the net and could not get a solution. Is there a way to get all the sheet names and paste it per row starting from A2 and A1 and which will reflect its file name without the extension?
Here is what I have so far:
Sub SheetNames()
Columns(1).Insert
For I = 1 To Sheets.Count
Cells(I, 1) = Sheets(I).Name
Next I
End Sub

You can try this code. It will save everything in first sheet of your master workbook:
Sub SheetNames()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim currentWorkbook, wb As Workbook
Dim i, j As Integer
Set currentWorkbook = ActiveWorkbook
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the current folder object
Set objFolder = objFSO.GetFolder(currentWorkbook.Path)
i = 1
j = 2
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'we filter filenames, so we get only excel files
'note that second condition is to prevent from using cached workbook associated with opened workbook
'it starts with ~$
If objFile.Name Like "*.xlsx" And Not objFile.Name Like "~$*.xlsx" _
And Not objFile.Name = currentWorkbook.Name Then
'get the name of a workbook in the first row
currentWorkbook.Worksheets(1).Cells(1, i).Value = objFile.Name
'open workbook
Set wb = Workbooks.Open(currentWorkbook.Path & "/" & objFile.Name)
'loop through sheets and get their names into cells
For j = 2 To wb.Worksheets.Count + 1
currentWorkbook.Worksheets(1).Cells(j, i).Value = wb.Worksheets(j - 1).Name
Next
'close workbook without saving changes
wb.Close (False)
i = i + 1
End If
Next objFile
End Sub

Related

find a value in excel across multiple worksheets and workbooks using vba

I have macro that finds the value "a" and replaces with value "b" across multiple worksheets and workbooks
the macro loops through files in folder and files in subfolders and replaces all the values it can find.
now i want the macro to return the file name in column E of the worksheet the macro is written in, ONLY IF changes where made in the file ( so if a was replaced with b return file name in colum E)
but my current code it only returns the file name of the first workbook it runs through.
my codes starts at sub search and it takes as an input sub()
Sub FindReplaceAcrossMultipleExcelWorkbooksFreeMacro(Path As String)
Dim CurrentWorkbookName As String
Dim ExcelCounter As Integer
Dim ExcelWorkbook As Object
Dim FindReplaceCounter As Integer
Dim FindandReplaceWorkbookName As String
Dim FindandReplaceWorksheetName As String
Dim LastRow As Integer
Dim oFile As Object
Dim oFolder As Object
Dim oFSO As Object
Dim Shape As Shape
Dim ws As Worksheet
Dim myrange As Range
Dim look As String
FindandReplaceWorkbookName = ActiveWorkbook.Name
FindandReplaceWorksheetName = ActiveSheet.Name
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(Path)
For Each oFile In oFolder.Files 'Loop through every File in Active Workbook's folder path
If InStr(1, oFile.Type, "Microsoft Excel") <> 0 And InStr(1, oFile.Name, FindandReplaceWorkbookName) = 0 And InStr(1, oFile.Name, "~") = 0 Then 'If the File Type contains the phrase Microsoft Excel isn't the current Excel Workbook and is NOT Lock File
Set ExcelWorkbook = Application.Workbooks.Open(Path & "\" & oFile.Name) 'Open Excel Workbook
CurrentWorkbookName = ActiveWorkbook.Name 'Name of Active Excel Workbook that was opened
Application.Workbooks(CurrentWorkbookName).Activate 'Ensure open Excel Workbook is active for future reference using ActiveWorkbook
Application.ScreenUpdating = False 'Limit screen flashing when Excel Workbooks opened and when Find & Replace is completed
FindReplaceCounter = 2
LastRow = Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(Rows.Count, 1).End(xlUp).Row 'Identify Last Row in Column A
Do Until FindReplaceCounter > LastRow 'Complete the Find and Replace for all values in Column A & B
For Each ws In ActiveWorkbook.Worksheets 'Loop through every Excel Worksheet in Active Excel Workbook
Set myrange = ws.UsedRange.Find(what:="ben")
If Not myrange Is Nothing Then
Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Range("E" & Rows.Count).End(xlUp).Offset(1, 0) = ExcelWorkbook.Name
End If
ws.Cells.Replace what:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 1).Value, Replacement:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 2).Value
Next ws
FindReplaceCounter = FindReplaceCounter + 1
Loop
ActiveWorkbook.Save 'Save Active Excel Workbook
ActiveWorkbook.Close 'Close Active Excel Workbook
End If
Next oFile
Application.ScreenUpdating = True 'Turn Excel ScreenUpdating back on
Set ExcelWorkbook = Nothing
Set oFSO = Nothing
Set oFolder = Nothing
Set oFile = Nothing
Exit Sub
End Sub
Sub Search()
FindReplaceAcrossMultipleExcelWorkbooksFreeMacro (Cells(2, 3).Value)
MsgBox "The Find and Replace has been completed."
End Sub
If I understand you correctly, maybe the code below can help you to compare it with your case.
Sub test()
Dim rg As Range: Dim wb As Workbook
Dim oFSO: Dim oFolder: Dim oFile
Dim fn As String: Dim sh As Worksheet: Dim cell As Range
Application.ScreenUpdating = False
Set wb = ActiveWorkbook
With wb.Sheets("Sheet1")
Set rg = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
.Range("E:E").ClearContents
End With
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder("D:\test")
For Each oFile In oFolder.Files
fn = oFile.Name
If InStr(fn, "test") Then GoTo nextfile:
Workbooks.Open oFile
With ActiveWorkbook
For Each sh In .Worksheets
For Each cell In rg
If Not sh.Cells.Find(cell.Value) Is Nothing Then
sh.UsedRange.Replace what:=cell.Value, Replacement:=cell.Offset(0, 1).Value, LookAt:=xlWhole
wb.Sheets("Sheet1").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
fn & " - " & sh.Name & " : value " & cell.Value & " is replaced with " & cell.Offset(0, 1).Value
End If
Next
Next
.Close SaveChanges:=False
End With
nextfile:
Next oFile
Application.ScreenUpdating = True
End Sub
To test the code, create 3 workbooks :
Name the first wb "test.xlsm", this is the wb where the code resides. In test.xlsm sheet Sheet1, make two column header in column A and B, and name it : FIND in A1 and REPLACE in B1. Under FIND, put data such as aaa in A2, bbb in A3, ccc in A4. Under REPLACE, put data such as XXX in B2, YYY in B3, ZZZ in B4.
Create other two workbooks, name it as you like. In each wb, put aaa and/or bbb and/or ccc to whatever cell whatever sheet as many as you like.
put test.xlsm and the other two workbooks in one folder in drive D:, name the folder "test".
Run the code in test.xlsm. Make sure that the other two workbooks is close.
There are three loops in the code.
The first is to loop to each file in test folder
The second is to loop to each sheet of that file
The third is to loop to each FIND/REPLACE value in sheet Sheet1 test.xlsm
On the first loop, it open the file / workbook (which is not test.xlsm)
then it loop to each sheet of that opened wb
on looped sheet, it loop to each data under FIND/REPLACE in sheet1 test.xlsm, and check if the looped cell value is found in the looped sheet, then it perform two process : (A) the found value is replaced with replace value (B) write the information in column E sheet1 of test.xlsm
Please note, the code doesn't write information on the looped sheet of the looped workbook which is being opened. It's just replace to a new value if the value to be replaced is found.
If you run the sub for the second time, there shouldn't be any information in column E sheet Sheet1 in test.xlsm.

VBA Copy and Paste without formatting

I've got this code but it pastes the cell formatting from the original document into the master file, how can I remove the formatting from the output please?
Option Explicit
Sub CopyPastefiles()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim MyFolder As String
Dim StartSht As Worksheet, ws As Worksheet
Dim WB As Workbook
Dim i As Integer
'turn screen updating off - makes program faster
'Application.ScreenUpdating = False
'location of the folder in which the desired TDS files are
MyFolder = "U:\Documents\DeleteMe\Sycle\"
Set StartSht = ActiveSheet
Set StartSht = Workbooks("masterfile.xlsx").Sheets("Sheet1")
'create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'get the folder object
Set objFolder = objFSO.GetFolder(MyFolder)
i = 1
'loop through directory file and print names
For Each objFile In objFolder.Files
If LCase(Right(objFile.Name, 3)) = "xls" Or LCase(Left(Right(objFile.Name, 4), 3)) = "xls" Then
'print file name to Column 1
Workbooks.Open Filename:=MyFolder & objFile.Name
Set WB = ActiveWorkbook
'print TOOLING DATA SHEET(TDS): values to Column 2
With WB
For Each ws In .Worksheets
StartSht.Cells(i + 1, 10) = objFile.Name
With ws
.Range("e6").Copy StartSht.Cells(i + 1, 4)
.Range("e7").Copy StartSht.Cells(i + 1, 5)
.Range("e8").Copy StartSht.Cells(i + 1, 6)
End With
i = i + 1
'move to next file
Next ws
'close, do not save any changes to the opened files
.Close SaveChanges:=False
End With
End If
'move to next file
Next objFile
'turn screen updating back on
'Application.ScreenUpdating = True
End Sub
thanks for you help.
Instead of using .Copy to directly paste the values into the destination, you can use .PasteSpecial Paste:=xlPasteValues.
I.e. something like
.Range("e6").Copy
StartSht.Cells(i + 1, 4).PasteSpecial Paste:=xlPasteValues
for your first line.
Or you can just set the cell equal to the range you're copying, as suggested in the comments on your question.
.StartSht.Cells(i + 1, 4) = .Range("E6")

Create range name in several files

I'm trying to create a range name in a number of excel files, and then write the file names and paths out to another excel. The files/paths are written correctly, but the range name doesn't appear to be created in the file. Can you tell me where I'm going wrong?
Sub directlisting()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim cell As Range
Dim RangeName As String
Dim CellName As String
Dim i As Integer
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder("\\xxxxxxxxxxx\testdata\Transfer")
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'open file if an Excel file
If Right(objFile, 4) = "xls*" Or Right(objFile, 3) = "xl*" Then
Application.Workbooks.Open (objFile)
'create range name
RangeName = "PVS"
CellName = "A4:AG27"
Set cell = Worksheets("PVS").Range(CellName)
objFile.Names.Add Name:=RangeName, RefersTo:=cell
'Save the file
Application.DisplayAlerts = False
objFile.Save
objFile.Close
Application.DisplayAlerts = True
End If
'print file name
Cells(i + 1, 1) = objFile.Name
'print file path
Cells(i + 1, 2) = objFile.path
i = i + 1
Next objFile
End If
End Sub
I tested this and it seemed to work for me. The main idea was to be more explicit with the workbook/worksheets and what you're calling them on:
Sub directlisting()
Dim objFSO As Object, objFolder As Object, objFile As Object
Dim cell As Range
Dim RangeName As String, CellName As String
Dim i As Integer
Dim tempWB As Workbook, mainWB As Workbook
Dim mainWS As Worksheet
'Assuming this is running from a "main" workbook
Set mainWB = ActiveWorkbook
Set mainWS = mainWB.ActiveSheet
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder("D:\User\Documents\Test") ' CHANGE TO YOUR PATH
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'open file if an Excel file
If Right(objFile, 4) = "xlsx" Or Right(objFile, 3) = "xl*" Then
Set tempWB = Application.Workbooks.Open(objFile)
'create range name
RangeName = "PVS"
CellName = "A4:AG27"
Set cell = tempWB.Worksheets("PVS").Range(CellName)
'ActiveWorkbook.Names.Add Name:="PVS", RefersToR1C1:="=PVS!R11C8:R18C14"
tempWB.Names.Add Name:=RangeName, RefersTo:=cell
'print file name
mainWS.Cells(i + 1, 1) = tempWB.Name
'print file path
mainWS.Cells(i + 1, 2) = tempWB.Path
i = i + 1
'Save the file
Application.DisplayAlerts = False
tempWB.Save
tempWB.Close
Application.DisplayAlerts = True
End If ' Right (objFile, 4) ...
Next objFile
End Sub
Small note: I had to change the ... = "xls*" Or Right ... to ... = "xlsx" Or ..., because for some reason it wouldn't open the .xlsx file. Curious. In any case, let me know if you get any errors or weird issues!
Also, I moved the part where you save the workbook name and path inside the If statement, so only if the file opens, will it mark it. Just tweak that line if you want to note every file, whether or not it opens.

Excel Load list of files in a folder to worksheets with contents on click

Good day.
I am looking for a solution for a problem, where in i have hundreds of CSV files located in a folder/nested folders.
I am trying to write a VBA script, which loads the list of files in this directory to Excel's work sheet-1 as soft links to each files. when a link is clicked, i am expecting the file contents to be loaded to worksheet 2, which would be used for further reporting purposes.
I have tried writing a VB script to extract the list of folder contents, however, i couldn't get them converted to soft links and loading the file contents. Any suggestions on how (else) could this be achieved ?
Any help in this regard is highly appreciated. Thanks in advance.
There will be 2 parts of code. First code will go to a module to list names of the files in the folder and addresses. First column will be names, second column will be addresses
Sub ListFiles()
Dim wb As Workbook
Dim ws As Worksheet
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Long
Set wb = ActiveWorkbook '<-- Master workbook
Set ws = wb.Sheets("Sheet1") '<-- Sheet you store file names and addresses
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\youfolderaddress")
i = 1
For Each objFile In objFolder.Files
ws.Cells(i + 1, 1) = objFile.Name
ws.Cells(i + 1, 2) = objFile.Path
i = i + 1
Next objFile
End Sub
Second part will go to worksheet where you store the list of files and we are going to use workshet selection change:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim wb As Workbook
Dim ws1, ws2 As Worksheet
Dim newBook As Workbook
Dim newSheet As Worksheet
Set wb = ActiveWorkbook '<- Master workbook with all list etc.
Set ws1 = wb.Sheets("Sheet1") '<-- Sheet that contains the list
Set ws2 = wb.Sheets("Sheet2") '<-- Sheet that will display csv content
If Target.Column = 2 And Target.Value <> "" Then '2 is the number of the column that contains file addresses
ws2.Cells.ClearContents
Workbooks.Open Filename:=Target.Value
Set newBook = ActiveWorkbook
Set newSheet = newBook.ActiveSheet
newSheet.Cells.Copy
ws2.Activate
ActiveSheet.Cells(1, 1).Select
ActiveSheet.Paste
Application.DisplayAlerts = False
newBook.Close
Application.DisplayAlerts = True
End If
End Sub
You could use event handlers. I assume that you are able to load the names into sheet 1 and set a range variable equal to the resulting range of names. You can then use the selection change event to trigger your loading code using something like the following (in the sheet1 code module). Clicking on a cell containing a file name will cause that name to be displayed:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim fnames As Range
Set fnames = Range("fnames") 'adjust to match your code
If Union(Target, fnames).Address = fnames.Address And _
Target.Cells.Count = 1 Then
MsgBox Target.Value 'replace this by code to load csv in sheet 2
End If
End Sub
With this code you can, with a default directory, retreive the list of file and add on sheet with the list (linked) of this file.
You can change this code with your to select the different directory
Sub ListAllFile()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim ws As Worksheet
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ws = Worksheets.Add
'Get the folder object associated with the directory
Set objFolder = objFSO.GetFolder("C:\Users\Desktop\Code\Excel")
ws.Cells(1, 1).Value = "The files found in " & objFolder.Name & "are:"
'Loop through the Files collection
For Each objFile In objFolder.Files
ws.Cells(ws.UsedRange.Rows.Count + 1, 1).Select
Selection.Hyperlinks.Add Anchor:=Selection, Address:=objFile.Name
Next
'Clean up!
Set objFolder = Nothing
Set objFile = Nothing
Set objFSO = Nothing
End Sub

Loop code keeps copying from the same excel spreadsheet in a folder

So I was trying to create a list of excel files in a folder (file name and path) and then use a For loop to copy and paste a specified worksheet for all of the files listed into a specified worksheet in the excel workbook that contains the macro. So far everything works except for the fact that the same file keeps getting copied and pasted over instead of all the files. The macro loops for the correct number of times, but it's not using all the excel files.
Here's the code:
First part for listing the files in the folder
Private Sub btn_LeaveReport()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder("D:\Administration\Time Sheets")
i = 2
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
Cells(i + 1, 2) = objFile.Name
'print file path
Cells(i + 1, 3) = objFile.Path
i = i + 1
Next objFile
End Sub
and this is the part for the loop
Private Sub btn_PullData()
'Declared Variables
Dim wbk As Workbook
Dim i As Integer
Dim StartAt As Integer
Dim EndAt As Integer
Dim CopyPath As String
Dim CopyPathRow As Integer
Dim iRow As Integer
'Ranges
StartAt = 1
EndAt = Val(ThisWorkbook.Worksheets("LeaveReport").Range("A1"))
CopyPathRow = 3
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
iRow = 3
'Loop de loop
For i = StartAt To EndAt
Application.ScreenUpdating = False
Set wbk = Workbooks.Open(CopyPath)
Sheets("TIMESHEET").Select
Range("C12:S34").Select
Selection.Copy
ThisWorkbook.Activate
Sheets("Pastebin").Select
Range("a" & iRow).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
iRow = iRow + 39
CopyPathRow = CopyPathRow + 1
wbk.Close True
Next i
Sheets("Pastebin").Select
Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Application.ScreenUpdating = True
MsgBox "Timesheet Data Imported"
End Sub
Based on the source of the error, i.e. same file being used, I'm guessing the issue lies with the part that has this:
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
and is "supposed" to update in the For loop via this:
CopyPathRow = CopyPathRow + 1
Move the line
CopyPath = ThisWorkbook.Worksheets("LeaveReport").Range("C" & CopyPathRow)
Inside the loop, that value of CopyPath is never being changed, but the value of CopyPathRow is.
Edit: I wouldn't call this recursion either.

Resources