open folder, manipulate files in excel, save excel files in new directory - vba

I have a folder called "maildir". It contains folders named numerically. These folders contain text files.
I have hacked together a macro that opens the numerically named folder, opens its first text file, and copies the contents into Excel. It then opens the next file in the directory, and copies the new file into a new sheet in the same workbook.
Then, the procedure deletes all the rows below row five, for every sheet in the workbook.
The next step combines the content from all the sheets into a new sheet called "Combined".
Then, all sheets but "Combined" are deleted
The next step saves the workbook into a new folder called "enron_excel".
This is where I am stuck: I was able to get the macro to work fine until I added a "For Loop" which is designed to both open the numerically named folders, and save them with numerical names in the "enron_excel" folder.
But when I run the code, and look in the "enron_excel" folder, it seems that the "combined" step has been missed. Does anyone know what happened?
Thank you.
Sub all()
Application.DisplayAlerts = False
Dim J As Integer
Dim ws As Worksheet
Dim wks As Worksheet
For i = 1 To 3 ' What I want this for loop to do: open the file called "1" (and later 2 and 3), manipulate the data then save with the same number in a different file
Path = "C:\Users\Kate\Desktop\enron4\maildir\" ' open folder in a directory
Filename = Dir(Path & i & "*.txt") ' opens a folder, and a text file in that folder
Do While Filename <> "" ' opens file in folder and copies to sheet in excel workbook
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
Sheet.Copy After:=ThisWorkbook.Sheets(1)
Next Sheet
Workbooks(Filename).Close
Filename = Dir()
Loop
For Each ws In ThisWorkbook.Worksheets ' deletes all the rows below row five
ws.Range("5:1000").Delete
Next ws
On Error Resume Next
Sheets(1).Select ' combines all the sheets into one worksheet
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next J
Sheets("Combined").Select ' selects the sheet calls "Combined" and deletes all the others
Application.DisplayAlerts = False
For Each wks In Worksheets
If wks.Name <> ActiveSheet.Name Then wks.Delete
Next wks
Path = "C:\Users\Kate\Desktop\enron_excel\" ' this opens a new path
FolderName = i
ActiveWorkbook.SaveAs Filename:=Path & FolderName ' this saves the file in the new path with the new name
Application.DisplayAlerts = True
Next i
End Sub

Why don't you use File System Object.
Something like:
Sub ReadAllfiles()
Dim fso As Scripting.FileSystemObject
Dim sFile As Scripting.File
Dim subFldr As Scripting.Folder
Dim wbName As String
Dim fldrPath As String
Dim fname As String
Dim fldrDesc As String
Dim wbTxt As Workbook
Dim ws As Worksheet
Dim wbDesc As Workbook
fldrDesc = "C:\User\Yourdestination\" '<~~ change to suit
fldrPath = "C:\User\Yourfolder" '<~~ change to suit
'iterate each folder of your source folder
Set fso = New Scripting.FileSystemObject
For Each subFldr In fso.GetFolder(fldrpath).SubFolders
wbName = subFldr.Name
Set wbDesc = Workbooks.Add 'add a new workbook
'create the combined sheet
Set ws = wbDesc.Sheets(1): ws.Name = "Combined"
'iterate each file on the folder
For Each sFile In subFldr.Files
fname = sFile.ParentFolder.Path & "\" & sFile.Name
Set wbTxt = Workbooks.Open(fname)
'I'm not sure why a text file will yield to multiple sheet
'so if that is really the case use your loop
'copy the 1st 4 rows to Combined sheet
wbTxt.Sheets(1).Range("1:4").Copy _
ws.Range("A" & ws.Rows.Count).End(xlUp).Offset(1, 0)
wbTxt.Close False 'close source text file
Next
wbDesc.SaveAs fldrDesc & wbName 'save the workbook
wbDesc.Close True 'close
Next
End Sub
I just based it on how you describe what you want. Not tested though.
You will need to add reference to Microsoft Scripting Runtime. HTH.

Related

How to get file path from different sheet in VBA

