Es el . en .Range necesario cuando está definido por .Cells?
Está ampliamente aceptado que ésta no es la "mejor práctica".
dim rng as range
with thisworkbook '<~~ possibly set an external workbook
with .worksheets("sheet1")
set rng = .range(cells(2, 1), cells(rows.count, 1).end(xlup))
end with
end with
Las dos propiedades Range.Cells que definen el alcance del objeto Range utilizarán de forma predeterminada la propiedad ActiveSheet . Si esta no es la Hoja1 (definida como .Parent en la instrucción With... End With ), la asignación fallará con,
Run-tim error '1004': Application-defined or object-defined error
Solución: .Cells
no usar Cells
. Caso cerrado.
Pero...
¿Es .
necesario en esta definición de objeto Range cuando ambas propiedades Range.Cells heredan la propiedad de la hoja de trabajo .Parent que se define en la declaración With... End With ?
¿Cómo puede esto?
dim rng as range
with thisworkbook '<~~ possibly set an external workbook
with .worksheets("sheet1")
' define rng as Sheet1!A2 to the last populated cell in Sheet1!A:A
set rng = .range(.cells(2, 1), .cells(rows.count, 1).end(xlup)) '<~~ .range
end with
end with
debug.print rng.address(0, 0, external:=true)
... ser diferente de esto,
dim rng as range
with thisworkbook '<~~ possibly set an external workbook
with .worksheets("sheet1")
' define rng as Sheet1!A2 to the last populated cell in Sheet1!A:A
set rng = range(.cells(2, 1), .cells(rows.count, 1).end(xlup)) '<~~ range not .range
end with
end with
debug.print rng.address(0, 0, external:=true)
Lo utilizamos .range
cuando los parámetros que definen el alcance del rango son ambiguos; por ejemplo .range([A1])
, la A1
celda podría ser de cualquier hoja de trabajo y su valor predeterminado será la propiedad ActiveSheet sin el archivo .
. Pero, ¿por qué necesitamos hacer referencia al padre de un objeto de rango cuando el alcance que lo define ha hecho referencia correctamente a su hoja de trabajo principal?
Mi opinión es ligeramente diferente aquí.
SÍ es necesario. No siempre se puede controlar desde dónde el usuario puede ejecutar el código.
Considere estos pocos casos de prueba
GUIÓN
El libro de trabajo tiene 2 hojas de trabajo. Hoja1 y Hoja2
TEST 1 (Ejecutando desde un módulo)
Ambos códigos dan el mismo resultado.
TEST 2 (Ejecutando desde un área de código de Hoja de Hoja1)
Ambos códigos dan el mismo resultado.
TEST 3 (Ejecutando desde un área de código de Hoja de Hoja2)
'~~> This code fails
set rng = range(.cells(2, 1), .cells(rows.count, 1).end(xlup))
Recibirás Application Defined or Object defined
un error
Y por eso siempre es recomendable calificar adecuadamente sus objetos para que el código pueda ejecutarse desde cualquier lugar.
No, .
no es obligatorio cuando las referencias de celda dentro de los corchetes están calificadas, a menos que el código esté en un Worksheet
módulo. Dicho esto, es más rápido ejecutarlo set rng = .range(.cells(...), .cells(...))
que ejecutarlo, set rng = range(.cells(...), .cells(...))
por lo que incluirlo .
hace algún bien.
Para un Worksheet
módulo, se .
requiere.
La respuesta parece ser: sólo si el código está ubicado en un objeto Hoja de trabajo. Sospecho firmemente que esto se debe a que los objetos de la hoja de trabajo son los únicos que son extensibles y tienen una Range
función. Cuando Range
se llama desde una hoja de trabajo, la Range
función de ese objeto tiene alcance. Cuando el código se encuentra en ThisWorkbook o en un módulo o clase de usuario, la Range
función con el alcance disponible más cercano es el Range
objeto global (suponiendo, por supuesto, que no haya una Range
función definida por el usuario). Ese está vinculado al Application
, que tiene que resolverlo en función de los parámetros pasados y reenviar la llamada a la hoja de trabajo correcta.