2012-06-18 5 views
5

Acabo de resolver un problema que estaba teniendo poner la palabra clave "Establecer" en una línea de definición pero lo que me gustaría saber es "por qué"?Diferencia en el tipo entre usar y no usar Establecer palabra clave

Básicamente, estoy haciendo esto:

Dim startCell, iCell as Range 
For Each iCell in Range(whatever) 
    If iCell.value <>"" Then 
     Set startCell = Cells(iCell.Row + 1, iCell.Column) 
    End If 
Next iCell 

Si Omito el "ajuste" palabra clave del código todavía compila bien, pero en la ventana variables locales veo que su tipo cambia a "cadena" en lugar de "Variante/Objeto/Rango". ¿Por qué sucedería eso?

+1

startCell no es del tipo de rango aquí ... – Qbik

Respuesta

14

Esto es por qué. Cuando se dice esto:

Dim startCell, iCell As Range 

que creo que haya hecho esto:

Dim startCell As Range, iCell As Range 

pero lo tienes muy hecho es la siguiente:

Dim startCell 'As Variant, by default 
Dim iCell As Range 

Este es un error clásico de VBA. La mayoría de los programadores de VBA lo han logrado, y es por eso que la mayoría de los programadores de VBA recurren a declarar solo una variable por declaración Dim (es decir, una por línea). De lo contrario, es demasiado fácil cometer ese error y es difícil detectarlo después.

Así que con Dim startCell ha declarado implícitamente su variable como tipo de Variante (equivalente a Dim startCell As Variant).

Cuando a continuación, dice esto:

Set startCell = Cells(iCell.Row + 1, iCell.Column) 

la variante adquiere el tipo de la cosa en el lado derecho de la asignación de referencia (rango). Sin embargo, cuando se dice esto:

startCell = Cells(iCell.Row + 1, iCell.Column) 

sin la palabra clave Set, no estamos asignando una referencia, pero un valor a la variable startCell, que ahora adquiere el tipo del valor en el lado derecho. ¿Qué es ese tipo? Bueno, la propiedad predeterminada de un objeto Range es Value, por lo que obtendrá el tipo de Cells(iCell.Row + 1, iCell.Column).Value. Si esa celda contiene una cadena, obtendrás una cadena.

1

Debe utilizar la palabra clave Establecer al asignar un objeto a una variable. Cells(iCell.Row + 1, iCell.Column) está devolviendo un objeto Rango, por lo tanto Conjunto debe usarse, de lo contrario obtendrá el error VBA favorito de todos: 91: Object variable or With block variable not set.

Editar:

objetos gama tienen una propiedad de retorno por defecto, así, que es la propiedad 'Valor'. Si tuviera que hacer referencia al rango ("A1"), tomaría los rangos 'Valor' como valor predeterminado para una variante. Es por eso que debe evitar el uso de variantes cuando el tipo de datos se conoce con anticipación.

+0

... sin embargo, como dice en la pregunta, no está recibiendo ese error. ¿Por qué? Eso es lo que hace que esta pregunta sea interesante. –

3

Set se utiliza para asignar una referencia a un objeto, Let (o asignación simple) para asignar el valor de un objeto (si los hay)

Dim a As Variant 
    Set a = ActiveSheet.Cells(1) 
    'TypeName(a) = Range, a now contains reference to the cell's range 
    a = ActiveSheet.Cells(1) 
    'TypeName(a) = Double or String, whatever is in the Cell, a contains the cell's value 
Cuestiones relacionadas