Run macro on newly created .xlsx file from another workbook - excel

I am opening and converting a .csv to an .xlsx file on a shared drive location. Once the .xlsx is created it remains open. The macros to do this are in a master Workbook located on the shared drive as well. Right now I have it set for a user to open the workbook and select a command button that opens and converts the file.
The user the selects the template needed from a list box and clicks a second command button which runs the following macro that calls a specific macro which converts the .xlsx just created to the correct format.
All my macros work except the macro below. It stops at the first Workbooks.. Right now the newly created .xlsx is the only .xlsx in its folder but eventually there may be multiple .xlsx files created from multiple .csv files.
Sub Run_Macros()
'IF USER SELECTED FXX_Rejects
If Range("A8").Value = Range("A2").Value Then
'ACTIVATE OTHER WORKBOOK
Workbooks("*.xlsx").Activate
Workbooks("*.xlsx").Sheets("Sheet1").Select
'AND THEN RUN APPROPRIATE MACRO
Call aaLayout
'IF USER SELECTED LXX_Rejects
ElseIf Range("A8").Value = Range("A3").Value Then
'ACTIVATE OTHER WORKBOOK
Workbooks("*.xlsx").Activate
Workbooks("*.xlsx").Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call abLayout
'IF USER SELECTED HXXXX_Rejects
ElseIf Range("A8").Value = Range("A4").Value Then
'ACTIVATE OTHER WORKBOOK
Workbooks("*.xlsx").Activate
Workbooks("*.xlsx").Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call acLayout
'IF USER SELECTED SXXX_Rejects
ElseIf Range("A8").Value = Range("A5").Value Then
'ACTIVATE OTHER WORKBOOK
Workbooks("*.xlsx").Activate
Workbooks("*.xlsx").Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call adLayout
End If
End Sub
I have edited my question post and added the macro below that locates and converts the .CSV files preparing them for templating. Maybe this can assist answering my original question.
Sub CSVFiles()
Dim MyFiles As String, ThisMonth As String
Dim startPath As String
Dim wb As Workbook
ThisMonth = Format(Date, "mmmm")
startPath = "\\XXX\2017\" & ThisMonth & "\"
MyFiles = Dir(startPath & "*.csv")
Do While MyFiles <> ""
Set wb = Workbooks.Open(startPath & MyFiles)
Call XLSXConvert
'Converts all csv files, saves and closes files. Prepares files for full template creation.
wb.SaveAs fileName:=startPath & Replace (MyFiles, ".csv", ".xlsx"),FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
wb.Close
MyFiles = Dir
Loop
End Sub

Your problem is with "*.xlsx". Operating system commands accept the * as a wildcard but you're not calling an operating system command. You are calling a VBA method on the Workbooks collection of objects that uses a number, usually the order in which the files were opened, as its identifier. Workbooks().Activate does not go out to the folder and look at all the available files and pick one that matches. Workbooks.Open() would do that but it still doesn't accept wildcards, and you said the workbook you want is already open.
Workbooks().Activate looks through the list of open workbooks for an identifier. The object you're trying to Activate was created in the code that ran before you get to this point, that we can't see from your posting. Somewhere in that code, you could assign that object to a variable and then you could create an argument in this code so you could pass in that variable.
What you could also do, IF you know that the only .xlsx file you have open is the one you want, is loop through all the open files and check the name to see if it ends in .xlsx and if it does assign that to a variable. Illustrated below:
Sub Run_Macros()
Dim wb As Workbook
Dim target As Workbook
Dim wbs As Workbooks
Set wbs = Workbooks
For Each wb In wbs
If LCase(Right(wb.FullName, 5)) = ".xlsx" Then
Set target = wb
End If
Next wb
'IF USER SELECTED FXX_Rejects
If Range("A8").Value = Range("A2").Value Then
'ACTIVATE OTHER WORKBOOK
target.Activate
target.Sheets("Sheet1").Select
'AND THEN RUN APPROPRIATE MACRO
Call aaLayout
'IF USER SELECTED LXX_Rejects
ElseIf Range("A8").Value = Range("A3").Value Then
'ACTIVATE OTHER WORKBOOK
target.Activate
target.Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call abLayout
'IF USER SELECTED HXXXX_Rejects
ElseIf Range("A8").Value = Range("A4").Value Then
'ACTIVATE OTHER WORKBOOK
target.Activate
target.Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call acLayout
'IF USER SELECTED SXXX_Rejects
ElseIf Range("A8").Value = Range("A5").Value Then
'ACTIVATE OTHER WORKBOOK
target.Activate
target.Sheets("Sheet1").Activate
'AND THEN RUN APPROPRIATE MACRO
Call adLayout
End If
End Sub

Related

