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

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

Related

VBA Copy Method keeps failing?

I could have sworn that this was working before - but for some reason, this doesn't appear to be working anymore. I'm trying to take the active worksheet (also, this may not be very pretty or clean, but I am still really new to VBA), copy it to a new worksheet, in the new worksheet I want to open the Excel save as dialog, and when the worksheet is saved (in CSV) format, I want the workbook to close (or even if it doesn't close) at least return the user to the original workbook and end the sub
Sub saveExportAs()
Application.CutCopyMode = False
Sheets("load").Select
ActiveWorkbook.Activate
Sheets("load").Copy
Dim varResult As Variant
Dim ActBook As Workbook
'display the save as dialog
varResult = Application.GetSaveAsFilename(InitialFileName:="\\network\folder\upload_" & Format(Date, "yyyy-mm-dd") & ".csv", FileFilter:= _
"Comma Delimited / Upload Files (*.csv),*.csv", Title:="Save Upload File")
'check to make sure the user didn't cancel
If varResult <> False Then
ActiveWorkbook.saveAs Filename:=varResult, _
FileFormat:=xlCSV
Exit Sub
End If
End Sub
you can use the sheets defined as workbook/worksheet to avoid issues... may be like this :
Sub saveExportAs()
Dim wb1, wb2 As Workbook
Dim ws As Worksheet
Dim varResult As Variant
Set wb1 = ThisWorkbook
Set ws = ThisWorkbook.Worksheets("load")
ws.Copy
Set wb2 = ActiveWorkbook
varResult = Application.GetSaveAsFilename(InitialFileName:="\\network\folder\upload_" & Format(Date, "yyyy-mm-dd") & ".csv", FileFilter:= _
"Comma Delimited / Upload Files (*.csv),*.csv", Title:="Save Upload File")
If varResult <> False Then
wb2.SaveAs Filename:=varResult, FileFormat:=xlCSV
wb2.Close Savechanges:=True
Exit Sub
End If
wb1.Activate
End Sub
Try this...
Sub exportAsCSV()
Dim wb As Workbook
Set wb = ActiveWorkbook
SaveCopyAsCSV ("Sheet1") ' replace Sheet1 with whatever sheet name you need
wb.Activate
End Sub
Private Function SaveCopyAsCSV(SourceSheet As String)
Application.DisplayAlerts = False
ThisWorkbook.Sheets(SourceSheet).copy
ActiveWorkbook.SaveAs fileName:=SourceSheet, FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Function

New Excel VBA compile error upon saving workbooks

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

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

Cycle a vba function through all workbooks in a folder

I want to cycle through all workbooks in a folder, extract worksheets named "Sheet Name", and save them as .csv files with the name of the file from which they originated. What's quick way to do this?
Example of vba function in question:
Sub Sheet_SaveAs()
Dim wb As Workbook
Sheets("Sheet Name").Copy
Set wb = ActiveWorkbook
With wb
.SaveAs ThisWorkbook.Path & "\" & ThisWorkbook.name, FileFormat:=xlCSV
'.Close False
End With
End Sub
Many thanks for looking
EDIT: Not a duplicate because I am working on extracting sheets from multiple workbooks, and not multiple worksheets from a single workbook.
EDIT2: thank you, everyone.
Something like this.
Change this path to suit your folder
strFolder = "c:\temp"
code
Sub LoopThroughFiles()
Dim Wb As Workbook
Dim ws As Worksheet
Dim strFolder As String
Dim strFile As String
strFolder = "c:\temp"
strFile = Dir(strFolder & "\*.xls*")
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
Do While Len(strFile) > 0
Set Wb = Workbooks.Open(strFolder & "\" & strFile)
Set ws = Nothing
On Error Resume Next
Set ws = Wb.Sheets("Sheet Name")
On Error GoTo 0
If Not ws Is Nothing Then ws.SaveAs Left$(Wb.FullName, InStrRev(Wb.FullName, ".")) & "csv", FileFormat:=xlCSV
Wb.Close False
strFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub

Copy another worksheet along if formulas on the main worksheet refert to it Excel VBA

Problem I have is, when I am saving my my worksheet as another workbook using code below I also need to copy additional worksheet only on one occasion when formulas on the worksheet I intend to save refer to the "Price List" worksheet, which I would need to also save along with the first worksheet. I hope it make sense. Also another small problem, when I save worksheet as a new workbook, I need that workbook to open imedietly, so that I can then continue to work with that workbook.
Here is my code
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In Worksheets
If InStr(LCase(ws.Name), "template") <> 0 Then
cmbSheet.AddItem ws.Name
End If
Next ws
End Sub
'Continue to create your invoice and check for the archive folder existance
Private Sub ContinueButton_Click()
If cmbSheet.Value = "" Then
MsgBox "Please select the Invoice Template from the list to continue."
ElseIf cmbSheet.Value <> 0 Then
Dim response
Application.ScreenUpdating = 0
'Creating the directory only if it doesn't exist
directoryPath = getDirectoryPath
If Dir(directoryPath, vbDirectory) = "" Then
response = MsgBox("The directory " & Settings.Range("_archiveDir").Value & " does not exist. Would you like to create it?", vbYesNo)
If response = vbYes Then
createDirectory directoryPath
MsgBox "The folder has been created. " & directoryPath
Application.ScreenUpdating = False
Else
MsgBox "You need to create new folder " & Settings.Range("_archiveDir").Value & " to archive your invoices prior to creating them."
GoTo THE_END
End If
End If
If Dir(directoryPath, vbDirectory) <> directoryPath Then
Sheets(cmbSheet.Value).Visible = True
'Working in Excel 97-2007
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim Sourcewb As Workbook
Set Sourcewb = ActiveWorkbook
Dim Destwb As Workbook
Dim TempFilePath As String
Dim TempFileName As String
Dim fName As String
Dim sep As String
sep = Application.PathSeparator
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Copy the sheet to a new workbook
Sourcewb.Sheets(cmbSheet.Value).Copy
Set Destwb = ActiveWorkbook
'Determine the Excel version and file extension/format
With Destwb
If Val(Application.Version) < 12 Then
'You use Excel 97-2003
FileExtStr = ".xls": FileFormatNum = -4143
Else
If Sourcewb.Name = .Name Then
GoTo THE_END
Else
Select Case Sourcewb.FileFormat
Case 51: FileExtStr = ".xlsx": FileFormatNum = 56
End Select
End If
End If
End With
'Copy current colorscheme to the new Workbook
For i = 1 To 56
Destwb.Colors(i) = Sourcewb.Colors(i)
Next i
'If you want to change all cells in the worksheet to values, uncomment these lines.
'With Destwb.Sheets(1).UsedRange
'With Sourcewb.Sheets(cmbSheet.Value).UsedRange
' .Cells.Copy
' .Cells.PasteSpecial xlPasteValues
' .Cells(1).Select
'End With
Application.CutCopyMode = False
'Save the new workbook and close it
Destwb.Sheets(1).Name = "Invoice"
fName = Home.Range("_newInvoice").Value
TempFilePath = directoryPath & sep
TempFileName = fName
With Destwb
.SaveAs TempFilePath & TempFileName, FileFormat:=FileFormatNum
.Close SaveChanges:=False
End With
MsgBox "You can find the new file in " & TempFilePath & TempFileName
End If
End If
THE_END:
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
Unload Me
End Sub
If I'm understanding you correctly, based on what you said you need to do two things:
Copy a worksheet when formulas contain references to the "Price List" worksheet
Save the new worksheet as a new workbook and open immediately
Here is code to paste in a module:
Sub IdentifyFormulaCellsAndCopy()
'******** Find all cells that contain formulas and highlight any that refer to worksheet 'price list' **********
Dim ws As Worksheet
Dim rng As Range
Set ws = ActiveSheet
For Each rng In ws.Cells.SpecialCells(xlCellTypeFormulas)
If InStr(LCase(rng.Formula), "price list") <> 0 Then
'Highlight cell if it contains formula
rng.Interior.ColorIndex = 36
End If
Next rng
'*******************************************************************************************************************
'********* Save worksheet as new workbook, then activate and open immediately to begin work on it *******************
'Hide alerts
Application.DisplayAlerts = False
Dim FName As String
Dim FPath As String
Dim NewBook As Workbook
FPath = "C:\Users\User\Desktop"
FName = "CopiedWorksheet " & Format(Date, "yyyy-mm-dd") & ".xls"
'Create a new workbook
Set NewBook = Workbooks.Add
'Copy the 'template' worksheet into new workbook
ThisWorkbook.Sheets("template").Copy Before:=NewBook.Sheets(1)
'If file doesn't already exist, then save new workbook
If Dir(FPath & "\" & FName) <> "" Then
MsgBox "File " & FPath & "\" & FName & " already exists"
Else
NewBook.SaveAs Filename:=FPath & "\" & FName
End If
'Activate workbook that you just saved
NewBook.Activate
'Show Alerts
Application.DisplayAlerts = True
'**********************************************************************************************************************
End Sub
Notes:
Depending on how you implement this code, you can add Application.ScreenUpdating = False to speed things up.
Also, this code assumes that you have worksheets with the names of template and Price List.