When we have a workbook with several sheets
sheet_1, sheet_2, ..., sheet_n, sheet_constant
and we like to create n workbooks with pairs of two sheets
workbook 1: sheet_1, sheet_constant
workbook 2: sheet_2, sheet_constant
...
workbook n: sheet_n, sheet_constant
how can we do this with vba?
I know we can copy one sheet with this
Sub CopySheet()
ThisWorkbook.Sheets("sheet_1").Copy
Application.Dialogs(xlDialogSaveAs).Show
End Sub
And I tried this with no success
Sub CopySheets()
ThisWorkbook.Sheets("sheet_1").Copy
ThisWorkbook.Sheets("sheet_constant").Copy
Application.Dialogs(xlDialogSaveAs).Show
End Sub
You can use:
Sub CopySheets(VariableSheetName As String, ConstantSheetName As String)
ThisWorkbook.Sheets(Array(VariableSheetName, _
ConstantSheetName)).Copy
Application.Dialogs(xlDialogSaveAs).Show
End Sub
Note: Copying both sheets at once has the advantage that any references between the sheets won't suddenly become links to the original workbook, which is what could happen if you copy the sheets one after the other.
This subroutine can be called as:
CopySheets "sheet_1", "sheet_constant"
CopySheets "sheet_2", "sheet_constant"
CopySheets "sheet_3", "sheet_constant"
or in a loop (assuming your sheets do have numbers in them)
For i = 1 To 3
CopySheets "sheet_" & i, "sheet_constant"
Next
or, if you want all sheets copied:
For Each ws in Worksheets
If ws.Name <> "sheet_constant" Then
CopySheets ws.Name, "sheet_constant"
End If
Next
Based on #YowE3K answer, this one is a little more generic and hase autoSave option.
Sub CopySheets()
Dim ws As Worksheet
ChDir (ThisWorkbook.Path)
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = "sheet_constant" Then GoTo NextIteration
ThisWorkbook.Sheets(Array(ws.Name, "sheet_constant")).Copy
Application.DisplayAlerts = False
Application.ScreenUpdating = False
ActiveWorkbook.SaveAs Filename:=ws.Name, FileFormat:=xlNormal, CreateBackup:=False
ActiveWorkbook.Saved = True
ActiveWindow.Close
Application.DisplayAlerts = True
Application.ScreenUpdating = True
NextIteration:
Next ws
End Sub
Related
I have a macro that generates a lot of worksheets and charts. There's also various subroutines that run so the names and quantity of each worksheet/chart generated is never the same. What is constant is my HOME worksheet which is the UI for the user and I want it to be unaffected.
I found a similar question here about deleting all worksheets except the one you are working with (i.e. HOME). Here's what I have so far.
Sub ZRESET()
Dim ws As Worksheet, wb As Workbook
Set wb = ActiveWorkbook
Sheets("HOME").Select
Application.DisplayAlerts = False
For Each ws In wb.Worksheets
If ws.Name <> "HOME" Then
ws.Delete
End If
If Chart.Name = "" Then
Charts.Delete
End If
Next
Application.DisplayAlerts = True
Range("B5:E5,B9:E9,B13:E13,B14:E14").ClearContents
Range("A1").Select
End Sub
The worksheets delete fine, the hang up I have is the charts. I tried various attempts to remove charts and sometimes they work (i.e placing Charts.Delete outside of a FOR loop and IF statement). But this requires me to actually have a chart in the workbook. Sometime the user can just develop worksheets but no charts.
Any advice to continue my goal of deleting SHEETS and/or CHARTS, while keeping my HOME sheet intact?
Option Explicit
Sub GetRid()
Dim ASheet As Worksheet
Dim AChart As Chart
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'** first scan for and delete all non HOME worksheets ***
For Each ASheet In ActiveWorkbook.Worksheets
If UCase(ASheet.Name) <> "HOME" Then
ASheet.Delete
End If
Next
'** Now scan and delete any ChartSheets ****
For Each AChart In ActiveWorkbook.Charts
AChart.Delete
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Option Explicit
Sub AllSheetsAndcharts()
Dim AChart As ChartObject
Dim ASheet As Worksheet
Application.DisplayAlerts = False
For Each ASheet In ActiveWorkbook.Worksheets
If UCase(ASheet.Name) <> "HOME" Then
For Each AChart In ASheet.ChartObjects
AChart.Delete
Next
ASheet.Delete
End If
Next
Application.DisplayAlerts = False
End Sub
I recently asked a question and received a great answer on this site, but I am now running into a different problem. The code below works well for running through each workbook in a folder, copying a sheet's contents, and pasting those contents into a master workbook exactly how I would like:
Sub ConslidateWorkbooks()
'Code to pull sheets from multiple Excel files in one file directory
'into master "Consolidation" sheet.
Dim FolderPath As String
Dim Filename As String
Dim Sheet As Worksheet
Dim wbName As String
With ActiveSheet
Range("A1").Activate
End With
Application.ScreenUpdating = False
FolderPath = ActiveWorkbook.Path & "\"
Filename = Dir(FolderPath & "*.xls*")
wbName = ActiveWorkbook.Name
Do While Filename <> ""
If Filename <> wbName Then
Workbooks.Open Filename:=FolderPath & Filename, ReadOnly:=True
For Each Sheet In ActiveWorkbook.Sheets
copyOrRefreshSheet ThisWorkbook, Sheet
Next Sheet
Workbooks(Filename).Saved = True
Workbooks(Filename).Close
ActiveSheet.Range("A1").Activate
End If
Filename = Dir()
Loop
Application.ScreenUpdating = True
End Sub
Sub copyOrRefreshSheet(destWb As Workbook, sourceWs As Worksheet)
Dim ws As Worksheet
On Error Resume Next
Set ws = destWb.Worksheets(sourceWs.Name)
On Error GoTo 0
If ws Is Nothing Then
sourceWs.Copy After:=destWb.Worksheets(destWb.Worksheets.Count)
Else
ws.Unprotect Password:="abc123"
ws.Cells.ClearContents
sourceWs.UsedRange.Copy
ws.Range(sourceWs.UsedRange.Address).PasteSpecial (xlPasteAll)
Application.CutCopyMode = False
End If
End Sub
The problem I am having now: After the paste is completed, each sheet in the master workbook has all of its cells selected, as though I Ctrl+A'd the entire sheet. I would like to get rid of this. It is a small task which I tried to accomplish in the line ActiveSheet.Range("A1").Activate within the Do While .. loop, but it has not worked for me.
EDIT:
I found a solution that works in this case. I am not sure why this was necessary, because the comments and answers in this thread seem like they should work, but they did not. I call this sub before I turn screenupdating to True in the main sub:
Sub selectA1()
Worksheets(1).Activate
Dim Sheet As Worksheet
For Each Sheet In ActiveWorkbook.Sheets
Sheet.Activate
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
Sheet.Range("A1").Select
Next Sheet
Worksheets(1).Activate
End Sub
I realize this is more complicated than it should be, but it works for my purposes.
In your copy sub, add in another code in the loop that will select a cell which should deactivate the total used range selection and just select the coded range.
Sub copyOrRefreshSheet(destWb As Workbook, sourceWs As Worksheet)
Dim ws As Worksheet
On Error Resume Next
Set ws = destWb.Worksheets(sourceWs.Name)
On Error GoTo 0
If ws Is Nothing Then
sourceWs.Copy After:=destWb.Worksheets(destWb.Worksheets.Count)
Else
ws.Unprotect Password:="abc123"
ws.Cells.ClearContents
sourceWs.UsedRange.Copy
ws.Range(sourceWs.UsedRange.Address).PasteSpecial (xlPasteAll)
ws.range("A1").select
Application.CutCopyMode = False
End If
End Sub
I added ws.range("A1").select which should do as I described above.
The macro appears to loops through all of the worksheets fine now. However, is there a way that I can make it so the macro does not get applied to a specific worksheet in my workbook, but does get applied to all other worksheets?
Sub FormatSheet()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Activate
Columns("A:J").Select
Selection.AutoFilter
Columns("A:J").EntireColumn.AutoFit
With Selection
.HorizontalAlignment = xlCenter
End With
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True
Next ws
End Sub
I created a dataset to test this out and found that the code worked just fine. So it must be something related to your specific data/worksheets. I would see if 2 sheets works, or try making a smaller sample on another workbook and see if it works. Sorry I'm not more helpful.
Consider this approach.
Option Explicit
Sub test()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Sheet1" Then
With ws.UsedRange
.Resize(.Rows.Count-1).Offset(1, 0).ClearContents
End With
End If
Next ws
End Sub
I encountered the following code:
Sub HideSheets()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> ActiveSheet.Name Then
Sht.Visible = xlSheetHidden
End If
Next Sht
End Sub
What it does is to use a loop to hide all worksheets in the active workbook, except the active sheet. What is xlSheetHidden and why is it not defined?
Its an enumeration. Normally something like this would be True or False, but here we have three possibilities, including xlSheetVeryHidden
I am needing to copy cells B3:W400 from multiple sheets (will have varying names each time it is run) and paste values into "CombinedPlans", appending each new selection under the last. I need 3 sheets excluded from the code: IBExport, MonthlyIBs, and Combined Plans.
A lot of googling with trial and error has given me the following code, which I got to work in my "practice" workbook. Now that I have put it into my production workbook, it is no longer copying any sheets. It just skips straight to the message box. What am I doing wrong?
Sub consolidatetest()
Sheets("CombinedPlans").Select
Range("B3:W1048576").Select
Selection.ClearContents
Dim J As Integer
Dim sh As Worksheet
Const excludeSheets As String = "QBExport,MonthlyIBs,CombinedPlans"
On Error Resume Next
For Each sh In ActiveWorkbook.Worksheets
If IsError(Application.Match(sh.Name, Split(excludeSheets, ","))) Then
Application.GoTo Sheets(sh.Name).[b3]
Range("B3:W400").Select
Selection.Copy
Worksheets("CombinedPlans").Activate
Range("B1048576").End(xlUp).Offset(rowOffset:=1, columnOffset:=0).PasteSpecial xlPasteValues
End If
Next
Application.CutCopyMode = False
MsgBox "Complete!"
End Sub
This should work. If you have still problems, make sure that the Sheet CombinedPlans is indeed so named.
Sub consolidatetest()
Dim wb As Workbook
Dim sh_CombPlans As Worksheet
Set wb = ThisWorkbook
Set sh_CombPlans = wb.Sheets("CombinedPlans")
sh_CombPlans.Range("B3:W1048576").ClearContents
Dim sh As Worksheet
For Each sh In ActiveWorkbook.Worksheets
Select Case sh.Name
Case "QBExport", "MonthlyIBs", "CombinedPlans":
'Do Nothing
Case Else
sh.Range("B3:W400").Copy
sh_CombPlans.Range("B1048576").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End Select
Next
Application.CutCopyMode = False
MsgBox "Complete!"
End Sub