How do I take Excel files from my Chrome Downloads and simultaneously combine them as tabs in an Excel Workbook?

Currently I have to manually click on each file in my Chrome Downloads and drag them into a workbook as a tab. If I download 60+ Excel files, it's a lot. Is it possible to have them all join together in one workbook simultaneously? Is there a code/formula/operation?
I tried "Get Data--> From Files--> From Folder and combine and load the files, but they don't combine as separate tabs. I just see general data of all the files in one worksheet tab.
Note: im operating under the assumption each workbook you are downloading is filetype ".xlsx" and contains only 1 worksheet.
If the files are in your "Chrome Downloads" then they are also located in your computers download folder.
For me this folder is "C:\Users[your name]\Downloads". The first step is for you to figure out where these downloads are going.
Do these files have names following some sort of pattern?
If yes this will make the automation simpler.
Below I will layout a simple directory traversal using
pattern matching to select multiple files.
Specifically, every file of type ".xlsx" will have it's first worksheet pulled into the workbook containing the macro.
Sub getDownloads()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
' *** WHAT YOU NEED TO CHANGE ***
Dim directory_Of_Downloads As String: directory_Of_Downloads = "C:\Users\[your name probably]\Downloads"
Dim fileName As Variant: fileName = Dir(directory_Of_Downloads & "\*.xlsx", vbDirectory)
Dim wb As Workbook
While Not fileName = ""
Set wb = Workbooks.Open(directory_Of_Downloads & "\" & fileName, ReadOnly:=True)
wb.Sheets(1).Copy Before:=ThisWorkbook.Sheets(1)
' If the sheet name in the source workbook is a duplicate of a pre-existing worksheet in our current workbook
' then the sheet will end up being named "Sheet (#)"
On Error Resume Next
ThisWorkbook.Sheets(1).Name = wb.Sheets(1).Name
On Error GoTo 0
' close the workbook
wb.Close SaveChanges:=False
'Delete the workbook -> If you are sure uncomment the below line
'Kill directory_Of_Downloads & "\" & fileName
' set fileName = The next file located at directory_Of_Downloads which meets our search criteria -> ".xlsx"
fileName = Dir
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Best of luck!

Using VBA in Excel to force save in directory

I have a huge Excel spreadsheet that I need to allow access to a large set of users so they can manipulate it for their customers, but I don't want them to be able to overwrite the original file (a variable easily set in Excel) or save their file outside the current folder - so I want to force them in a "saveas" mode, and force the file to be saved in that folder. Otherwise, they won't be able to save. I'm not much of a VBA person, and I've found a lot of examples that may work, but nothing seems to be exactly what I need or maybe I'm not smart enough to figure it out. I found this code, but I'm not sure it FORCES the issue. Help?
I've tried to manage this in GPOs but everything seems to give them access to download the folder and save in other places.
Sub ExampleToSaveWorkbookSet()
Dim wkb As Workbook
'Adding New Workbook
Set wkb = Workbooks.Add
'Saving the Workbook
wkb.SaveAs "C:\WorkbookName.xls"
'OR
'wkb.SaveAs Filename:="C:\WorkbookName1.xls"
End Sub
Expected output is the amended Excel file saved in the original directory with a different name, or not at all.
Here's a macro that runs on open and immediately saves as .xlsx to a user location you can specify. Unfortunately the original needs to be .xlsm to store a macro.
This macro is to be located in the "ThisWorkbook" object. It will exit before making a copy when you open the workbook.
Private Sub Workbook_Open()
Dim wb As Workbook
Set wb = ActiveWorkbook
vWbName = wb.Name
vUserProf = Environ("USERPROFILE")
vx = InStr(1, vUserProf, "Users\")
If "<Use your own profileID>" = Mid(vUserProf, vx + 6) Then Exit Sub
vDir = vUserProf & "\Downloads\"
vWbName = Left(vWbName, Len(vWbName) - 5) & ".xlsx"
wb.SaveAs vDir & vWbName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
MsgBox "You are now using a copy of the original"
End Sub

Merging workbooks into a new file

I'm trying to merge multiple Excel files from one Folder into a new file. I've found a solution on the Internet, that is adding my files into an open one. I'm not really into VBA Excel, so I think it's a basic problem, but I can't do it, things I've tried haven't worked properly. I would like to change the following code to create a new file called "summary" in the "Path" and copy the Sheets into this new file, overwriting the file every time I do it and deleting the several source files after doing this.
Is there a possibility of merging all those files into one without opening everyone of it?
Sub GetSheets()
Path = "C:\Merging\"
FileName = Dir(Path & "*.xls")
Do While FileName <> ""
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
End Sub
Your code almost works as is, just needs a couple of slight tweaks. I also agree with #AnalystCave that if this is a repeating exercise, you may consider a more streamlined solution. But this will work for you.
EDIT: changed to deal with existing destination file -- if it exists and is open, then connect to it otherwise open it; then delete all sheets in the existing file to prepare for the copies
Option Explicit
Function IsSheetEmpty(sht As Worksheet) As Boolean
IsSheetEmpty = Application.WorksheetFunction.CountA(sht.Cells) = 0
End Function
Sub GetSheets()
Dim Path, Filename As String
Dim Sheet As Worksheet
Dim newBook As Workbook
Dim appSheets As Integer
Dim srcFile As String
Dim dstFile As String
Dim dstPath As String
Dim wasntAlreadyOpen As Boolean
Application.ScreenUpdating = False 'go faster by not waiting for display
'--- create a new workbook with only one worksheet
dstFile = "AllSheetsHere.xlsx"
dstPath = ActiveWorkbook.Path & "\" & dstFile
wasntAlreadyOpen = True
If Dir(dstPath) = "" Then
'--- the destination workbook does not (yet) exist, so create it
appSheets = Application.SheetsInNewWorkbook 'saves the default number of new sheets
Application.SheetsInNewWorkbook = 1 'force only one new sheet
Set newBook = Application.Workbooks.Add
newBook.SaveAs dstFile
Application.SheetsInNewWorkbook = appSheets 'restores the default number of new sheets
Else
'--- the destination workbook exists, so ...
On Error Resume Next
wasntAlreadyOpen = False
Set newBook = Workbooks(dstFile) 'connect if already open
If newBook Is Nothing Then
Set newBook = Workbooks.Open(dstPath) 'open if needed
wasntAlreadyOpen = True
End If
On Error GoTo 0
'--- make sure to delete any/all worksheets so we're only left
' with a single empty sheet named "Sheet1"
Application.DisplayAlerts = False 'we dont need to see the warning message
Do While newBook.Sheets.Count > 1
newBook.Sheets(newBook.Sheets.Count).Delete
Loop
newBook.Sheets(1).Name = "Sheet1"
newBook.Sheets(1).Cells.ClearContents
newBook.Sheets(1).Cells.ClearFormats
Application.DisplayAlerts = True 'turn alerts back on
End If
Path = "C:\Temp\"
Filename = Dir(Path & "*.xls?") 'add the ? to pick up *.xlsx and *.xlsm files
Do While Filename <> ""
srcFile = Path & Filename
Workbooks.Open Filename:=srcFile, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
'--- potentially check for blank sheets, or only sheets
' with specific data on them
If Not IsSheetEmpty(Sheet) Then
Sheet.Copy After:=newBook.Sheets(1)
End If
Next Sheet
Workbooks(Filename).Close (False) 'add False to close without saving
Kill srcFile 'deletes the file
Filename = Dir()
Loop
'--- delete the original empty worksheet and save the book
If newBook.Sheets.Count > 1 Then
newBook.Sheets(1).Delete
End If
newBook.Save
'--- leave it open if it was already open when we started
If wasntAlreadyOpen Then
newBook.Close
End If
Application.ScreenUpdating = True 're-enable screen updates
End Sub
Firstly, regardless of your solution you will still need to OPEN every Excel workbook if you want to merge all of them.
Secondly, I think you might want to rephrase your question to "Is there a possibility of merging all those files into one faster or in any easier way?"
From the level of Excel VBA there is really no other way then opening each Workbook within the same Application level. If this is a one-time exercise I would stick to the code you already have and bear with it.
However, if this is an exercise you will be doing repeatedly and need an efficient solution, your only option is resorting to the OpenXML format which does not require a heavyweight Excel process e.g. creating a C# solution using the ClosedXML library. This will definitely reduce the time needed to consolidate your workbooks.

csv output from excel error but other data types work correctly?

Ok I am attempting to write a Macro that saves an excel Workbook into a csv file. I have tried many different solutions but I am still having issues getting the values to print properly. when I open the file it produces. The rest of the code I left out all it does is takes the original spreadsheet and copys the contents into a temporary sheet so I can take multiple sheets from the same WB and print them to the same csv file. it also has a module that will clear all formatting and contents of that temporary file. I ran the code to just print it to a new excel spreadsheet and it worked fine just will not print to a csv not sure why
out put looks like this:
K ! bîh^ [Content_Types].xml ¢(
[… skip a bunch of binary lines …]
KÆ8k¡~¥-ÙÔäá ûÜ
My code looks like this:
Sub SaveFile()
Dim NewName As String
Dim nm As Name
Dim ws As Worksheet
If MsgBox("Copy specific sheets to a new workbook" & vbCr & _
"New sheets will be pasted as values, named ranges removed" _
, vbYesNo, "NewCopy") = vbNo Then Exit Sub
With Application
.ScreenUpdating = False
' Copy specific sheets
' *SET THE SHEET NAMES TO COPY BELOW*
' Array("Sheet Name", "Another sheet name", "And Another"))
' Sheet names go inside quotes, seperated by commas
On Error GoTo ErrCatcher
Sheets(Array("Raw Data Copy")).copy
On Error GoTo 0
' Paste sheets as values
' Remove External Links, Hperlinks and hard-code formulas
' Make sure A1 is selected on all sheets
For Each ws In ActiveWorkbook.Worksheets
ws.Cells.copy
ws.[A1].PasteSpecial Paste:=xlValues
ws.Cells.Hyperlinks.Delete
Application.CutCopyMode = False
Cells(1, 1).Select
ws.Activate
Next ws
Cells(1, 1).Select
' Remove named ranges
For Each nm In ActiveWorkbook.Names
nm.Delete
Next nm
' Input box to name new file
NewName = "test"
' Save it with the NewName and in the same directory as original
ActiveWorkbook.SaveCopyAs ThisWorkbook.path & "\" & NewName & ".csv"
ActiveWorkbook.Close SaveChanges:=False
.ScreenUpdating = True
End With
Exit Sub
ErrCatcher:
MsgBox "Specified sheets do not exist within this workbook"
End Sub
SaveCopyAs only saves an Excel Workbook in Excel format. Even if you append .csv to your filename, the file is still an .xls formatted file.
The Workbook SaveAs method lets you to specify the type of file you want to save to.
However, if you use the SaveAs method, it changes the name of your current file.
This earlier question on Stack Overflow has some options on how to use the SaveAs method without changing the name of the file you are working on.
Why does VBA ActiveWorkbook.SaveAs change the open spreadsheet? has some comments on how to properly use the SaveAs method and not have the name of your current file changed in the process.

Why does VBA ActiveWorkbook.SaveAs change the open spreadsheet?

My function is as follows:
Sub saveCSV()
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:= _
"c:\temp\file.csv", FileFormat:=xlCSV _
, CreateBackup:=False
End Sub
I'm trying to export the active worksheet to CSV. When I run the code in the title, Book1.xlsm changes to file.csv and Sheet1 changes to file. The export works fine. How can I do the export without these unwanted side effects?
That's always how SaveAs has worked. The only way to get around this is to copy the worksheet and do a SaveAs on the copy, then close it.
EDIT: I should add an example as it's not that difficult to do. Here's a quick example that copies the ActiveSheet to a new workbook.
Dim wbk As Workbook
Set wbk = Workbooks.Add
ActiveSheet.Copy wbk.Sheets(1) ' Copy activesheet before the first sheet of wbk
wbk.SaveAs ....
wbk.Close
A complicated workbook may get issues with links and macros, but in ordinary scenarios this is safe.
EDIT 2: I'm aware of what you're trying to do, as your other question was about trying to trigger an export on every change to the sheet. This copy sheet approach presented here is likely to be highly disruptive.
My suggestion is to write a CSV file by hand to minimise GUI interruption. The sheet is likely to become unusable if the saves are occurring at high frequency. I wouldn't lay the blame for this at the door of Excel, it simply wasn't built for rapid saves done behind the scenes.
Here's a little routine that does what you want by operating on a copy of the original ... copy made via file scripting object. Hardcoded to operate on "ThisWorkbook" as opposed to active workbook & presumes ".xlsm" suffix - could tweak this to do the job I think:
Public Sub SaveCopyAsCsv()
Dim sThisFile As String: sThisFile = ThisWorkbook.FullName
Dim sCsvFile As String: sTempFile = Replace(sThisFile, ".xlsm", "_TEMP.xlsm")
ThisWorkbook.Save ' save the current workbook
' copy the saved workbook ABC.xlsm to TEMP_ABC.xlsm
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Call fso.deletefile(sTempFile, True) ' deletes prev temp file if it exists
On Error GoTo 0
Call fso.CopyFile(sThisFile, sTempFile, True)
' open the temp file & save as CSV
Dim wbTemp As Workbook
Set wbTemp = Workbooks.Open(sTempFile) ' open the temp file in excel
' your prev code to save as CSV
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileName:="c:\temp\file.csv", FileFormat:=xlCSV, CreateBackup:=False
wbTemp.Close ' close the temp file now that the copy has been made
Application.DisplayAlerts = True
' delete the temp file (if you want)
On Error Resume Next
Call fso.deletefile(sTempFile, True) ' deletes the temp file
On Error GoTo 0
End Sub

Resources