I am new in VBA. I have two sheets i.e. sheet1 has path of input Directory and Output directory.
On sheet2 i am started to code. i wants to read data from multiple xls files that are are stores in a folder . this folder path is specified in sheet1. i wants to copy all files headers from all xls files to sheet3 in a column.
my code is working well but i have given file path directly but i wants to get it from other sheet. Please help me. Below is my code and i have attched sheet1.
Public Sub CommandButton1_Click()
'DECLARE AND SET VARIABLES
Dim wbk As Workbook
Dim Filename As String
Dim Path As String
Dim mainwb As Workbook
Dim ws As Worksheet
Dim search_result As Range 'range search result
Dim blank_cell As Long
Dim wb As Workbook
Path = "D:\Testing\Data\Input\"
Filename = Dir(Path & "*.xls")
'--------------------------------------------
'OPEN EXCEL FILES
Do While Len(Filename) > 0 'IF NEXT FILE EXISTS THEN
Set wbk = Workbooks.Open(Path & Filename)
'MySheet = Application.Caller.Worksheet.Name
'Set sh = MySheet()
'Variable = ActiveSheet.Name
' Sheets(Variable).Range("A1:D1").Copy
'Sheets("Sheet2").Column(B2).Select.Activate.Paste
' Sheets("Sheet2").Active
'Columns("B2").Select
Set wbk = ActiveWorkbook
Variable = ActiveSheet.Name
wbk.Sheets(Variable).Rows(1).EntireRow.Copy
Workbooks("Tool.xlsm").Activate
' Workbooks("DFT Tool.xlsm").Sheets("Sheet2").Activate
'ActiveWorkbook.ActiveSheet
'Sheets("Sheet2").Activate
'ActiveSheet.Columns("E").Select
' Range("E1").End(xlDown).Offset(1, 0).Select
'ActiveSheet.Paste
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Sheet2")
For Each cell In ws.Columns(3).Cells
If IsEmpty(cell) = True Then cell.Select: Exit For
Next cell
Selection.PasteSpecial Paste:=xlPasteValues, Transpose:=True
' Selection.PasteSpecial Paste:=xlPasteValues, Transpose:=True
wbk.Close savechanges:=False
Filename = Dir
Loop
End Sub
Thanks in Advance
Try
Path = Cells(2,2).value
This takes the Value of Cell B2 and stores it in the Path variable.
Another possibility:
Filename = Dir(Cells(2,2).value & "*.xls")

Consolidate multiple sheets in multiple workbooks into one workbook with the same sheets but the data in the multiple sheets will be consolidated

