I keep getting an Out of Range error when trying to copy a sheet from on workbook to another. The original spreadsheet (Master_Data.xlsm) is what is running the vba script. The scripts opens another spreadsheet, manipulates it, then copies the final sheet to be pasted in the Master_Data.xlsm Workbook.
Sub Result_Scrapper()
Dim wb As Workbook, ws As Worksheet, wbFile As Object
Dim masterBook As Workbook
Dim wsa As Worksheet
Dim year As Integer
Set fso = CreateObject("Scripting.FileSystemObject")
Set fldr = fso.GetFolder("C:\Users\Output_Spreadsheets\")
Set masterBook = Excel.Workbooks("Master_Data.xlsm")
Application.ScreenUpdating = False
For Each wbFile In fldr.Files
If fso.GetExtensionName(wbFile.Name) = "xlsm" Then
Set wb = Workbooks.Open(wbFile.Path)
'Copy sheet of interest
ActiveSheet.Copy 'Before:=ThisWorkbook.Sheets(“A”) 'tried doing it using before statement but it also caused errors
'paste sheet into masterBook spread--this is where the error comes
masterBook.Sheets(Sheets.Count).Paste
End If
masterBook.Sheets("master").Name = Right([A2], 30)
Next wbFile
There are two issues. First, as someone else commented, you need to fully qualify the count. Second, you'll want to do it on one line; and you could do before, but then you're just pushing out whatever that last sheet is, if you add it after, then the sheets stay in order.
Try:
ActiveSheet.Copy After:=masterBook.Sheets(masterBook.Sheets.Count)
Related
I'd like to ask if you could help me with copying some worksheet data from workbook A into my active workbook (workbook B)
I have the following code in the main workbook to copy the data from workbook A
Public Sub Worksheet_Activate()
test
End Sub
Sub test()
Dim Wb1 As Workbook
Dim MainBook As Workbook
'Open All workbooks first:
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm")
'Set MainBook = Workbooks.Open(Application.ActiveWorkbook.FullName)
Set MainBook = Application.ActiveWorkbook
'Now, copy what you want from wb1:
Wb1.Sheets("Projekte").Cells.Copy
'Now, paste to Main worksheet:
MainBook.Worksheets("Projekte").Range("A1").PasteSpecial xlPasteAll
Application.CutCopyMode = False
'Close Wb's:
Wb1.Close SaveChanges:=False
End Sub
I know, that it opens worksheet A and that it highlights and copys the data.
The script wont paste it into worksheet B (where the script is executed from)
Anybody know what i did wrong?
Kindest regards, and thanks for any help !
You should set the Mainbook (destination) first before the origin (if you're going to use ActiveWorkbook).
'Set MainBook First
Set MainBook = ThisWorkbook
'Open All workbook:
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm")
Just for clarity, it's just me being OC on this one.
you have to properly reference your workbook and worksheet objects
if you have to paste the whole content of range (including formatting, comments, ...), then you want to code like follows (explanations in comments):
Option Explicit
Sub test()
Dim targetSheet As Worksheet
Set targetSheet = ActiveSheet 'store currently active sheet
Workbooks.Open("Z:\Folder\WorkbookA.xlsm").Sheets("Projekte").UsedRange.Copy Destination:=targetSheet.Range("A1") ' open the wanted workbook and copy its "Projekte" sheet used range to 'targetSheet (i.e.: the sheet in the workbook where it all started) from its cell A1
ActiveWorkbook.Close SaveChanges:=False ' close the currently active workbook (i.e. the just opened one)
End Sub
if you only need to paste values, then this is the way to go (much faster!):
Option Explicit
Sub test()
Dim targetSheet As Worksheet
Set targetSheet = ActiveSheet 'store currently active sheet
With Workbooks.Open("Z:\Folder\WorkbookA.xlsm").Sheets("Projekte").UsedRange ' open the wanted workbook and reference its sheet "Projekte" used range
targetSheet.Range("A1").Resize(.Rows.Count, .Columns.Count).Value = .Value
.Parent.Parent.Close SaveChanges:=False 'close the parent workbook of referenced range (i.e., the newly opened workbook)
End With
End Sub
My recommendation is never to use ActiveWorkbook.
In most cases when people use ActiveWorkbook they actually meant to use ThisWorkbook. The difference is:
ActiveWorkbook is the currently selected one which is "on top of the screen" in exact that moment when your code runs. That can be any workbook the user just clicked on while your code runs. So you never can be 100% sure to get the right workbook.
ThisWorkbook is the actual workbook your code runs at the moment. And this doesn't change ever. So this is a well defined reference and no gamble about which workbook is on top at the moment.
About why your approach did not work
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm") 'this line makes WorkbookA the active one
Set MainBook = Application.ActiveWorkbook 'this makes MainBook = WorkbookA
Therefore a simple Set MainBook = Application.ThisWorkbook should work here.
Another recommendation
Sheets and Worksheets is not the same. Make sure you never use Sheets when you can use Worksheets.
Sheets contains worksheets and charts
Worksheets contain only worksheets
An example Sheets(1).Range("A1") fails if it is a chart.
I need to copy paste all my Worksheet name in the current workbook to a new workbook with same worksheet names. (without the datas. I only need the worksheet names.)
I tried following VBA but it shows the error
"The name is already taken." (Runtime Error 1004)
'Create new work book for Pivot
Dim Source As Workbook
Dim Pivot As Workbook
Set Source = ActiveWorkbook
Set Pivot = Workbooks.Add
Dim ws As Worksheet
For Each ws In Worksheets
'Create new worksheet in new excel
Dim Line As String
Line = ActiveSheet.Name
Pivot.Activate
Sheets.Add
ActiveSheet.Name = Line
Source.Activate
Next
You never use ws so Line never changes. Also you do not need to select or activate anything. Finally, you should qualify your Worksheets etc with the workbook they come from.
Dim Source As Workbook
Dim Pivot As Workbook
Set Source = ActiveWorkbook
Set Pivot = Workbooks.Add
Dim ws As Worksheet
For Each ws In Source.Worksheets
Pivot.Worksheets.Add.Name = ws.Name
Next
That will not protect you from a situation where there is already a sheet in the new workbook with the name identical to one of your sheets name (e.g. Sheet1), and it will leave any sheets the new workbook has by default (controlled by the Application.SheetsInNewWorkbook property).
I have three workbooks.
One workbook is a list I add to every month, of things I need to delete from a second workbook. I receive a second workbook every month. The second workbook I receive always contains extraneous entries (the number growing every month) and will not be fixed anytime soon. There is no general filter I can make without making the second workbook useless, so I need to be really specific and have a silly cleaning list.
My third workbook is where I run all of my workbook cleaning macros from.
The objective is to compare the entries in column A or B on the first workbook with the entries in column A or B of the second workbook I receive. If any of the entries match, delete the entire row on the second workbook.
I will be doing this once a month for a few hundred lines, and it will be run from a macro assigned to a shape on a third workbook.
Here I am posting some code that lets me open my two files and copy the contents of one of them, but what I need is code that will compare and delete rows on Workbook 2 that match with Workbook 1. My own code to do exactly that is terrible, not worth posting at all.
Code:
Sub test()
Dim strFileName As String
Dim wbTarget As Workbook
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
strFileName = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open data")
Set wbSource = ThisWorkbook
Set wbTarget = Workbooks.Open(strFileName)
Set wsSource = wbSource.Worksheets("Sheet1")
Set wsTarget = wbTarget.Worksheets("Sheet1")
'to copy from Target - > Source
wsTarget.Range("B2").Resize(5, 5).Copy wsSource.Range("B2")
'etc.
End Sub
Code, comment and suggestion is greatly appreciated!
Cheers,
Christopher
CODE UPDATE 8:30 AM: This is a new way I am thinking of making things work. I am getting a type mismatch error on the code line Set Rng = Range("A1:B10000" & LR)
Sub test()
Dim strFileName As String
Dim strFileName2 As String
Dim wbTarget As Workbook
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wsSource As Worksheet
Dim LR
Dim Rng As Range
strFileName = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open 'Things Which Have Been Removed'")
strFileName2 = Application.GetOpenFilename("Excel files (*.xls*),*.xl*", Title:="Open This Month's Purge List")
Set wbSource = ThisWorkbook
Set wbTarget = Workbooks.Open(strFileName)
Set wsSource = wbSource.Worksheets("Sheet1")
Set wsTarget = wbTarget.Worksheets("Sheet1")
Set LR = wsSource.UsedRange.Rows
With wbTarget.Sheets(1)
Set Rng = Range("A1:B10000" & LR)
Rng.RemoveDuplicates Columns:=Array(4), Header:=xlNo
End With
End Sub
To answer your specific question.
Set Rng = Range("A1:B10000" & LR)
Should be
Set Rng = Range("A1:B" & LR)
I would like to help with your other issues, but your description is confusing, this is what I understand; you identify bad information in the second workbook and copy that information from the second workbook to the first workbook, then you want a macro to match what is in the first workbook to the second workbook and delete the rows in the second workbook that match. Question, why don't you delete the rows in the second workbook instead of copying them to the first workbook?
You can use find method ; after open workbook u can use this code, findind the cell adress u can easily delete it clear command
Dim GCell As Range
Set GCell = ActiveSheet.Cells.Find("yourvariable")
Is it possible to save into another workbook instead of same workbook. we are making a master workbook. daily we are updating data, once updated by pushing button need to copy in to master workbook with sheet name as current date.
below code working for copying into same work book into sheet2
Private Sub CommandButton1_Click()
On Error GoTo Err_Execute
Sheet1.Range("A1:J75").Copy
Sheet2.Range("A1").Rows("1:1").Insert Shift:=xlDown
Err_Execute:
If Err.Number = 0 Then
MsgBox "All have been copied!"
ElseIf Err.Number <> 0 Then
MsgBox Err.Description
End If
End Sub
Yes, this is possible. You just have to set the Workbooks properly to be able to refer to them:
Dim masterWB As Workbook
Dim dailyWB As Workbook
'Set Current Workbook as Master
Set masterWB = Application.ThisWorkbook
'Set some Workbook as the one you are copying from
Set dailyWB = Workbooks.Open("PATH TO WORKBOOK HERE")
'Copy the Range from the Workbook and Paste it into the MasterWB
dailyWB.Sheets(1).Range("A1:J75").Copy masterWB.Sheets(1).Range("A1").Rows("1:1")
Close the Workbook without saving
dailyWB.Close False
'Clear the Variables
Set dailyWB = Nothing
Set masterWB = Nothing
Just modify the Sheets to match your needs and it should work
If you want to create a Worksheet on your Master Workbook and Rename it use this:
Dim tempWS as Worksheet
Set tempWS = masterWB.Sheets.Add
tempWS.Name = Format(Date, "mm-dd-yyyy")
Depending on the Format you want to use for the name, modify the "mm-dd-yyyy" to your needs. e. g. "yyyy.mm.dd"
I am trying to create a copy of a large macro enabled (xlsm) file in xlsx format.
Sub Button1_Click()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\original.xlsm")
Dim mySheetList() As String
ReDim mySheetList(0 To (ThisWorkbook.Sheets.Count) - 1)
Dim a As Integer
a = 0
For Each ws In ActiveWorkbook.Worksheets
mySheetList(a) = ws.Name
a = a + 1
Next ws
'actually save
Worksheets(mySheetList).Copy
ActiveWorkbook.SaveAs Filename:="ORIGINAL_COPY.xlsx" 'default ext
wb.Close
End Sub
I am getting subscript out of range error at following line:
mySheetList(a) = ws.Name
You are sizing the array with ThisWorkbook.Sheets but the loop use ActiveWorkbook.Worksheets. You need the same reference to avoid issues when multiple workbooks are opened.
You're using 4 different references to workbooks:
wb, ThisWorkbook and ActiveWorkbook are not necessarily the same thing. Furthermore, when you use Worksheets without prefixing it with a workbook reference, you're implicitly referencing the Activeworkbook. And, when you use Worksheets.Copy without any arguments, you're implictly creating a new workbook.
Currently, if ThisWorkbook has fewer sheets than original.xlsm, then your array will not be large enough to accommodate indexes larger than the count of sheets in ThisWorkbook. That is what is causing your out of bounds error.
I've adjusted the code. This will open the XLSM, copy the sheets, save the new XLSX workbook, and close the original XLSM, leaving the new XLSX workbook open.
Sub Button1_Click()
Dim wbOriginal As Workbook
Dim wbOutput As Workbook
Set wbOriginal = Workbooks.Open("C:\original.xlsm")
Dim mySheetList() As String
ReDim mySheetList(0 To (wbOriginal.Sheets.Count) - 1)
Dim a As Integer
a = 0
For Each ws In wbOriginal.Worksheets
mySheetList(a) = ws.Name
a = a + 1
Next ws
'Unfortunately, Worksheets.Copy isn't a function, so it doesn't
'return the workbook that it creates, so we have to execute the
'copy, then find the activeworkbook
Worksheets(mySheetList).Copy
Set wbOutput = ActiveWorkbook
'actually save
wbOutput.SaveAs Filename:="ORIGINAL_COPY.xlsx" 'default ext
wbOriginal.Close
End Sub
Why bother with all that looping?
Sub MM()
Dim sourceWB As Excel.Workbook
Set sourceWB = Workbooks.Open("C:\Original.xlsm")
sourceWB.SaveAs "C:\ORIGINAL_COPY.xlsx", FileFormat:=xlOpenXMLWorkook
sourceWB.Close False '// Optional
End Sub
The .SaveAs() method would be far more effective.
As mentioned in other answers, your issue seems to be with wb, ActiveWorkbook and ThisWorkbook being used interchangeably when they are actually different things.
wb is a workbook object that has been set to "C:\original.xlsm". It will always refer to that workbook unless you close the workbook, empty the object, or assign a new object to it.
ActiveWorkbook refers to the workbook that is currently active in Excel's forefront window. (i.e. The workbook you can see on your screen)
ThisWorkbook refers to the workbook in which the currently executing code belongs to. To quickly explain the difference:
Workbook A is the only workbook open, and has some code in to open another workbook (let's call it Workbook B).
At the moment, Workbook A is the ActiveWorkbook.
The code in workbook A starts running, workbook A is now the ActiveWorkbook and ThisWorkbook (because the running codes resides in this workbook)
The code opens Workbook B, which naturally opens in the forefront of Excel. Now Workbook B is the ActiveWorkbook and Workbook A is still the ThisWorkbook
Hopefully that clears it up a bit for you...