Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel VBA, getting range from an inactive sheet

Tags:

excel

vba

This script works fine when I'm viewing the "Temp" sheet. But when I'm in another sheet then the copy command fails. It gives an Application-defined or object-defined error:

Sheets("Temp").Range(Cells(1), Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial

I can use this script instead, but then I have problems with pasting it:

Sheets("Temp").Columns(1).Copy
Sheets("Overview").Range("C40").PasteSpecial

I don't want to activate the "Temp" sheet to get this.

What else can I do?

like image 643
Aziz Avatar asked Nov 08 '11 08:11

Aziz


People also ask

Can you select a worksheet without activating it?

If a worksheet is not the active sheet, it cannot have a selection nor an activecell. There is one Selection for the entire Excel application instance regardless of how many workbooks or worksheets or windows are open.

How do you reference a range in VBA?

If the Excel VBA Range object you want to refer to is a single cell, the syntax is simply “Range(“Cell”)”. For example, if you want to make reference to a single cell, such as A1, type “Range(“A1″)”.


3 Answers

Your issue is that the because the Cell references inside the Range 's are unqualified, they refer to a default sheet, which may not be the sheet you intend. For standard modules, the ThisWorkbook module, custom classes and user form modules, the defeault is the ActiveSheet. For Worksheet code behind modules, it's that worksheet.

For modules other than worksheet code behind modules, your code is actually saying

Sheets("Temp").Range(ActiveSheet.Cells(1), ActiveSheet.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial

For worksheet code behind modules, your code is actually saying

Sheets("Temp").Range(Me.Cells(1), Me.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial

In either case, the solution is the same: fully qualify the range references with the required workbook:

Dim sh1 As Worksheet
Dim sh2 As Worksheet

Set sh1 = ActiveWorkbook.Sheets("Temp")
Set sh2 = ActiveWorkbook.Sheets("Overview")

With sh1
    .Range(.Cells(1,1), .Cells(1,1).End(xlDown)).Copy
End With
sh2.Range("C40").PasteSpecial

Note: When using .End(xlDown) there is a danger that this will result in a range extending further than you expect. It's better to use .End(xlUp) if your sheet layout allows. If not, check the referenced cell and the cell below for Empty first.

like image 93
chris neilsen Avatar answered Oct 19 '22 22:10

chris neilsen


I encountered a problem like this myself: I was trying to search through a separate worksheet to see if the color of a cell matched the color of a cell in a list and return a string value: if you are using .Cells(row, column), you only need this: Sheets("sheetname").Cells(row, column) to reference that range of cells.

I was looping through a block of 500 cells and it works surprisingly quickly for me.

I have not tried this with .Copy, but I would assume it would work the same way.

like image 3
Anonymous Avatar answered Oct 19 '22 23:10

Anonymous


This will do, I don't like to use (xlDown) in case a cell is empty.

Dim lRow As Long
lRow = Sheets("Temp").Cells(Cells.Rows.Count, "A").End(xlUp).Row

With Sheets("Temp")
     .Range("A1:A" & lRow).Copy Sheets("Overview").Range("C40")
End With

Or if you want to just use Columns...

Sheets("Temp").Columns(1).SpecialCells(xlCellTypeConstants).Copy Destination:=Sheets("Overview").Range("C40")
like image 1
GMalc Avatar answered Oct 20 '22 00:10

GMalc