¿Por qué funciona Range, pero no Cells?

Estoy tratando de mover algunos datos de un libro de trabajo a otro asignando los valores de un rango a otro. Cuando uso la syntax de Rango normal para especificar el rango de destino (Rango (“A1: B2”)) mi código funciona, pero si trato de usar la syntax de Rango, Células (Rango (Células (1,1), Células (2) , 2))) mi código no funciona.

Activo el libro de trabajo de destino (ActiveWorkbook) y ejecuto el código en el libro de trabajo de origen (ThisWorkbook).

Este código funciona:

ActiveWorkbook.Worksheets(1).Range("A1:B2").Value _ = ThisWorkbook.Worksheets(1).Range(Cells(1, 1), Cells(2, 2)).Value 

Pero este código no:

 ActiveWorkbook.Worksheets(1).Range(Cells(1, 1), Cells(2, 2)).Value _ = ThisWorkbook.Worksheets(1).Range(Cells(1, 1), Cells(2, 2)).Value 

El error que obtengo es el error en tiempo de ejecución ‘1004’: error definido por aplicación o error definido por el objeto.

¿Alguien sabe por qué usar el objeto de las celdas me está causando problemas, o si hay algún otro problema que desconozco?

El problema es que Cells no está calificado, lo que significa que la hoja a la que se refieren esas celdas es diferente dependiendo de dónde esté el código. Cada vez que llama a Range o Cells o Rows o UsedRange o cualquier cosa que devuelva un objeto Range, y no especifica en qué hoja está, la hoja se asigna de acuerdo con:

  • En el módulo de clase de una hoja: esa hoja independientemente de lo que esté activo
  • En cualquier otro módulo: el ActiveSheet

Califica la referencia de Range , pero la referencia de Cells no está calificada y probablemente esté apuntando a la Hoja de Activo. Es como escribir

 ThisWorkbook.Worksheets(1).Range(ActiveSheet.Cells(1, 1), ActiveSheetCells(2, 2)).Value 

que, por supuesto, no tiene ningún sentido a menos que ThisWorkbook.Worksheets (1) esté activo. A menudo me gusta usar un bloque With para asegurarme de que todo esté completamente calificado.

 With Sheets(1) .Range(.Cells(1,1), .Cells(2,2)).Value = "something" End With 

Pero se refiere a dos hojas diferentes, por lo que será mejor que use variables de hoja cortas como:

 Dim shSource As Worksheet Dim shDest As Worksheet Set shSource = ThisWorkbook.Worksheets(1) Set shDest = Workbooks("myBook").Worksheets(1) shDest.Range(shDest.Cells(1, 1), shDest.Cells(2, 2)).Value = _ shSource.Range(shSource.Cells(1, 1), shSource.Cells(2, 2)).Value 

Pero en realidad, si va a codificar los argumentos de Cells , podría limpiar eso como

 shDest.Cells(1, 1).Resize(2, 2).Value = shSource.Cells(1, 1).Resize(2, 2).Value