New Excel VBA compile error upon saving workbooks - vba

I have been using the code below to successfully create and save a new workbook for each worksheet in my workbook. When I try to run it now I get an error "Compile Error Wrong number of arguments or invalid property assignments". I cannot see why it is not working now; it did before. I do want the date in the final name. If I run the code with the wb.SaveAs line marked with ' it works fine. It doesn't seem to like the format part now. Any ideas what is different and why? Thank-you.
Sub Make_Workbooks()
Dim ws As Worksheet
Dim wb As Workbook
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
For Each ws In ThisWorkbook.Worksheets
Set wb = Workbooks.Add
'wb.SaveAs ThisWorkbook.Path & "\" & ws.Name
wb.SaveAs ThisWorkbook.Path & "\" & ws.Name & Format(Date, "yyyy-mm-dd") & ".xlsx"
ws.Copy Before:=wb.Worksheets(1)
wb.Close SaveChanges:=True
Next ws
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

The syntax used to use the SaveAs should be FileName, FileFormat, ....
In your code it should be:
wb.SaveAs ThisWorkbook.Path & "\" & ws.Name & Format(Date, "yyyy-mm-dd"), xlOpenXMLWorkbook
(xlOpenXMLWorkbook = ".xlsx")
If you will run your code a few times every day, you will get a message if you want to overwrite the existing file since ThisWorkbook.Path & "\" & ws.Name & Format(Date, "yyyy-mm-dd") will have the same String on the same day.
If you want to automatically overwrite your previous file, then add the line Application.DisplayAlerts = False.
Code
Option Explicit
Sub Make_Workbooks()
Dim ws As Worksheet
Dim wb As Workbook
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
For Each ws In ThisWorkbook.Worksheets
Set wb = Workbooks.Add
' add this line to automatically overwrite the exisitng file (not getting the MsgBox on every time)
Application.DisplayAlerts = False
wb.SaveAs ThisWorkbook.Path & "\" & ws.Name & Format(Date, "yyyy-mm-dd"), xlOpenXMLWorkbook
ws.Copy Before:=wb.Worksheets(1)
wb.Close SaveChanges:=True
Next ws
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Edit1: If you want to make sure 2 file names never have the same name, you can use the Now function:
wb.SaveAs ThisWorkbook.Path & "\" & ws.Name & Format(Now, "yyyy-mm-dd_hh_mm_ss"), xlOpenXMLWorkbook

I can't replicate your problem on my system, but the following code minimizes the explicit creation and tracking of new Workbook objects, so it may be less error-prone across different environments:
Sub Make_Workbooks()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Copy 'Copies current sheet to new workbook
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\" & ws.Name & "_" & Format(Date, "yyyy-mm-dd") & ".xlsx"
ActiveWindow.Close
Next ws
End Sub

Related

Export multiple worksheets to CSV and specify save folder

I've got this Macro working beautifully, but every now and again it will save the exported sheets into the last folder I was working in, and not the specific folder I want them in. How do I specify the folder they should go into?
Sub asdf()
Dim ws As Worksheet, newWb As Workbook
Application.ScreenUpdating = False
For Each ws In Sheets(Array("sheet1", "sheet2", "sheet3"))
ws.Copy
Set newWb = ActiveWorkbook
With newWb
.SaveAs ws.Name & ".csv", xlCSVWindows
.Close (False)
End With
Next ws
Application.ScreenUpdating = True
End Sub
You need to specify the location you want it saved to in the code.
Try this.
.SaveAs FileName:="C:\OutputFilepath\" & ws.Name & ".csv", FileFormat:=xlCSV, CreateBackup:=False
Replace this line
.SaveAs ws.Name & ".csv", xlCSVWindows
With
.SaveAs "D:\MyFolder\" & ws.Name & ".csv", xlCSVWindows
Change the "D:\MyFolder\" to your desired path.
Add a string type var that contains the full path to the folder. In the following example, I'll use the temp directory.
Sub asdf()
Dim ws As Worksheet, newWb As Workbook, fp as string
fp = environ("TEMP") & Chr(92)
'could be something like
'fp = environ("USER") & "\desktop\"
Application.ScreenUpdating = False
For Each ws In Sheets(Array("sheet1", "sheet2", "sheet3"))
ws.Copy
Set newWb = ActiveWorkbook
With newWb
.SaveAs fp & ws.Name, xlCSVWindows 'add the path, let saveas add the extension
.Close savechanges:=False
End With
Next ws
Application.ScreenUpdating = True
End Sub

copy all workbook sheets to a new workbook VBA

