Dynamically Copy Range of Cells from Closed Workbook? - excel

I would like to copy a range of cells in a closed notebook that does not have a static set of rows. I would like to copy it into an active workbook.
I am trying to dynamically copy all entries under the column of F from file 'test.xlsx' from the 'exception' worksheet. The macro runs without issue if there I use static referencing instead. Here is the code that I am running, it gives me a runtime error for the line that copies the data.
Sub GetClassID()
Dim App As New Excel.Application
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.ActiveSheet
Dim wbImport As Workbook
Set wbImport = App.Workbooks.Open(Filename:="C:\Test.xlsx",
UpdateLinks:=True, ReadOnly:=True)
wbImport.Worksheets("Exception").Range("F2",Range("F2").end(xldown)).Copy
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub
Error I get is runtime erorr '1004': Interface not registered

Assuming you run this in an Excel VBA? You don't need to open the other workbook as an Excel.Application, just remove the app out of it and open the workbook normally:
Sub GetClassID()
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.Sheets("Another Sheet Name")
Dim wbImport As Workbook
Set wbImport = Workbooks.Open(Filename:="C:\Test.xlsx", UpdateLinks:=True, ReadOnly:=True)
With wbImport.Worksheets("Exception")
.Range("F2", .Range("F2").End(xlDown)).Copy
End With
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub

In my experience, the most effective way to copy a dynamic range is to create a variable as an integer and assign the row of the last cell to be copied (or column if needing to select a row of data across to a certain point. I usually accomplish it with something like this:
Dim R as Integer
With ThisWorkbook.Worksheets
R = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
Then you can plug in 'R' for the row number in a range to make it dynamic each time the macro is ran. For instance: .Range("A1:A" & R).Copy would copy the used range in Column A. It also makes it really easy to reference the last row for loops and such continuously throughout your code. Hope this helps!

Related

How do I Copy spreadsheet formats while updating a given cell with a counter in vba?

The project I am working on is the creation of a macro in Excel that copies the format from a given tab and duplicates it into subsequent tabs.
Just as a heads up, this is my first exposure to VBA but I do have some experience with C++
I have already found a good template to work with for the above that does the task well enough and is as follows:
Public Sub CopySheetAndRenameByCell()
Dim wks As Worksheet
Set wks = ActiveSheet
ActiveSheet.Copy After:=Worksheets(Sheets.Count)
If wks.Range("H9").Value <> "" Then
On Error Resume Next
ActiveSheet.Name = wks.Range("H9").Value
End If
wks.Active
End Sub
The problem I am trying to solve at this point is integrating a line of code that acts as a counter which updates the value of the given cell by +1 with every new sheet and references the updated cell for the sheet label.
Any insights would be appreciated.
Public Sub AddNewPage()
Sheets(Sheets.Count).Select 'references last sheet in workbook
Dim wks As Worksheet 'establish static variable wks to reference worksheets
Set wks = ActiveSheet 'set wks to be the defined active sheet
ActiveSheet.Copy After:=Worksheets(Sheets.Count)
Range("H9").Value = Range("H9").Value + 1 'sets value of cell H9 in new worksheets to sequentially increase by 1
If wks.Range("H9").Value <> "" Then
On Error Resume Next
wks = Sheets(Sheets.Count).Select 'references last sheet in workbook
ActiveSheet.Name = wks.Range("H9").Value + 1 'sets page title to sequentially increase by 1 with each iteration
End If
wks.Activate
End Sub
This is the solution I came up with with a little help from the internet. Thank you for the responses.

copy and paste error causing workbook to crash

I'm having an issue with copy and pasting from one spreadsheet to another.
I am using the following code:
Sub LoadnH()
Dim NF As Workbook
Dim shtMain As Worksheet
Set shtMain = Worksheets("Main")
Dim filePath As String
Dim strFileName As Variant
strFileName = Application.GetOpenFilename("All Files (*.*), *.*", , "Select File to Import", , False)
shtMain.Range("filePath").Value = strFileName
If strFileName <> False Then
Set NF = Application.Workbooks.Open(strFileName)
Application.CutCopyMode = False
NF.Sheets("Summary").Copy
Application.DisplayAlerts = False
NF.Close False
Dim nH As Worksheet
Set nH = Worksheets("Hedge Data")
nH.Activate
With nH
.Cells.Clear
.Pictures.Delete
.Range("A1").Select
.PasteSpecial xlPasteValues
End With
End If
End Sub
The code errors out at the following point
.PasteSpecial xlPasteValues
The code show a runtime error '1004':
Method 'PasteSpecial' of object'_Worksheet' failed
how can I fix this so this error? Many times when it hits this error excel will crash and shutdown as well.
To Avoid Select and other similar methods you can assign your value of the destination range with the value from your source range.
You are using the Worksheet.Copy method which copies an entire Worksheet not the data in a Range of the worksheet. This will be creating a new copy of your source worksheet each time you run the code but not copying the data of the worksheet to the clipboard. (NB: below demonstrates using the Before parameter which dictates where the Worksheet will be copied to).
The Range.Copy method will copy the defined range's data to the clipboard (unless you specify the destination parameter).
Rather than using Copy/Paste etc. you can assign the value of the destination range with the value from your source range.
These examples below are all for demonstration of the above points and are tested using 2 new workbooks with default names for the workbooks and worksheets.
E.g 1
Sub WorksheetCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Copy DestinationWorksheet
End Sub
The result of this test creates a copy of Sheet1 from Book1 before Sheet1 on Book2.
E.g 2
Sub RangeCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Range("A1").Copy
DestinationWorksheet.Range("A1").PasteSpecial xlPasteValues
End Sub
This example copies cell A1 from Book1 - Sheet1 and pastes it to cell A1 in Book2 - Sheet1.
E.g 3
Sub AvoidSelectMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
DestinationWorksheet.Range("A1").Value = SourceWorksheet.Range("A1").Value
End Sub
This example assigns the Value property of A1 from Book1 - Sheet1 to cell A1 in Book2 - Sheet1. It's the same outcome as E.g 2 but avoids using Select, Copy & Paste etc. This method is much faster and generally less error prone than the 2nd example.
Depending on your environment, the first example may be the easiest and quickest method.

How to copy a range of cell from another workbook and paste it to another one?

I need to update my main file every time a third party sends me an updated version of his input. Therefore, I need to copy-paste the range of this new input in a saved workbook on my computer. The range needs to include all columns and all rows if the value in column A is greater than 0. For example, in the picture below, from A1 to A45.
enter image description here
I found a way to select the rows and stop at the first zero. I've put a sum-product formula on the side that I call in my code i.
For now, I have this code:
I have an error on line
Set wb2 = Workbooks("20200403 Selina - Loanbook V2.09 (1).xls")
I can't fix it... I have tried ThisWorkbook but nothing, do you have any idea?
Let me know :)
Antoine
Sub CopyPaste()
Dim wb1 As Workbook
Dim wb2 As Workbook
'Open Workbook from Pepper
Set wb1 = Workbooks.Open("G:\Shared drives\Reporting\Power BI Source Files- DO NOT TOUCH\Pepper Automation\Accounts latest\Accounts updated\Accounts_latest.xlsx")
'Copy Range (Column A to BW - all filled rows)
Dim i As Integer
i = Worksheets("Accounts_latest").Range("CA1").Value
wb1.Worksheets("Accounts_latest").Range("A1:BW" & i).Copy
'Paste to worksheet in workbook2:
Set wb2 = Workbooks("20200403 Selina - Loanbook V2.09 (1).xls")
wb2.Activate
wb2.Sheets("Pepper Accounts RAW").Range("A1").PasteSpecial Paste:=xlPasteValues
Range("A1").Select
'Close workbook
wb1.Close savechanges:=True
Application.DisplayAlerts = True
End Sub
something like this
Set wb2 = Workbooks.Open("20200403 Selina - Loanbook V2.09 (1).xls")
wb2.Close savechanges:=True

copy non empty rows from a subset of columns to another worksheet

