I would like to copy all the sheets from one workbook other than the first sheet to another workbook and then once the sheets have been copied to the other workbook, close it. Here is what I have for my code so far. Right now, it is copying all the sheets from Workbook SD09_KW.xlsm and pasting them into the Workbook Pending SD09 which is the correct location. However, I would like it to copy all the worksheets in SD09_KW other than the first sheet. It also is making copies of all the sheets in Pending SD09 and saving them inside the workbook too which I do not want it to do. Any help would be great! Thanks.
Sub CopySD()
Dim DataWorkbook As Workbook, PendingWorkbook As Workbook, Sheet As Worksheet
Set DataWorkbook = Workbooks.Open("C:\Users\Documents\SD09_KW.xlsm")
Set PendingWorkbook = Workbooks("Pending SD09")
For Each Sheet In DataWorkbook.Sheets
Sheets.copy After:=PendingWorkbook.Sheets(PendingWorkbook.Worksheets.Count)
Next
PendingWorkbook.Close SaveChanges:=True
End Sub
UPDATE: I have made a few changes, however, nwo I am getting an error of "Object doesn't support this property or method" in line DataWorkbook(i).Sheets.copy After:=PendingWorkbook.Sheets(PendingWorkbook.Worksheets.Count)
Here is the updated code:
Sub CopySD(sysnum As String) ' copies over the SD tabs created into the pending doc workbook
Dim DataWorkbook As Workbook, PendingWorkbook As Workbook, i As Long
Set DataWorkbook = Workbooks.Open("C:\Users\Documents\SD093_KW.xlsm")
Set PendingWorkbook = Workbooks.Open("C:\Users\Documents\Pending SD093.xlsx")
For i = 2 To DataWorkbook.Worksheets.Count
If Not SheetExists(sysnum, PendingWorkbook) Then ' SD tab not already saved to pending workbook
DataWorkbook.Sheets(i).copy After:=PendingWorkbook.Sheets(PendingWorkbook.Worksheets.Count) ' save SD tab to pending workbook
End If
Next
PendingWorkbook.Close SaveChanges:=True
Application.DisplayAlerts = False
For i = DataWorkbook.Sheets.Count To 2 Step -1
DataWorkbook.Sheets(i).Delete
Next i
Application.DisplayAlerts = True
End Sub
Copy/Delete Worksheets
Note the mistakes in your codes where you have used:
Sheets.Copy... instead of
Sheet.Copy...
DataWorkbook(i).Sheets.copy... instead of
DataWorkbook.Worksheets(i).Copy...
Note the inaccuracies (inconsistencies, mistakes if the workbooks contain charts) in your codes where you have used:
... In DataWorkbook.Sheets instead of
... In DataWorkbook.Worksheets
... After:=PendingWorkbook.Sheets(PendingWorkbook.Worksheets.Count) instead of
... After:=PendingWorkbook.Sheets(PendingWorkbook.Sheets.Count)
... To DataWorkbook.Sheets.Count instead of
... To DataWorkbook.Worksheets.Count
Copy All But the First Worksheet
For Each...Next
Sub CopyForEach()
Dim DataWorkbook As Workbook
Set DataWorkbook = Workbooks.Open("C:\Users\Documents\SD09_KW.xlsm")
Dim PendingWorkbook As Workbook
Set PendingWorkbook = Workbooks.Open("C:\Users\Documents\Pending SD09.xlsx")
Dim ws As Worksheet
Dim FoundFirst As Boolean
For Each ws In DataWorkbook.Worksheets
If FoundFirst Then
ws.Copy After:=PendingWorkbook.Sheets(PendingWorkbook.Sheets.Count)
Else ' skip first
FoundFirst = True
End If
Next ws
PendingWorkbook.Close SaveChanges:=True
End Sub
For...Next
Sub CopyForNext()
Dim DataWorkbook As Workbook
Set DataWorkbook = Workbooks.Open("C:\Users\Documents\SD09_KW.xlsm")
Dim PendingWorkbook As Workbook
Set PendingWorkbook = Workbooks.Open("C:\Users\Documents\Pending SD09.xlsx")
Dim i As Long
For i = 2 To DataWorkbook.Worksheets.Count ' 2 means skip first
DataWorkbook.Worksheets(i).Copy _
After:=PendingWorkbook.Sheets(PendingWorkbook.Sheets.Count)
Next i
PendingWorkbook.Close SaveChanges:=True
End Sub
Delete All But the First Worksheet
After PendingWorkbook.Close SaveChanges:=True you will use either
DeleteAllButFirstWorksheetForEachNext DataWorkbook
or
DeleteAllButFirstWorksheetForNext DataWorkbook
Of course, use shorter names for the procedures e.g. DeleteAllButFirst.
For Each...Next
Sub DeleteAllButFirstWorksheetForEachNext(ByVal wb As Workbook)
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount < 2 Then Exit Sub
Dim WorksheetNames() As String: ReDim WorksheetNames(1 To wsCount - 1)
Dim ws As Worksheet
Dim n As Long
Dim FoundFirst As Boolean
For Each ws In wb.Worksheets
If FoundFirst Then
n = n + 1
WorksheetNames(n) = ws.Name
Else ' skip first
FoundFirst = True
End If
Next ws
Application.DisplayAlerts = False
wb.Worksheets(WorksheetNames).Delete
Application.DisplayAlerts = True
End Sub
For...Next
Sub DeleteAllButFirstWorksheetForNext(ByVal wb As Workbook)
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount < 2 Then Exit Sub
Dim WorksheetNames() As String: ReDim WorksheetNames(1 To wsCount - 1)
Dim i As Long
Dim n As Long
For i = 2 To wsCount
WorksheetNames(i - 1) = wb.Worksheets(i).Name
Next i
Application.DisplayAlerts = False
wb.Worksheets(WorksheetNames).Delete
Application.DisplayAlerts = True
End Sub
Related
Wondering why I can't do :
For i = 1 To ThisWorkbook.Sheets.Count
If ThisWorkbook.Sheets(i).Name <> "DO NOT SAVE" Then ThisWorkbook.Sheets(i).Select Replace:=False
Next i
Selection.Copy
what would be the best way to save all sheets which does not match DO NOT SAVE name in another wb ?
Try this:
Sub Tester()
Dim ws As Worksheet, arr(), i As Long
ReDim arr(0 To ThisWorkbook.Worksheets.Count - 2)
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "DO NOT SAVE" Then
arr(i) = ws.Name
i = i + 1
End If
Next ws
Worksheets(arr).Copy
End Sub
A Reflection on the Sheets' Visibility
To export a single sheet to a new workbook, the sheet has to be visible.
To export multiple sheets (using an array of sheet names) to a new workbook, at least one of the sheets has to be visible, while very hidden sheets will not get exported (no error though).
In a given workbook, the following procedure will copy all its sheets, except the ones whose names are in a given array (Exceptions), to a new workbook if at least one of the sheets is visible.
Before copying, it will 'convert' the very hidden sheets to hidden and after the copying, it will 'convert' the originals and copies to very hidden.
Option Explicit
Sub ExportSheets( _
ByVal wb As Workbook, _
ByVal Exceptions As Variant)
Dim shCount As Long: shCount = wb.Sheets.Count
Dim SheetNames() As String: ReDim SheetNames(1 To shCount)
Dim sh As Object
Dim coll As Object
Dim Item As Variant
Dim n As Long
Dim VisibleFound As Boolean
Dim VeryHiddenFound As Boolean
For Each sh In wb.Sheets
If IsError(Application.Match(sh.Name, Exceptions, 0)) Then
Select Case sh.Visible
Case xlSheetVisible
If Not VisibleFound Then VisibleFound = True
Case xlSheetHidden ' do nothing
Case xlSheetVeryHidden
If Not VeryHiddenFound Then
Set coll = New Collection
VeryHiddenFound = True
End If
coll.Add sh.Name
End Select
n = n + 1
SheetNames(n) = sh.Name
End If
Next sh
If n = 0 Then
MsgBox "No sheet found.", vbExclamation
Exit Sub
End If
If Not VisibleFound Then
MsgBox "No visible sheet found.", vbExclamation
Exit Sub
End If
If n < shCount Then ReDim Preserve SheetNames(1 To n) ' n - actual count
If VeryHiddenFound Then ' convert to hidden
For Each Item In coll
wb.Sheets(Item).Visible = xlSheetHidden
Next Item
End If
wb.Sheets(SheetNames).Copy ' copy to new workbook
If VeryHiddenFound Then ' revert to very hidden
Dim dwb As Workbook: Set dwb = Workbooks(Workbooks.Count)
For Each Item In coll
wb.Sheets(Item).Visible = xlSheetVeryHidden
dwb.Sheets(Item).Visible = xlSheetVeryHidden
Next Item
End If
MsgBox "Sheets exported: " & n, vbInformation
End Sub
Sub ExportSheetsTEST()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
ExportSheets wb, Array("DO NOT SAVE")
End Sub
Alternatively you could use the following snippet:
Sub CopyWorkbook()
Dim i As Integer
For i = 1 To ThisWorkbook.Sheets.Count
If ThisWorkbook.Sheets(i).Name <> "DO NOT SAVE" Then
Dim rng As Range
Windows("SOURCE WORKBOOK").Activate
rng = ThisWorkbook.Sheets(i).Cells
rng.Copy Before:=Workbooks("TARGET WORKBOOK").Sheets(i)
End If
Next i
End Sub
I need to copy data from the (origin) Workbook to the (destination) Workbook with pre-built existing worksheets in the destination Workbook. I need the code to loop through the worksheets in the origin file and copy and paste values to the specified worksheets in the destination. There are around 100+ sheets that will need this to be done for.
I found this code online and am trying to modify it to fit my needs. The issue is that the sheets are being made after the existing sheets, and I need the data to be copied over to the already existing sheets.
Sub CopyWorkbook()
Dim sh As Worksheet, wb As Workbook
Set wb = Workbooks("Destination.xlsm")
For Each sh in Workbooks("Origin.xlsm")
sh.Copy After:=wb.Sheets(wb.Sheets.Count)
Next sh
End Sub
Any help would be greatly appreciated.
Copy Sheets to Another Workbook
The following will delete existing destination sheets and replace them with the new versions of the source sheets. If a source sheet doesn't exist in the destination workbook, it will get copied to the last position.
Option Explicit
Sub CopySheets()
Const ProcTitle As String = "Copy Sheets"
Const sExceptionsList As String = "Sheet1,Sheet2"
Const dFilePath As String = "C:\Test\2021\69957615\Destination.xlsm"
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
Dim sExceptions() As String: sExceptions = Split(sExceptionsList, ",")
Dim sshCount As Long: sshCount = swb.Sheets.Count
Dim sshNames() As String: ReDim sshNames(1 To sshCount)
Dim ssh As Object
Dim sshName As String
Dim dIndex As Long
Dim n As Long
' Write the Source Sheet Names to an array.
For Each ssh In swb.Sheets
sshName = ssh.Name
If IsError(Application.Match(sshName, sExceptions, 0)) Then
n = n + 1
sshNames(n) = sshName
End If
Next ssh
If n < sshCount Then
sshCount = n
ReDim Preserve sshNames(1 To sshCount)
End If
Dim dwb As Workbook: Set dwb = Workbooks.Open(dFilePath)
Dim dshCount As Long: dshCount = dwb.Sheets.Count
Dim dsh As Object
Application.ScreenUpdating = False
For n = 1 To sshCount
sshName = sshNames(n)
Set ssh = swb.Sheets(sshName)
On Error Resume Next
Set dsh = dwb.Sheets(sshName)
On Error GoTo 0
If dsh Is Nothing Then ' copy new sheet
ssh.Copy After:=dwb.Sheets(dwb.Sheets.Count)
dshCount = dshCount + 1
Else ' copy existing sheet
dIndex = dsh.Index
Application.DisplayAlerts = False
dsh.Delete
Application.DisplayAlerts = True
If dIndex = dshCount Then
ssh.Copy After:=dwb.Sheets(dIndex - 1)
Else
ssh.Copy Before:=dwb.Sheets(dIndex)
End If
End If
Set dsh = Nothing
Next n
Application.ScreenUpdating = True
MsgBox "Sheets copied.", vbInformation, ProcTitle
End Sub
I have two workbooks with worksheets (having the same names). I would like copy and paste specific cells from one worksheet to another if the name of worksheets are the same.
I tried to compare name of worksheets with array based on names from another workbook but stack when comes to comparison
Sub check()
Dim xArray, i
Dim x As Workbook
Dim ws As Worksheet
Set x = Workbooks.Open("C:\Users\user\Desktop\xxx.xlsx", False)
With x
ReDim xArray(1 To Sheets.Count)
For i = 1 To Sheets.Count
xArray(i) = x.Sheets(i).Name
Debug.Print xArray(i)
Next
End With
x.Close (False)
For Each ws In ThisWorkbook.Worksheets
If ws.Name = xArray Then
' copy for each worksheet define in xArray xxx.xlsx file, range A1,B4,D5:G5
' and paste to worksheet with the same name in this open workbook
End Sub
Thanks for any help !
Use an Error handler to test if the sheet exists.
Sub check()
Dim wb As Workbook, SouceWorksheet As Worksheet, TargetWorksheet As Worksheet
Set wb = Workbooks.Open("C:\Users\user\Desktop\xxx.xlsx", False)
For Each SouceWorksheet In wb.Worksheets
On Error Resume Next
Set TargetWorksheet = ThisWorkbook.Worksheets(SouceWorksheet.Name)
On Error GoTo 0
If Not TargetWorksheet Is Nothing Then
SouceWorksheet.Range("A1").Copy TargetWorksheet.Range("A1")
SouceWorksheet.Range("B4").Copy TargetWorksheet.Range("B4")
SouceWorksheet.Range("D5:G5").Copy TargetWorksheet.Range("D5:G5")
End If
Next
wb.Close False
End Sub
for this functionality , you don't need to create array , it can be done easily with simple logic mentioned below.Also you can customize or replace your workbook and worksheet name and your copy-paste range in the below code.
Sub so()
Dim wb As Workbook
Dim wb1 As Workbook
Set wb = Workbooks("Book1.xlsx")
Set wb1 = Workbooks("Book2.xlsx")
Dim wk As Worksheet
Set wk = wb.Worksheets("Sheet1")
Dim wm As Worksheet
Set wm = wb1.Worksheets("Sheet1")
If (wk.Name = wm.Name) Then
Dim TR As Integer
TR = wk.Range("A" & Rows.Count).End(xlUp).Row
wk.Range("A1:A" & TR).Copy wm.Range("A1")
Application.CutCopyMode = False
End If
End Sub
I've got over 200 workbooks that I need to merge, the code below will merge the workbooks and add all the sheets into one workbook.
In that workbook the sheets are being named Sheet 1 (1), Sheet 1 (2) and so on.
If the sheet was copied from Workbook1 the sheet name would be workbook 1
Sub mergeFiles()
'Merges all files in a folder to a main file.
'Define variables:
Dim numberOfFilesChosen, i As Integer
Dim tempFileDialog As FileDialog
Dim mainWorkbook, sourceWorkbook As Workbook
Dim tempWorkSheet As Worksheet
Set mainWorkbook = Application.ActiveWorkbook
Set tempFileDialog = Application.FileDialog(msoFileDialogFilePicker)
'Allow the user to select multiple workbooks
tempFileDialog.AllowMultiSelect = True
numberOfFilesChosen = tempFileDialog.Show
'Loop through all selected workbooks
For i = 1 To tempFileDialog.SelectedItems.Count
'Open each workbook
Workbooks.Open tempFileDialog.SelectedItems(i)
Set sourceWorkbook = ActiveWorkbook
'Copy each worksheet to the end of the main workbook
For Each tempWorkSheet In sourceWorkbook.Worksheets
tempWorkSheet.Copy after:=mainWorkbook.Sheets(mainWorkbook.Worksheets.Count)
Next tempWorkSheet
'Close the source workbook
sourceWorkbook.Close
Next i
End Sub
Add this in you For Each loop
Dim j as integer ‘Add to top of your sub
j = 0 ‘Add inside for loop
For Each tempWorkSheet In sourceWorkbook.Worksheets
j= j+1
tempWorkSheet.Copy after:=mainWorkbook.Sheets(mainWorkbook.Worksheets.Count)
ActiveSheet.Name = sourceWorkBook.Name & “ - “ & j ‘Added Line of code to rename copied tab
Next tempWorkSheet
As long as your workbook names aren’t too long or duplicate, it should be good
Merge Files
Code Issues
You have declared numberOfFilesChosen as Variant:
Dim numberOfFilesChosen, i As Integer ' Wrong
Dim numberOfFilesChosen as Integer, i As Integer ' OK
You have declared mainWorkbook as Variant:
Dim mainWorkbook, sourceWorkbook As Workbook ' Wrong
Dim mainWorkbook as Workbook, sourceWorkbook As Workbook ' OK
Such a code should be in the Workbook (mainWorkbook) where the
Worksheets are being imported, so you don't need a variable, just use
ThisWorkbook. Then in combination with the With statement, you
can use e.g. .Sheets(.Sheets.Count).
You are changing between sheets and worksheets. When you use mainWorkbook.Worksheets.Count, this might not necessarily be the last sheet, so it would be more correct to use mainWorkbook.Sheets.Count especially for the added sheet counter to function correctly.
tempWorkSheet.Copy after:=mainWorkbook.Sheets(mainWorkbook.Worksheets.Count)
tempWorkSheet.Copy after:=mainWorkbook.Sheets(mainWorkbook.Sheets.Count) ' Preferable
When you use sourceWorkbook.Close, you might be asked to save the workbook. Using
sourceWorkbook.Close False ' Preferable
will close the workbook without saving changes.
The code will fail if you run it another time, because the sheet names
it will try to create are the same. Therefore I have added
DeleteWorksheetsExceptOne which I used while testing the code.
The Code
Sub mergeFiles()
'Merges all files in a folder to a main file.
'Define variables:
Dim tempFileDialog As FileDialog
Dim sourceWorkbook As Workbook
Dim tempWorkSheet As Worksheet
Dim numberOfFilesChosen As Long, i As Long, j As Long
Set tempFileDialog = Application.FileDialog(msoFileDialogFilePicker)
'Allow the user to select multiple workbooks
tempFileDialog.AllowMultiSelect = True
numberOfFilesChosen = tempFileDialog.Show
With ThisWorkbook
'Loop through all selected workbooks
For i = 1 To tempFileDialog.SelectedItems.Count
'Open each workbook
Workbooks.Open tempFileDialog.SelectedItems(i)
Set sourceWorkbook = ActiveWorkbook
j = 0
'Copy each worksheet to the end of the main workbook
For Each tempWorkSheet In sourceWorkbook.Worksheets
j = j + 1
tempWorkSheet.Copy After:=.Sheets(.Sheets.Count)
' Rename newly added worksheet to the name of Source Workbook
' concatenated with "-" and Counter (j).
.Sheets(.Sheets.Count).Name = sourceWorkbook.Name & "-" & j
Next
'Close the source workbook. False for not saving changes.
sourceWorkbook.Close False
Next
End With
End Sub
Delete All Worksheets But One
'*******************************************************************************
' Purpose: Deletes all Worksheets in the ActiveWorkbook except one.
' Danger: This code doesn't ask anything, it just does. In the end you will
' end up with just one worksheet (cStrWsExcept) in the workbook
' (cStrWbPath). If you have executed this code and the result is not
' satisfactory, just close the workbook and try again or don't. There
' will be no alert like "Do you want to save ..." because of the line:
' ".Saved = True" i.e. "objWb.Saved = True".
' Arguments (As Constants):
' cStrWbPath
' The path of the workbook to be processed. If "", then ActiveWorkbook is
' used.
' cStrWsExcept
' The worksheet not to be deleted. If "", then the Activesheet is used.
'*******************************************************************************
Sub DeleteWorksheetsExceptOne()
Const cStrWbPath = "" ' if "" then ActiveWorkbook
Const cStrWsExcept = "Sheet1" ' if "" then ActiveSheet
Dim objWb As Workbook
Dim objWsExcept As Worksheet
Dim objWsDelete As Worksheet
If cStrWbPath = "" Then
Set objWb = ActiveWorkbook
Else
Set objWb = Workbooks(cStrWbPath)
End If
With objWb
If cStrWsExcept = "" Then
Set objWsExcept = .ActiveSheet
Else
Set objWsExcept = .Worksheets(cStrWsExcept)
End If
' To suppress the "Data may exist in the sheet(s) selected for deletion.
' To permanently delete the data, press Delete." - Alert:
Application.DisplayAlerts = False
For Each objWsDelete In .Worksheets
If objWsDelete.Name <> objWsExcept.Name Then
objWsDelete.Delete
End If
Next
' To suppress the "Do you want to save changes you made to ... ?" - Alert:
.Saved = True
Application.DisplayAlerts = True
End With
End Sub
'*******************************************************************************
I found this great Macro that copies each of my rows in my data frame separately into a new sheet, but keeps the first row with the column names as well:
Sub abc_01()
Dim WS As Worksheet, newWS As Worksheet
Dim X As String
Application.ScreenUpdating = False
Set WS = Sheets("Sheet1")
On Error Resume Next
X = InputBox("number of names 1,2,", , "9")
For i = 1 To X
Set newWS = Worksheets.Add(after:=Worksheets(Worksheets.Count))
WS.Range("A1:G1").Copy Destination:=newWS.Range("A1")
WS.Range(WS.Cells(i + 1, "A"), WS.Cells(i + 1, "G")).Copy
newWS.Range("A2").PasteSpecial xlValues
Next i
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
I tried now to copy it into a new workbook rather than a new sheet, but the new workbook stays empty when I run it. Also, I haven't saved the new workbooks yet as a new filename (ideally a specific cell value if possible?)
Sub abc_02()
Dim thisWB As String
Dim newWB As String
thisWB = ActiveWorkbook.Name
Dim X As String
Application.ScreenUpdating = False
Set WS = Sheets("Sheet1")
On Error Resume Next
X = InputBox("number of names 1,2,", , "9")
For i = 1 To X
Workbooks.Add
ActiveWorkbook.SaveAs supName
newWB = ActiveWorkbook.Name
Windows(thisWB).Activate
Sheets("Sheet1").Select
Range("A1:G1").Copy
Windows(newWB).Activate
Sheets("Sheet1").Select
ActiveSheet.Range("A1").Select
ActiveSheet.Range("A1").Paste
Windows(thisWB).Activate
Sheets("Sheet1").Select
Range(Sheet1.Cells(i + 1, "A"), Sheet1.Cells(i + 1, "G")).Copy
Windows(newWB).Activate
Sheets("Sheet1").Select
Range("A2").PasteSpecial xlValues
Next i
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
I am a VBA noob so any help much appreciated!
In the original code, you have
Dim WS As Worksheet, newWS As Worksheet
Dim X As String
Dim WS as Worksheet and newWS as Worksheet tells Excel "WS and newWS will be worksheets."
Later in the code, these are set respectively, WS as Sheet1 in the active workbook, and newWS as a new worksheet within the active workbook.
Changing
Dim thisWB As String
Dim newWB As String
to
Dim thisWB As Workbook
Dim newWB As Workbook
should fix your issue.
You should be dimming thisWB and newWB as Workbooks, not strings.
Excel will be looking for a string of text instead of Workbooks.
Also - try looking on ExcelForum.com VBA section; I learnt a lot of what I know from there.
Hope that helps