I am using this code to copy every sheet in a workbook to a new one and it works fine but it reverses the order of the sheets, would there be anyway to keep it from doing this?
Sub copy()
'copies all the sheets of the open workbook to a new one
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
'save vba code here
Application.Dialogs(xlDialogSaveAs).Show Range("CA1").Text & "- (Submittal) " & Format(Date, "mm-dd-yy") & "_" & Format(Time, "hhmm") & ".xlsx"
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
I'm copying all the sheets so i can save it as a different file extension and this was the only way i found that worked.
Workbook before it copies
Workbook after it copies
From Scott Craner's comment, which OP replied to indicating it worked:
Change
ws.copy After:=wbTemp.Sheets(1)
to:
ws.copy After:=wbTemp.Sheets(wbTemp.Worksheets.Count)
If you only want to change the file format
(I'm copying all the sheets so i can save it as a different file extension and this was the only way i found that worked.)
Then you can try this code:
Sub Test()
fn = Range("CA1").Text & "- (Submittal) " & Format(Now, "mm-dd-yy_hhmm")
fileSaveName = Application.GetSaveAsFilename(InitialFileName:=fn, fileFilter:="Excel Workbook (*.xlsx), *.xlsx")
If fileSaveName <> False Then
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs fileSaveName, xlOpenXMLWorkbook
Application.DisplayAlerts = True
End If
End Sub

Saving Active Workbook when using Macro from Add-In

I created a macro that saves the value of an .xlsx file to a csv in a certain directory with the name of the csv = to the name of the Excel file which it was written from.
I wanted this macro to be available in any spreadsheet/workbook so I saved and added it as an add in.
I think I am having issues with ActiveWorkbook vs Thisworkbook.
The following code is the original that works as intended when not used as an add in:
Sub CSV()
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
SaveToDirectory = "C:\SomeDirectory\"
For Each WS In ThisWorkbook.Worksheets
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & ThisWorkbook.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
ThisWorkbook.Activate
Next
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = False
End Sub
However if that code is used in the add in, the file saves with the name of the add in. So I changed the code and used ActiveWorkbook but it appears the value gets changed when it is time to save.
Sub CSV2()
On Error GoTo error_handler
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ActiveWorkbook.Name
CurrentFormat = ActiveWorkbook.FileFormat
SaveToDirectory = "C:\SomeDirectory\"
For Each WS In ActiveWorkbook.Worksheets
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & ThisWorkbook.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
ThisWorkbook.Activate
Next
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = False
error_handler:
MsgBox Err.Description
End Sub
I want to write my Excel file to csv. Save that CSV in the directory that is defined. With the name of the csv = the name of the file that the information is coming from. And to be able to do this in any workbook I open.
Try this code:
Sub CSV2()
On Error GoTo error_handler
Dim aWB As Workbook
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
Set aWB = ActiveWorkbook
CurrentWorkbook = aWB.Name
CurrentFormat = aWB.FileFormat
SaveToDirectory = "C:\SomeDirectory\"
For Each WS In aWB.Worksheets
WS.Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & aWB.Name & "_" & WS.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
'ThisWorkbook.Activate
Next
Application.DisplayAlerts = False
aWB.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = False
Exit Sub
error_handler:
MsgBox Err.Description
End Sub
I add ws.name after awb.name to prevent the same file name.

Automatically save certain sheets in workbook to CSV file

I have found a decent solution Saving excel worksheet to CSV files with filename+worksheet name using VB for saving all worksheets in a workbook as CSV files. However, I would like to be able to modify this code to only save worksheets where the sheet name ends with _t.
I am using the following code:
Sub SaveWorksheetsAsCsv()
Dim WS As Excel.Worksheet
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
' Store current details for the workbook
SaveToDirectory = "H:\test\"
For Each WS In ThisWorkbook.Worksheets
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & ThisWorkbook.Name & "-" & 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
Can this be done?
Use the Right or Instr-Method on the worksheet.name property to get the last characters / check if your searchstring is exisiting.
In your for each-loop add the following code:
If Right(WS.name, 2) = "_t" Then
Sheets(WS.Name).Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & ThisWorkbook.Name & "-" & WS.Name & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close savechanges:=False
ThisWorkbook.Activate
End if

Excel VBA Creating/overwriting a new workbook and using the cancel button

I have a macro written that take a range from one workbook and copies into into a new workbook, which then saves the newly created workbook (and gives it a name) into the same folder path. When this workbook already exists, (overwriting the workbook), the default windows dialogue box pops up asking if you would like to overwrite, with a yes no cancel selection of buttons. When the cancel button is pressed, a new workbook is created. How do I edit this code so that when cancel is pressed, no new workbook is created? I have pasted the macro below:
Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook
Set ThisWB = ActiveWorkbook
Set NewBook = Workbooks.Add
On Error Resume Next
ThisWorkbook.Worksheets("Summary").Range("A1:I100").Copy
NewBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
NewBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
NewBook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit
NewBook.SaveAs Filename:=ThisWB.Path & "\" & NewBook.Worksheets("Sheet1").Range("A4").Value & "_Summary"
NewBook.ActiveSheet.Range("A1").Select
Application.ScreenUpdating = True
End Sub
EDIT: WORKING CODE SHOWN BELOW
Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook
Dim fname As String
Set ThisWB = ActiveWorkbook
Set Newbook = Workbooks.Add
ThisWorkbook.Worksheets("Summary").Range("A1:I100").Copy
Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
Newbook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit
fname = ThisWB.Path & "\" & ThisWB.Worksheets("Summary").Range("A4").Value & "_Summary.xls"
If Dir(fname) <> "" Then
If MsgBox("Summary output already exists, are you sure you want to overwrite?", vbOKCancel) = vbCancel Then Newbook.Close False: Application.CutCopyMode = False: Exit Sub
End If
Application.DisplayAlerts = False
Newbook.SaveAs Filename:=fname
Application.DisplayAlerts = True
ThisWB.Activate
ActiveWorkbook.Worksheets("Summary").Range("A1").Select
Newbook.Activate
ActiveWorkbook.ActiveSheet.Range("A1").Select
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Thank you!
On error resume next is seldom a good idea. If the user selects no or cancel, an error is triggered. Better to handle that error to delete the unwanted workbook (although another idea is to test if a workbook with the target name exists before creating it and, if it does, use msgbox to ask the user if they want to overwrite the file and, if so, only then create the workbook, disable alerts, and only then do saveas).
A problem seems to be that you need to have a filename to kill a workbook. In your situation the workbook doesn't yet have a filename. One solution is to create a safe filename whose sole purpose in life is to kill an unwanted workbook, do saveas again with this name, then kill it. Something like this:
Sub Test()
On Error GoTo err_handler
Dim wb As Workbook
Dim fname As String
Dim tempname As String
fname = "C:\Programs\testbook.xlsx"
Set wb = Workbooks.Add
wb.Sheets(1).Range("A1").Value = Now 'for testing purposes
wb.SaveAs fname
Exit Sub
err_handler:
tempname = "C:\Programs\name_i_will_never_use.xlsx"
wb.SaveAs tempname
wb.Close
Kill tempname
End Sub
Here is a possible approach:
Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook, Newbook As Workbook
Dim fname As String
Set ThisWB = ActiveWorkbook
fname = ThisWB.Path & "\" & ThisWB.Sheets("Sheet1").Range("A4").Value & "_Summary"
If Dir(fname) <> "" Then
If MsgBox("Are you sure you want to overwrite?", vbOKCancel) = vbCancel Then Exit Sub
End If
Set Newbook = Workbooks.Add
ThisWB.Worksheets("Summary").Range("A1:I100").Copy
Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteValues)
Newbook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteFormats)
Newbook.Worksheets("Sheet1").Range("A:J").Columns.AutoFit
'This code should be faster since it bypasses the copy-paste buffer
'With Newbook.Sheets(1)
' ThisWB.Sheets("Summary").Range("A1:I100").Copy .Range("A1")
' .Range("A1:I100").Value = .Range("A1:I100").Value
' .Columns.AutoFit
'End With
Application.DisplayAlerts = False
Newbook.SaveAs Filename:=fname
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
this is the full code with
check if file already exist
if exist close the newbook and ask you if the existed file will be opened
close the newbook
in case of error save the newbook with (error) suffix before the extension file
Sub ExportNewBook()
Application.ScreenUpdating = False
Dim ThisWB As Workbook
Dim NewName As String
Set ThisWB = ActiveWorkbook
Set NewBook = Workbooks.Add
On Error GoTo err_handler
ThisWB.Worksheets("Summary").Range("A1:I100").Copy
NewBook.Worksheets("Foglio1").Range("A1").PasteSpecial (xlPasteValues)
NewBook.Worksheets("Foglio1").Range("A1").PasteSpecial (xlPasteFormats)
NewBook.Worksheets("Foglio1").Range("A:J").Columns.AutoFit
NewName = ThisWB.Path & "\" & NewBook.Worksheets("Foglio1").Range("A4").Value & "_Summary.xls"
If Dir(NewName) "" Then
If MsgBox("A file named '" & NewName & " already exists." & vbCr & vbCr & _
MeaName & " will now open??", vbYesNo) = vbYes Then
Workbooks.Open NewName
End If
NewBook.Close False
Exit Sub
End If
NewBook.SaveAs Filename:=NewName
NewBook.ActiveSheet.Range("A1").Select
NewBook.Close
Application.ScreenUpdating = True
err_handler:
NewName = ThisWB.Path & "\" & NewBook.Worksheets("Foglio1").Range("A4").Value & "_Summary(error).xls"
NewBook.SaveAs Filename:=NewName
NewBook.ActiveSheet.Range("A1").Select
NewBook.Close
Application.ScreenUpdating = True
End Sub