I tried looking for this across the web but for my purpose, I have been unable so far to optimize the code required. This is what I am trying to accomplish:
I have files called Excel 1, Excel 2, Excel 3 and Master Excel. All of the files have the same number of worksheets, worksheet name and the same structure when it comes to the header and such.
I am trying to consolidate the values of Excel 1, Excel 2 and Excel 3 to the Master file.
So on the Master File, if there is sheet named 1000, then copy paste a range from Excel 1 sheet named 1000. Then look for sheet 1000, in Excel 2 and copy paste a range on the blank line following the last row used on Master file Sheet 1000.
The range is always the row after the header (this is fixed on all sheets) till the last row with data on a specific column.
Now there are multiple sheets in each workbooks and all the worksheets will have the same name.
Also the filepath of the files will be constant so I dont want an option to choose from.
The below code is able to loop through the worksheets and I can also define the copy paste range perfectly but only issue with the below is that I dont know how to match a target sheet with a destination sheet meaning sheet 1000's data in excel 1 file to be pasted to sheet 1000 in the master file.
Sub test()
Dim MyFile As String, MyFiles As String, FilePath As String
Dim erow As Long
'~~> Put additional variable declaration
Dim wbMaster As Workbook, wbTemp As Workbook
Dim wsMaster As Worksheet, wsTemp As Worksheet
FilePath = "\\AM01PCIFS01.global.root\HomeDirs$\yameen.sarwar\Desktop\Test\II1\"
MyFiles = "\\AM01PCIFS01.global.root\HomeDirs$\yameen.sarwar\Desktop\Test\II1\*.xlsx"
MyFile = Dir(MyFiles)
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
'~~> Set your declared variables
Set wbMaster = ThisWorkbook 'if you want to consolidate files in this workbook
Set wsMaster = wbMaster.Sheets("Sheet1") 'replace Sheet1 to suit
Do While Len(MyFile) > 0
'Debug.Print MyFile
If MyFile <> "master.xlsm" Then
'~~> Open the file and at the same time, set your variable
Set wbTemp = Workbooks.Open(Filename:=FilePath & MyFile, ReadOnly:=True)
Set wsTemp = wbTemp.Sheets(1) 'I used index, you said there is only 1 sheet
'~~> Now directly work on your object
With wsMaster
erow = .Range("A" & .Rows.Count).End(xlUp).Row 'get the last row
'~~> Copy from the file you opened
wsTemp.Range("A2:S20").Copy 'you said this is fixed as well
'~~> Paste on your master sheet
.Range("A" & erow).Offset(1, 0).PasteSpecial xlPasteValues
End With
'~~> Close the opened file
wbTemp.Close False 'set to false, because we opened it as read-only
Set wsTemp = Nothing
Set wbTemp = Nothing
End If
'~~> Load the new file
MyFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
Try this (see my comments in the code), but I made some small alterations in your Do While loop
Sub test()
Dim MyFile As String, MyFiles As String, FilePath As String
Dim erow As Long
'~~> Put additional variable declaration
Dim wbMaster As Workbook, wbTemp As Workbook
Dim wsMaster As Worksheet, wsTemp As Worksheet
Dim i As Integer
FilePath = "\\AM01PCIFS01.global.root\HomeDirs$\yameen.sarwar\Desktop\Test\II1\"
MyFiles = "\\AM01PCIFS01.global.root\HomeDirs$\yameen.sarwar\Desktop\Test\II1\*.xlsx"
MyFile = Dir(MyFiles)
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
'~~> Set your declared variables
Set wbMaster = ThisWorkbook 'if you want to consolidate files in this workbook
Do While Len(MyFile) > 0
'Debug.Print MyFile
If MyFile <> "master.xlsm" Then
'~~> Open the file and at the same time, set your variable
Set wbTemp = Workbooks.Open(Filename:=FilePath & MyFile, ReadOnly:=True)
'Start the loop of sheets within the source workbook
For i = 1 To wbTemp.Sheets.Count
Set wsTemp = wbTemp.Sheets(i) 'I used index, you said there is only 1 sheet
'~~> Now directly work on your object
With wbMaster.Worksheets(wsTemp.Name) 'This matches the sheet name in the source workbook to the sheet name in the target workbook
erow = .Range("A" & .Rows.Count).End(xlUp).Row 'get the last row of target sheet
'~~> Copy from the file you opened
wsTemp.Range("A2:S20").Copy 'you said this is fixed as well
'~~> Paste on your master sheet
.Range("A" & erow).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
Next i
'~~> Close the opened file
wbTemp.Close False 'set to false, because we opened it as read-only
End If
'~~> Load the new file
MyFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
To take sheetnames in wbMaster and reference a sheet with the same name in wbTemp, you can pass the name through a variable. Here is a couple of lines that will loop through your sheets in wbMaster
Dim strSheetname as String
For i = 1 To wbMaster.Sheets.Count
strSheetName = wbMaster.Sheets(i).Name
Set wsTemp = wbTemp.Sheets(strSheetName)
'Do whatever you need here with wsTemp
Next i
This code lacks error handling (i.e. if a sheet exists in wbMaster that does not exist in wbTemp, you will get an out of range error) but this will get you started.

Macro to copy data from one workbook to multiple workbooks in a specific folder

This is exactly what I wanted but after changing the folder path file name etc. for my needs, it doesn't work.
My workbook's path is C:\Users\navinc\Desktop\
My file name is test(2)
My worksheet name is Master Project List
My target files in folder path C:\Users\navinc\Desktop\test\
Error message : "Subscript out of range" Is there anything i'm missing ?
My code :
Sub Macro1()
Dim file As String
Dim myPath As String
Dim wb As Workbook
Dim rng As Range
Dim wbMaster As Workbook
'if master workbook already opened
'Set wbMaster = Workbooks("test(2).xlsx")
'if master workbook is not opened
Set wbMaster = Workbooks.Open("C:\Users\navinc\Desktop\test(2).xlsx")
Set rng = wbMaster.Sheets("Master Project list").Range("A1:D1")
myPath = "C:\Users\navinc\Desktop\test\" ' note there is a back slash in the end
file = Dir(myPath & "*.xlsx*")
While (file <> "")
Set wb = Workbooks.Open(myPath & file)
rng.Copy
With wb.Worksheets("Master Project list").Range("A1")
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteAll
End With
wb.Close SaveChanges:=True
Set wb = Nothing
file = Dir
Wend
Application.CutCopyMode = False
End Sub
Seems like wb doesn't have a sheet named "Master Project list" ?
If you don't know what the target sheet name will be then that's going to be tricky unless (eg) it's always the first worksheet you want, in which case you can use:
With wb.Worksheets(1).Range("A1")

Open all files in same folder as active workbook EXCEPT active workbook

