Running multiple macros to create separate workbooks - vba

I have a macro written to take selected sheets from one workbook, and copy those to another workbook, saving it under a new name. I need to run this same query repeatedly until I create about 6 separate files. Each individual macro works, and I can call them each up one at a time, but they will not run sequentially. I believe I know that the problem lies in the fact that the code I have written will not reference back to the source workbook, and I don’t know how to write code to do it.
The attached code is what I am using, and it may seem a bit sloppy – I put together pieces from several different macros to get this to work. Gqp Master is the name of the master workbook that all the other workbooks are being created from.
Sub Snuth()
'This will prevent the alet from popping up when overwriting graphs, etc
Application.DisplayAlerts = False
Dim FName As String
Dim FPath As String
Dim NewBook As Workbook
Dim strFileName As String
Dim WS As Worksheet
Dim WBk As Workbook
Set WBk = ("Gap Master")
For Each WS In Worksheets
WS.Visible = True
Next
For Each WS In Worksheets
If WS.Range("C4") <> "Snuth, John" Then
WS.Visible = False
End If
If WS.Range("C4") = "Snuth, John" Then
WS.Visible = True
End If
Next WS
FPath = "C:\Users\mmarshall\Documents\GAP\GAP Development"
FName = "Snuth GAP " & Format(Date, "yyyy-mm-dd") & ".xlsx"
Set NewBook = Workbooks.Add
ThisWorkbook.Sheets.Copy Before:=NewBook.Sheets(1)
Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select
ActiveWindow.SelectedSheets.Delete
If Dir(FPath & "\" & FName) <> "" Then
MsgBox "File " & FPath & "\" & FName & " already exists"
Else
NewBook.SaveAs Filename:=FPath & "\" & FName
End If
Application.DisplayAlerts = True
End Sub

I am assuming you have several other macros that do, more or less, the exact same thing, just for different manager names.
You can create a master subroutine that will invoke other subs/functions. What this does is send some arguments/parameters to a subroutine, these are
WBk: the workbook you're copying from
lastName: the manager's last name
firstName: the manager's first name
Here is the code:
Sub CreateCopies()
Dim WBk As Workbook
Set WBk = Workbooks("Gap Master")
'# Run the CopyForName for each of your manager names, e.g.:
CopyForName WBk, "Snuth", "John"
CopyForName WBk, "Zemens", "David"
CopyForName WBk, "Bonaparte", "Napoleon"
CopyForName WBk, "Mozart", "Wolfgang"
End Sub
Now, some revisions to your subroutine so that it is generic enough to perform the function for all managers:
Sub CopyForName(wkbkToCopy as Workbook, lastName as String, firstName As String)
'This will prevent the alert from popping up when overwriting graphs, etc
Application.DisplayAlerts = False
Dim FName As String
Dim FPath As String
Dim NewBook As Workbook
Dim strFileName As String
Dim WS As Worksheet
FPath = "C:\Users\mmarshall\Documents\GAP\GAP Development"
FName = lastName & " GAP " & Format(Date, "yyyy-mm-dd") & ".xlsx"
'## I consolidated your 3 loops in to 1 loop
For Each WS In wkbkToCopy.Worksheets
WS.Visible = (WS.Range("C4") = lastName & ", " & firstname)
Next
Set NewBook = Workbooks.Add
'Copies sheets from your Gap Master file:
wkbkToCopy.Sheets.Copy Before:=NewBook.Sheets(1)
'## I think you're trying to delete the default sheets in the NewBook:
NewBook.Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Delete
If Dir(FPath & "\" & FName) <> "" Then
MsgBox "File " & FPath & "\" & FName & " already exists"
Else
NewBook.SaveAs Filename:=FPath & "\" & FName
NewBook.Close
End If
Application.DisplayAlerts = True
End Sub

Try this:
After your line:
NewBook.SaveAs Filename:=FPath & "\" & FName
insert:
NewBook.Close
This should cause you to "fall back" to the original workbook.

Try this:
Step1:
Change
Set WBk = ("Gap Master")
To
Set WBk = ActiveWorkbook
Step 2:
Also add another line:
Set NewBook = Workbooks.Add
WBk.Activate '''''add this line''''''
ThisWorkbook.Sheets.Copy Before:=NewBook.Sheets(1)

Here is what I came up with, cobbling together several different pieces of code:
Sub VPFiles()
Dim WBk As Workbook
Set WBk = ThisWorkbook
'# Run the CopyForName for each of your manager names, e.g.:
CopyForName WBk, "Doe", "Christopher"
CopyForName WBk, "Smith", "Mark"
CopyForName WBk, "Randall", "Tony"
CopyForName WBk, "Jordan", "Steve"
CopyForName WBk, "Marshall", "Ron"
End Sub
Followed By This:
Sub CopyForName(wkbkToCopy As Workbook, lastName As String, firstName As String)
'This will prevent the alert from popping up when overwriting graphs, etc
Application.DisplayAlerts = False
Dim FName As String
Dim FPath As String
Dim NewBook As Workbook
Dim strFileName As String
Dim WS As Worksheet
FPath = "\\filesrv1\department shares\Sales"
FName = lastName & " GAP " & Format(Date, "yyyy-mm-dd") & ".xlsx"
'## I consolidated your 3 loops in to 1 loop
For Each WS In wkbkToCopy.Worksheets
WS.Visible = (WS.Range("K4") = lastName & ", " & firstName)
Next
Set NewBook = Workbooks.Add
'Copies sheets from your Gap Master file:
wkbkToCopy.Sheets.Copy Before:=NewBook.Sheets(1)
'This delets all unnecessary sheets in the NewBook:
NewBook.Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Delete
For Each WS In Worksheets
If WS.Visible <> True Then WS.Delete
Next
NewBook.SaveAs Filename:=FPath & "\" & FName
NewBook.Close
Application.DisplayAlerts = True
End Sub

Related

Excel VBA: Runtime Error 1004 When Deleting Sheet1

I'm still working on learning VBA, so this might be a dumb question, but I'm looking to loop through a workbook of ~ 90-95 sheets, break each out into its own workbook, and save it as the name of the worksheet from the original file.
The script works, but only if I comment out the .Worksheets(1).Delete, and I'm wondering why...It throws a 1004 error on both sheets that I'm running it against, but not in the same spot. The first sheet errors out on tab 4, the second on tab 40-something.
Right now I've got the FileNamePrefix variable set up to toggle, because I'm running this in the VBA window under "ThisWorkbook", since I haven't figured out how to run this macro from its own sheet, and choose the prefix based on the name/extension of the file it maps to. (AC comes to me as a .xlsm, CC as a .xlsx) That is still on my to-do, so no spoilers, please! :)
Macro:
Sub Sheet_SaveAs()
Dim wb As Workbook
Dim WS_Count As Integer
Dim ActiveSheetName As String
Dim ws As Worksheet
Dim FileNamePrefix As String
Dim FileName As String
Dim FilePath As String
'FileNamePrefix = "CC Dashboard "
FileNamePrefix = "AC Dashboard "
WS_Count = ActiveWorkbook.Worksheets.Count
MsgBox (" This will create: " & WS_Count & " Files")
For Each ws In ThisWorkbook.Worksheets
Set wb = Workbooks.Add(xlWBATWorksheet)
With wb
ThisWorkbook.Worksheets(ws.Name).Copy After:=.Worksheets(.Worksheets.Count)
Application.DisplayAlerts = False
.Worksheets(1).Delete
Application.DisplayAlerts = True
.SaveAs ThisWorkbook.Path & "\" & FileNamePrefix & ws.Name
.Close False
End With
ws.Name = FileNamePrefix & ws.Name
Next
MsgBox (" Done! ")
End Sub
So lets get rid of the Delete and just create the new file with only the worksheet you want. I also did a little clean up on your code.
Sub Sheet_SaveAs()
Dim wb As Workbook
Dim WS_Count As Integer
Dim ActiveSheetName, FileNamePrefix, FileName, FilePath As String
Dim ws As Worksheet
'FileNamePrefix = "CC Dashboard "
FileNamePrefix = "AC Dashboard "
WS_Count = ActiveWorkbook.Worksheets.Count
MsgBox (" This will create: " & WS_Count & " Files")
For Each ws In ThisWorkbook.Worksheets
ws.Copy 'this creates a new file with only the one sheet, so no Delete needed
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\" & FileNamePrefix & ws.Name
ActiveWorkbook.Close False
Next
MsgBox (" Done! ")
End Sub

VBA Export Sheets to Separate CSV Starting at Sheet 4 and beyond

as the title suggests, I'm trying to export sheets (starting from the fourth sheet and beyond, this is a fixed value) to separate CSV files. Ideally it would be right into a folder on the desktop containing each files. Below is the code I've been working with / trying to tweak-
Sub ExportSheetsToCSV()
Dim xWs As Worksheet
Dim xcsvFile As String
For Each xWs In Application.ActiveWorkbook.Worksheets
xWs.Copy
xcsvFile = CurDir & "\" & xWs.Name & ".csv"
Application.ActiveWorkbook.SaveAs Filename: = xcsvFile, _
FileFormat: = xlCSV, CreateBackup: = False
Application.ActiveWorkbook.Saved = True
Application.ActiveWorkbook.Close
Next
End Sub
Use the worksheets collection index.
Sub ExportSheetsToCSV()
Dim xWs As Worksheet
Dim xcsvFile As String, w as long
For w=4 to ActiveWorkbook.Worksheets.count
with ActiveWorkbook.Worksheets(w)
xcsvFile = CurDir & "\" & .Name & ".csv"
.Copy
with ActiveWorkbook
.SaveAs Filename:=xcsvFile, FileFormat:=xlCSV
.Close savechanges:=false
end with
end with
Next w
end sub
Is CurDir appropriate here? ActiveWorkbook.Path may be another option.

Excel VBA .SaveAs breaking in loop

I have an excel workbook broken out with multiple worksheets, 1 per customer. In my code, I am trying to save each individual customer worksheet as its own excel file. However, the .SaveAs command breaks the second time it triggers in the loop. Any pointers would be fantastic.
Dim SchedWorksheet As Worksheet
Dim SchedWorkbook As Workbook
Dim SchedName As String
Set SchedWorkbook = ActiveWorkbook
Set SchedWorksheet = ActiveSheet
Application.DisplayAlerts = False
For Each Worksheet In SchedWorkbook.Sheets
If Worksheet.Name = "Instructions" Or Worksheet.Name = "Invoice_Items"
Or Worksheet.Name = "Customers" Or _
Worksheet.Name = "Terms" Or Worksheet.Name = "Dilution_Type" Or
Worksheet.Name = "Approval_Status" Or _
Worksheet.Name = "Carriers" Then
GoTo NextSched
End If
If Worksheet.Name = "Invoices" Then
'basicScheduleFileName is global set at beginning of program
SchedName = basicScheduleFileName & "ALL"
Else
SchedName = Worksheet.Name
End If
'payoutFileName is global set at beginning of program
Worksheet.SaveAs Application.ActiveWorkbook.Path & "\" & payoutFileName
& "\Basic Schedule" & "\" & SchedName, xlOpenXMLWorkbook
NextSched:
Next Worksheet
The error on the second iteration is as follows:
Run-time error 1004 'Application-defined or object-defined error'
I have also attempted to run this loop using the SchedWorksheet object in lieu of Worksheet and get the error "method .SaveAs of object _Worksheet failed" on the second iteration.
Question I have code extremely similar to his code earlier in my program that takes a similar dataset and uses an exportAsFixedFormat call to save each worksheet as a PDF. Is there an equivalent for .xlsx? (.csv would be fine as well)
I don't know what value "payOutFileName" has so I left it out of the code. I also don't know the value for basicScheduleFileName so I set it to "Something." You will have to change that to whatever you need to change it too. This works fine when saving to my dir "C\Files" Might be a little buggy for you. Hopefully it will be a start.
Sub asdfghj()
Dim SchedWorkbook As Workbook
Dim SchedName As String
Dim basicScheduleFileName As String
Dim payoutFileName As String
Dim ws As Worksheet
Dim wb As Workbook
basicScheduleFileName = "Something"
Set SchedWorkbook = ActiveWorkbook
Application.DisplayAlerts = False
For Each ws In SchedWorkbook.Sheets
Debug.Print ws.Name
If ws.Name = "Instructions" Or ws.Name = "Invoice_Items" _
Or ws.Name = "Customers" Or _
ws.Name = "Terms" Or ws.Name = "Dilution_Type" Or _
ws.Name = "Approval_Status" Or _
ws.Name = "Carriers" Then
GoTo NextSched
End If
If ws.Name = "Invoices" Then
SchedName = basicScheduleFileName & "ALL" & ".xlsx"
Else
SchedName = ws.Name & ".xlsx"
End If
ws.Activate
' SaveAs Application.ActiveWorkbook.Path & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName, xlOpenXMLWorkbook
Set wb = Workbooks.Add
ws.Copy Before:=wb.Sheets(1)
wb.Sheets("Sheet1").Delete
wb.SaveAs Filename:="C:\Files\" & SchedName, FileFormat:= _
xlOpenXMLWorkbook, CreateBackup:=False
wb.Close
NextSched:
Next ws
End Sub
First off, thanks to everyone who took time and brainpower trying to figure out my issue. I finally figured out a fix that works.
First I made sure to get rid of ActiveWorkbook and ActiveSheet references to avoid any confusion in Excel.
Second As #NickSlash pointed out, it was likely that even if my code did work, it would save multiple copies of the same file under different names. So, to solve that while fixing my original issue, I changed my code to copy the worksheets that I need into a new workbook and save them that way:
Dim WS As Worksheet
Dim WB As Workbook
Dim NWB As Workbook
Dim SchedName As String
Set WB = Workbooks("Basic_Schedule-.xls")
WB.Activate
'Application.DisplayAlerts = False
For Each WS In WB.Sheets
WB.Activate
If WS.Name = "Instructions" Or WS.Name = "Invoice_Items" Or WS.Name = "Customers" Or _
WS.Name = "Terms" Or WS.Name = "Dilution_Type" Or WS.Name = "Approval_Status" Or _
WS.Name = "Carriers" Then
GoTo NextSched
End If
If WS.Name = "Invoices" Then
SchedName = basicScheduleFileName & "ALL" & ".xlsx"
Else
SchedName = WS.Name & ".xlsx"
End If
'Copy sheet to another WB
Set NWB = Workbooks.Add
WB.Activate
Sheets(WS.Name).Copy After:=NWB.Sheets(NWB.Sheets.Count)
NWB.Sheets("Sheet1").Delete
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close
WB.Activate
NextSched:
Next WS
Instead of this:
'Copy sheet to another WB
Set NWB = Workbooks.Add
WB.Activate
Sheets(WS.Name).Copy After:=NWB.Sheets(NWB.Sheets.Count)
NWB.Sheets("Sheet1").Delete
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close
WB.Activate
Do this -- you can avoid the "Activate" method call, and also if you have a reference to WS as an object, it's redundant to do WB.Sheets(WS.Name) when WS already refers to the same Worksheet.
'Copy sheet to another WB
WS.Copy '## Creates a new workbook with the copied sheet.
Set NWB = ActiveWorkbook
NWB.SaveAs filename:=basicScheduleFilePath & "\" & payoutFileName & "\Basic Schedule" & "\" & SchedName
NWB.Close

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.

Export all but certain excel sheets to CSV via VBA?

Based on some other stuff I found here, I have made the following script to do almost exactly what I want. It will export all but 4 specific sheets in an excel file to CSV files, append dates to them, and save them to dated folders. The only problem is it renames the sheets it exported in the original processing file. How can I rectify this?
Sub SaveLCPWorksheetsAsCsv()
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 = "C:\test\" & Format(Date - 1, "YYYYMM") & "\"
If Len(Dir(SaveToDirectory, vbDirectory)) = 0 Then
MkDir SaveToDirectory
End If
For Each WS In ThisWorkbook.Worksheets
If WS.Name <> "Input" And WS.Name <> "Ref" And WS.Name <> "Total" And WS.Name <> "Affected Accounts" Then
WS.SaveAs SaveToDirectory & WS.Name & "_" & Format(Date - 1, "YYYYMMDD"), xlCSV
End If
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
Sub Tester()
Dim ws As Worksheet, wb As Workbook
For Each ws In ThisWorkbook.Worksheets
ws.Copy 'creates a new workbook
With ActiveWorkbook
.SaveAs "C:\temp\" & ws.Name & "_blah.csv", xlCSV
.Close False
End With
Next ws
End Sub