Total VBA noob here, so bear with me, please.
I have a workbook that has 67 columns, of which I only need the data of 14 columns pasted into a new worksheet and then is formatted into a table. This source workbook is updated daily with new rows of data that I would like to update the new worksheet and table with the update data.
My Current workflow is as follows:
Download Source Workbook with updates.
I copy the source workbook into MasterList, as is no modifications. I make sure to copy only rows and columns with data.
In the Master List Sheet I placed an Update button, so that it copies the columns I need from MasterList to MasterTable.
I found a solution that copies the data but it appears that it copies all of the rows whether they have data or not. Resulting in the new table having 100,000+ rows and really slowing down my excel app and hanging my system.
Here is the code that I am using to accomplish the copy and paste. I
Sub Button1_Click()
Worksheets("MasterList").Activate
Worksheets("MasterList").Range("I:I,J:J,K:K,L:L,M:M,N:N,S:S,X:X,Y:Y,Z:Z,AA:AA,AC:AC,AD:AD").Select
Selection.Copy
Worksheets("MasterTable").Activate
Worksheets("MasterTable").Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
If hiding the unnecessary columns weren't so tedious every time I get a new update I could live with that set up, but I am hoping there is a faster more efficient way to accomplish this.
I appreciate any directions or suggestions.
Don't use .select or .activate. It is resource heavy / slow.
Tested and working.
Sub test()
' These will help with the speed of your macro.
' This turns of calculations
Application.Calculation = xlCalculationManual
' This runs the macro "behind the scenes"
Application.ScreenUpdating = False
' Always dim your variables
Dim lRow As Long
Dim wb As Workbook: Set wb = ThisWorkbook
Dim Sourcews As Worksheet: Set Sourcews = wb.Worksheets("MasterList")
Dim Destinationws As Worksheet: Set Destinationws = wb.Worksheets("MasterTable")
' find the last row of the source ws
lRow = Sourcews.Cells(Sourcews.Rows.Count, "I").End(xlUp).Row
' "select" from row 1 to the last row containing data and paste to the destination ws
Sourcews.Range("I1:N" & lRow & ", S1:S" & lRow & ", X1:AA" & lRow & ", AC1:AD" & lRow).Copy Destination:=Destinationws.Range("A1")
' turn the calculations and screen updating back on
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Autofilter a protected excel sheet opened from access

Im currently moving some code from excel to access. In excel there is a button that opens another excel document and applies an autofilter.
Dim cell As Long
cell = Sheet2.Cells(9, "i").Value
Workbooks.Open Filename:= _
"C:/worksheet1.xls"
Selection.AutoFilter Field:=3, Criteria1:=cell
This is the code from excel and it used to work fine but now also throws an error because the sheet is protected.
Using some code I got from this thread Autofilter Excel with VBA
I came up with code that should work in access but doesn't
What I have so far is
Dim oApp As Object
Dim wb As Object
Dim ws As Object
Set oApp = CreateObject("Excel.Application")
oApp.Visible = True
'tries to open workbook
On Error Resume Next
'change file path to the correct one
Set wb = oApp.Workbooks.Open(FileName:="C:/worksheet1.xls")
On Error GoTo 0
'if workbook succesfully opened, continue code
If Not wb Is Nothing Then
'specify worksheet name
Set ws = wb.Worksheets("BOM")
With ws
'apply new filter
.Cells(3, 3).Select
.AutoFilter Field:=3, Criteria1:=110, Operator:=7
End With
End If
Set wb = Nothing
Set oApp = Nothing
Im getting an error on the .AutoFilter Field:=3, Critera1:=110, Operator:=7
I cant just select a range to autofilter because the sheet is protected and I do not have write access. There is already autofilters in place on the sheet I just need to set the value of one.
Does anybody know a solution to this in either access or excel but preferably both?
Thanks
I believe an AutoFilter needs to be applied to a Range. Your "With" statement resolves to a worksheet, not a range.
ws.Range(xxxxxx).Autofilter Field:=3, Criteria1:=110, Operator:=7
Unless someone that has access to the worksheet changes the protection using information from the following link, this cannot be done.
http://office.microsoft.com/en-us/excel-help/enable-autofilter-functionality-for-a-protected-worksheet-HA001098270.aspx
I hope this helps.

Resources