¿Cuál es la diferencia entre dim y set en vba?

82

Perdóname porque soy un novato en VBA.

A veces uso

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

Otras veces uso

Set r = Range("A1")

¿Cuál es la diferencia? ¿Y cuándo debería usar qué?

RAM
fuente

Respuestas:

78

No hay razón para usarlo a setmenos que se refiera a una referencia de objeto. Es una buena práctica usarlo solo en ese contexto. Para todos los demás tipos de datos simples, simplemente use un operador de asignación. Sin dimembargo, es una buena idea (dimensionar) TODAS las variables:

Los ejemplos de los tipos de datos simples serían integer, long, boolean, string. Estos son solo tipos de datos y no tienen sus propios métodos y propiedades.

Dim i as Integer
i = 5

Dim myWord as String
myWord = "Whatever I want"

Un ejemplo de un objectsería a Range, a Worksheeto a Workbook. Estos tienen sus propios métodos y propiedades.

Dim myRange as Range
Set myRange = Sheet1.Range("A1")

Si intenta utilizar la última línea sin Set, VB arrojará un error. Ahora que tiene un objectdeclarado, puede acceder a sus propiedades y métodos.

myString = myRange.Value
Michael
fuente
3
¿Puedo saber a qué tutorial o libro te refieres para entender esto?
Ram
18
Esta respuesta realmente no explica el "por qué"
kizzx2
1
VBA es muy inteligente, no requiere que le digas qué diablos estás haciendo como muchos idiomas. Sin embargo, esto agrega tiempo. Si está utilizando una gran cantidad de dimensiones diferentes en todo tipo de variantes diferentes, el tiempo se suma. Si le dice a VBA qué esperar cuando ve una variable, entonces no tiene que resolverlo. Además, si le dice a VBA que una variable es un número entero, no una cadena, entonces no ocupará tanta RAM. Aunque el último punto probablemente no sea tan válido en proyectos de VBA pequeños comunes, sigue siendo una buena práctica de codificación.
Rápido
¿Está bien usarlo Setsin Dimla variable primero?
solstice333
64

Sin embargo, no creo que esto sea lo que realmente estás preguntando.

A veces uso:

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

Esto nunca funcionará. Sin Set, recibirá el error de tiempo de ejecución # 91 Variable de objeto o Con variable de bloque no establecida . Esto se debe a que debe utilizar Setpara asignar un valor de variable a una referencia de objeto. A continuación, el código anterior será trabajar.

Creo que el siguiente código ilustra lo que realmente estás preguntando. Supongamos que no declaramos un tipo y dejamos rser un Varianttipo en su lugar.

Public Sub test()
    Dim r
    debug.print TypeName(r)

    Set r = Range("A1")
    debug.print TypeName(r)

    r = Range("A1")
    debug.print TypeName(r)
End Sub

Entonces, analicemos lo que sucede aquí.

  1. r se declara como una variante

    `Dim r` ' TypeName(r) returns "Empty", which is the value for an uninitialized variant
    
  2. rse establece en la Rangecelda contenedora "A1"

    Set r = Range("A1") ' TypeName(r) returns "Range"
    
  3. rse establece en el valor de la propiedad predeterminada de Range("A1").

    r = Range("A1") ' TypeName(r) returns "String"
    

En este caso, la propiedad predeterminada de un rango es .Value, por lo que las siguientes dos líneas de código son equivalentes.

r = Range("A1")
r = Range("A1").Value

Para obtener más información sobre las propiedades de objeto predeterminadas, consulte "Miembro predeterminado de una clase" de Chip Pearson .


En cuanto a tu Setejemplo:

Otras veces uso

Set r = Range("A1")

Esto no funcionaría sin antes declarar que res un objeto Rangeu Variant... usando la Dimdeclaración, a menos que no lo haya Option Explicithabilitado, lo que debería. Siempre. De lo contrario, está utilizando identificadores que no ha declarado y todos se declaran implícitamente como Variantes .

RubberDuck
fuente
@PierreClaverie Sí :) incluye las referencias originales para Dim and Set
Wolf
1
@Wolf no estoy seguro si lo sabe, pero la referencia de lenguaje de VBA ahora se mantiene en github. github.com/OfficeDev/VBA-content/blob/master/VBA/…
RubberDuck
@RubberDuck No estaba al tanto (soy nuevo en vb *), gracias por agregar esta nota.
Wolf
De nada @Wolf. Sé que los documentos VBA y VB6 antiguos pueden ser difíciles de encontrar en estos días.
RubberDuck
8

Dim: está definiendo una variable (aquí: r es una variable de tipo Range)

Establecer: está configurando la propiedad (aquí: establezca el valor de r en Rango ("A1"); esto no es un tipo, sino un valor).

Tienes que usar set con objetos, si r fuera un tipo simple (por ejemplo, int, string), entonces simplemente escribirías:

Dim r As Integer
r=5
Tobias Schittkowski
fuente
3

Dim simplemente declara el valor y el tipo.

Set asigna un valor a la variable.

Justin Niessner
fuente
2

Si una variable se define como un objeto, por ejemplo, Dim myfldr As Folder, se le asigna un valor mediante la palabra clave "Set".

usuario2479175
fuente
1

Dim es la abreviatura de Dimension y se usa en VBA y VB6 para declarar variables locales.

Set, por otro lado, no tiene nada que ver con declaraciones de variables. La Setpalabra clave se utiliza para asignar una variable de objeto a un nuevo objeto.

Espero que te aclare la diferencia.

IqbalHamid
fuente
0

De acuerdo con la ayuda de VBA en la declaración SET, establece una referencia a un objeto. Por lo tanto, si cambia una propiedad, el objeto real también cambiará.

Dim newObj as Object
Set var1=Object1(same type as Object)
Set var2=Object1(same type as Object)
Set var3=Object1(same type as Object)
Set var4=Object1(same type as Object)
Var1.property1=NewPropertyValue

las otras propiedades de Vars también cambian, entonces:

Var1.property1=Var2.property1=Var3.property1=Var4.property1=Object1.Property1=NewpropertyValue`

¡en realidad todas las vars son iguales!

Soroush
fuente