I am using a macro that opens each excel file in the same folder that the workbook containing the macro (I'll call it the master workbook) is in and copies all the data in the first spreadsheet, then pastes them into the master workbook on a new worksheet. I found some very useful code online that I made a few changes to. Everything seems to be working fine, except that while this code is opening each file in the folder (in the Do Until loop), it opens itself half way through.
I'd like to be able to avoid this without referencing the master spread sheet's name directly, in case someone renames it.
Is there a simple command that will make skip the remaining code in the loop if it tries to open itself?
Code is below:
Sub CombineWSs()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim MyPath As String
Dim strFilename As String
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
MyPath = ThisWorkbook.Path
Set wbDst = ThisWorkbook
strFilename = Dir(MyPath & "\*.xls", vbNormal)
If Len(strFilename) = 0 Then Exit Sub
Do Until strFilename = ""
Set wbSrc = Workbooks.Open(Filename:=MyPath & "\" & strFilename)
Set wsSrc = wbSrc.Worksheets(1)
'copy the data
wbSrc.ActiveSheet.UsedRange.Select
Selection.Copy
'create a new worksheet in this master file
wbDst.Sheets.Add After:=Sheets(Sheets.Count)
'paste the data into master file's new sheet
wbDst.Sheets(wbDst.Worksheets.Count).Range("A1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
wbSrc.Close False
strFilename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Put an If block inside our loop
Do Until strFilename = ""
If strFilename <> wbDest.Name Then 'since you already set wbDest = ThisWorkbook
'... rest of code
End If
Loop

How to save Specific worksheets from a workbook using VBA?

Objective:
To save specific worksheets in a workbook as unique CSV files
Conditions:
To save specific worksheets (plural) from a workbook that contains both the specific worksheets and extraneous worksheets (e.g. to save specific 10 out of 20 available worksheets)
Insert the current date into the CSV's file name in order to avoid overwriting files currently in the save folder (this VBA is run daily)
File name syntax: CurrentDate_WorksheetName.csv
I've found VBA code that gets me half way to my goal. It saves ALL worksheets in the workbook but the file name is not dynamic with the current date.
Current Code:
Private Sub SaveWorksheetsAsCsv()
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim DateToday As Range
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
' Store current details for the workbook
SaveToDirectory = "S:\test\"
For Each WS In ThisWorkbook.Worksheets
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & WS.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
ThisWorkbook.Activate
Next
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = True
' Temporarily turn alerts off to prevent the user being prompted
' about overwriting the original file.
End Sub
There are several issues with your code:
i) There is no reason to save the format or name of your current workbook. Just use a new workbook to save the CSVs that you want.
ii) You were copying each worksheet in the book, but not copying it anywhere. This code was actually saving the same workbook with the name of each sheet. Copying the worksheet doesn't paste it anywhere and doesn't actually tell the saving function only to use parts of the document.
iii) To put the date in the name, you just need to append it to the save name string, as below.
Dim myWorksheets() As String 'Array to hold worksheet names to copy
Dim newWB As Workbook
Dim CurrWB As Workbook
Dim i As Integer
Set CurrWB = ThisWorkbook
SaveToDirectory = "S:\test\"
myWorksheets = Split("SheetName1, SheetName2, SheetName3", ",")
'this contains an array of the sheets.
'If you want more, put another comma and then the next sheet name.
'You need to put the real sheet names here.
For i = LBound(myWorksheets) To UBound(myWorksheets) 'Go through entire array
Set newWB = Workbooks.Add 'Create new workbook
CurrWB.Sheets(Trim(myWorksheets(i))).Copy Before:=newWB.Sheets(1)
'Copy worksheet to new workbook
newWB.SaveAs Filename:=SaveToDirectory & Format(Date, "yyyymmdd") & myWorksheets(i), FileFormat:=xlCSV
'Save new workbook in csv format to requested directory including date.
newWB.Close saveChanges:=False
'Close new workbook without saving (it is already saved)
Next i
CurrWB.Save 'save original workbook.
End Sub
It seems to me that in that code was a lot of unnecessary stuff but the most important part was almost ready.
Try this:
Sub SaveWorksheetsAsCsv()
Dim WS As Worksheet
Dim SaveToDirectory As String
SaveToDirectory = "C:\tmp\"
Application.DisplayAlerts = False
For Each WS In ThisWorkbook.Worksheets
WS.SaveAs Filename:=SaveToDirectory & Format(Now(), "yyyymmdd") & "_" & WS.Name & ".csv", FileFormat:=xlCSV
Next
Application.DisplayAlerts = True
End Sub