I have a requirement from the client in which they want us to rename the column from multiple excel sheets which are present in the same directory.
There are 70+ excel reports and we are not sure that the particular column is present in which excel file. So every time they ask us to change, all the time we have to drill down all the excel sheets to find out the changes required which is really time consuming.
I thought of automating the process. Since all the files are present under the same directory, can't we use a MACRO,BATCH/UNIX SCRIPTS or any other way by which we can traverse the entire directory and make those changes by performing a find and replace thing.
So my first question is, if this is feasible ? If yes, then can anyone suggest/advice how to work around on this process ?
Thanks in Advance
I can't take full credit for the below as this is a patchwork of code I have used over the years. This is how I would go about it personally:
Manually make a copy of the files to change and place them in a folder (keep the originals safe!)
Let the code open each file and change it
Code will save a copy in a different 'done' folder
The example below loops through each Excel file and moves it from the 'to-do' folder to the 'done' folder once it has changed the cell "A1" to "Hello World". When the 'to-do' folder is empty the code stops.
You'll need to change the file paths for this to work.
Sub Example()
Dim FolderPath As String, FilePath As String, FileCount As Integer
Dim objExcelApp As Object
Dim wb As Object
Dim SaveName As String
FolderPath = "C:\Users\********\Desktop\To Do\"
NewFolderPath = "C:\Users\********\Desktop\Done\"
FilePath = FolderPath & "*.xl??"
FileName = Dir(FilePath)
ChangeNextFile:
FileCount = 0
'count how many files in "files to be changed" folder
Do While FileName <> ""
FileCount = FileCount + 1
FileName = Dir()
Loop
'if there are no files left end the code
If FileCount = 0 Then GoTo FinishedLoadingFiles
'choose the first file to change
FileName = Dir(FilePath)
Debug.Print FileName
'create an instance of Excel
Set objExcelApp = CreateObject("Excel.Application")
With objExcelApp
.Visible = False
.DisplayAlerts = False
End With
'opens the excel file in the background
objExcelApp.Workbooks.Open FileName:=FolderPath & FileName, UpdateLinks:=False
Set wb = objExcelApp.ActiveWorkbook
objExcelApp.ActiveWindow.Activate
'changes cell "A1" to say "hellow world"
wb.Sheets(1).Cells(1, 1).Value = "Hello World"
'saves the file in the done pile
wb.saveas NewFolderPath & FileName '& ".xlsb"
'closes excel
With objExcelApp
.DisplayAlerts = True
End With
wb.Close
objExcelApp.Quit
Set wb = Nothing
Set objExcelApp = Nothing
'deletes the original file. New file has been saved in the new folder
Kill FolderPath & FileName
GoTo ChangeNextFile
FinishedLoadingFiles:
MsgBox "All done"
End Sub
Related
I have daily excel reports that get created by an external program. I am looking to automate a simple row formatting on these reports. They always have the same number of columns, however, different number of rows.
This is the macro I have in place: (it does the job as expected when run on a single xlsm file, which is not ideal)
Sub FormatLeadLists()
Application.DisplayAlerts = False
Columns("A:F").Select
Selection.ColumnWidth = 8.29
Columns("A:F").EntireColumn.AutoFit
Range("A1").Select
Selection.CurrentRegion.Select
ActiveSheet.ListObjects.Add(xlSrcRange, Selection, , xlYes).Name = "Table1"
Range("Table1[#All]").Select
End Sub
This is the .vbs code that I run from a batch file:
Dim args, objExcel
Set args = WScript.Arguments
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open args(0)
objExcel.Visible = True
objExcel.Run "FormatLeadLists"
objExcel.ActiveWorkbook.Save
objExcel.ActiveWorkbook.Close(0)
objExcel.Quit
This works well on a single file, however, to make this work I have to create my macro in my "All Open workbooks" and have to save my excel as an xlsm file.
That's not ideal if I have these reports overwritten every day as xlsx files.
How can I create a macro in my personal workbook so I don't have to save the report as xlsm and so I can apply the same macro on the other xlsx reports?
I know I should even be able to create a .vbs file that loops through my windows folder and applies the macro on all existing excel files.
Edit:
Code for the loop (from comments):
Dim strFileName As String
Dim strFolder As String: strFolder = "C:\myfiles\"
Dim strFileSpec As String: strFileSpec = strFolder & "*.*"
strFileName = Dir(strFileSpec)
Do While Len(strFileName) > 0
Debug.FormatLeadLists strFileName
strFileName = Dir
Loop
I want to perform analysis of a list of similarly named files. For example, at a specific directory, call it "\USSECVAPFL23\23AM0039\A\" there will be folder with a list of 15-30 files. The names of these files are all similar except for different policy numbers. For example one name might be "Policy 0048284.xlsx" then "Policy 3329851.xlsx" then "Policy 323483.xlsx" etc. My goal is to one by one open each file, copy a range of cells, and paste them into a new workbook. Then save that new workbook as "Results 0048284" before moving onto the next file and doing the same thing until all the files in the folder have a "Results" file. Is this possible?
This was my attempt at looping and opening each file but it doesn't open the files.
Sub openfiles()
Dim directory As String, fileName As String, sheet As Worksheet, i As
Integer, j As Integer
Application.ScreenUpdating = False
directory = "\\USSECVAPFL23\23AM0039\A\ACTL\Tax Actuarial\Product Tax\Calculators\TC
Calculator\Audit 7702\CUNA CVAT Test"
fileName = Dir(directory & "*.xlsx")
Do While fileName <> ""
Workbooks.Open (directory & fileName)
fileName = Dir()
Loop
Application.ScreenUpdating = True
End Sub
I have multiple files with data that need to be transposed into a single master file with all the data into a single row.
I'm a complete noob in programming so if the code I have so far doesn't make any sense, then please feel free to change it
I was able to find this "Loop all excel files in a folder" code from www.TheSpreadsheetGuru.com The code works perfectly fine, it will open up each file individually in the folder and then close it, and then open the next file and close it until it has gone through every file in that folder.
However, I'd like to insert a "copy and paste data" code loop within the loop. So what needs to happen is, the code will open "File1" in the folder, and then copy and paste the data into the "Master File" in cell A4. Then it will close "File1", and then open up "File2" and copy the data into "Master File" in cell A5 and then close "File2". It will repeat this until all files in the folder have been opened/closed.
This is the code I have right now, but I can't get the copy and paste code to work properly. I'm having a hard time figuring out how to set the loop up where the code will know what file it is currently on and setting a counter for the cell of the Master File that it is pasting into.
Sub LLoopAllExcelFilesInFolder()
'PURPOSE: To loop through all Excel files in a user specified folder and perform a set task on them
'SOURCE: www.TheSpreadsheetGuru.com
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "March"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancelhow
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xlsx"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'THIS IS MY COPY AND PASTE CODE (DOESN'T WORK)
Dim row As Integer
While row = 4
Workbooks("Filename:=myPath & myFile").Worksheets("Resin Log").cell("I5") = Workbooks("Workbook1.xlsm").Worksheets("Sheet1").Range("A" & row).Value
Next row
'Save and Close Workbook
wb.Close SaveChanges:=False
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
It is possible to do what you're talking about. I would suggest, trying to just set cell values in the file being created directly
targetworkbook.worksheets(1).Range("A1").value = sourceworkbook.Worksheets(1).Range("C4").value
rather than using .Copy & .Paste so that if the macro takes a while to run you aren't locked out of using Copy/Paste in other applications. If you're still unsure of what to do, try doing it with Record Macro turned on. The generated code will need tweaked, but will give you most of what you need.
Also, be sure to look at this link for some other things to avoid using in your code.
I have a folder in my Desktop with more or less 2000 csv files. Those files have only 1 "Sheet" but the sheet name varies. The only similar thing is that it starts with the word "Tankard".
In that one sheet, I just need to remove Column A and Save it, for all 2000 files. Its only my 2nd month to explore vba automation at work. I'd appreciate if someone can help me. Thanks in advance.
Script:
Sub Tank()
Dim wb As Workbook
Dim myPath As String
Dim myfile As String
Dim myExtension As String
Dim SheetName As String
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
SheetName = "Tankard*"
myPath = "\\ph00winfdfs01p\shares\JoeyC\documents\Roaming\Windows\Desktop\Tank\"
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "Tankard*.csv"
'Target Path with Ending Extention
myfile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
For i = 1 To 201
Set wb = Workbooks.Open(Filename:=myPath & myfile)
';;;;;;;;;;;;;;WRITE YOUR CODE HERE
Sheets("SheetName").Select
Columns("A").Select
Selection.Delete
wb.Close SaveChanges:=True
Next i
'Get next file name
myfile = Dir
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Try to understand what's happening. What this sub does at the moment is opening the first workbook that Dir can find, opening it 201 times and deleting the first column of sheet "Sheetname" every time.
Sheets("SheetName").Select
This selects the sheet with the name "Sheetname", not the name with the value that you set the string Sheetname to. If anything, it should be Sheets(Sheetname) but wildcards don't work here anyways.
Now let's look at the process you're trying to achieve.
myfile = Dir(myPath & myExtension)
sets myfile to the first file that matches your pattern ...\Tankard*.csv
Set wb = Workbooks.Open(Filename:=myPath & myfile)
opens the file and now you can access the workbook via wb
To delete the first column on the sheet I would recommend selecting all that stuff but deleting the range directly:
wb.Sheets(1).Columns(1).Delete 'If you want to actually delete the column
wb.Sheets(1).Columns(1).Clear 'If you want to just remove the values
As you can see you don't need the name of the sheet at all. Now save the workbook:
wb.Close SaveChanges:=True
Now you can set myfile to the next filename using Dir:
myfile = Dir
Then repeat that until there are no more files (at that point Dir will return "". The best way to achieve that is to use a While loop, e.g. like this
While myfile <> ""
'Do stuff here
Wend '(While End)
The advantage over a For loop is that you don't need to know the exact number of files in your folder.
I'll leave it up to you to patch that all together.
I am trying to import all the XLS files in a particular directory into one workbook. I've tried several sources for the code and the closest I've come is the one below (all the rest complained when closing the imported workbook no matter what i tried).
All I want to do now is take the text from a merged cell (C7 and D7) and rename the new worksheet to that. (there is a carriage return above the name in the cell in case this has any impact. I have no control over the source files as they're produced by an external team).
I'm afraid I have almost no ability with coding of any kind but I can normally futz things reading code from other sources but I stumped here. I've managed to get it to rename it to the source filename but I would prefer to get it from the cell text.
Cheers!
Sub Merge2MultiSheets()
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 = "C:\Temp\" ' change to suit
Set wbDst = Workbooks.Add(xlWBATWorksheet)
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)
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
ActiveSheet.Name = wsSrc.Range("C7").Value
wbSrc.Close False
strFilename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
I would change this line:
ActiveSheet.Name = wsSrc.Range("C7").Value
to:
wbDst.Worksheets(wbDst.Worksheets.Count).Name = wsSrc.Range("C7")
This will ensure you're naming the sheet in your destination workbook, not in your source workbook, which you might end up with by using ActiveSheet
From your question in the comment about the order of your files:
(BTW - you should edit your post and put the question in there, comments can get deleted)
The order is determined by the "natural" sort order that the files are held in by the OS. I have not found any flags that can be added to the Dir() command to sort them on input.
If you need to process them in name order, I would suggest:
Create a scratch sheet in wbDst
Loop through all the files using Dir(), putting them in Range(A1:An)
i.e put the first file name in Range("A1"), the second file name in Range("A2"), etc
Sort Range(A1:An) so they are in the desired order
Loop through your now sorted Range() to do the actual processing
Delete the scratch sheet from wbDst when you're done processing
For now, comment out:
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
These are great things to have in your code, but not until everything is working properly
I would suggest changing:
If Len(strFilename) = 0 Then Exit Sub
to
If Len(strFilename) > 0 Then
Do Until...
Loop
Because, if your initial read of the directory gives you no files, you never get to your clean up code after your loop. At the moment, there's nothing really critical there, but you may modify code in the future, or use this as model for other code that will require critical clean up, and it's a good habit to be in.