En mis macros cuando hago referencia a un valor encontrado en una celda, he estado usando inconsistentemente .cell (r, c) o .cell (r, c) .value.

dim c as variant 
c = sheet1.cell(1,1) 'or sheet1.cell(1,1).value

¿Ambas referencias son correctas o hay una forma preferida?

vba
4
lostinOracle 20 mar. 2017 a las 03:47

2 respuestas

La mejor respuesta

.Value es la propiedad predeterminada del objeto de rango. Por lo tanto, cuando asigna algo como esto:

myVar = myRange

Es equivalente a myVar = myRange.Value, porque está asignando una variable no un Objeto .

Sin embargo, si usa Set, así:

Set myObj = myRange

Estaría asignando una referencia de objeto. La palabra clave Set le dice a VBA que está asignando una referencia de objeto. La ausencia de Set hace que VBA concluya que quiere obtener implícitamente el .value, la propiedad predeterminada del rango.

Es una buena práctica de programación usar .value explícitamente, por dos razones:

1- Hace que el código sea más legible, porque el lector no tiene que adivinar lo que está sucediendo implícitamente

2- Con la llegada de VB.net, la palabra clave Set ha desaparecido; La sintaxis para asignar un objeto o una variable normal se convierte en la misma. Por esta razón, la expresión propiedad predeterminada ha desaparecido con VB.net. Por lo tanto, una buena práctica es usar .value también en VBA, porque hace que la transferencia de su código a VB.net sea mucho más fácil.

6
A.S.H 20 mar. 2017 a las 02:00

Siempre uso .Value2 para obtener el valor de una celda (o una matriz de variables de un rango). Si no uso .Value2 significa que quiero una referencia a los objetos Range y no el valor. Por ejemplo

Dim r as Range
Set r = Range("A1")

Dim x as Double, i as Integer
x = r.Offset(1,0).Value2

Dim vals() as Variant
vals = r.Offset(1,0).Resize(10,1).Value2

For i=1 to 10
    vals(i,1) = CDbl(i)/10
Next i

r.Offset(1,0).Resize(10,1).Value2 = vals

Además, no uso el método Cell() porque la ubicación de las células puede cambiar en el futuro. Utilizo rangos con nombre con los métodos .Offset() y .Resize() para establecer el rango de celdas en las que quiero leer o escribir valores. Entonces, en el código anterior, nunca usaría Range("A1") pero algo como Range("my_table") con un rango con nombre "my_table" definido en la celda superior izquierda de donde interactúo.


Hay un acceso directo poco conocido para obtener el valor de una celda con la notación []

Dim x as Double
x = [A2]
// This is the same as x = Range("A2").Value2
0
John Alexiou 20 mar. 2017 a las 02:17