¿Cuándo se debería usar Set ?

Me temo que no entiendo bien la documentación de VBA para Excel, tengo esta línea que parece ser un error:

Range a = Selection.SpecialCells(xlCellTypeConstants, 23) 

Pero este está bien:

 Set a = Selection.SpecialCells(xlCellTypeConstants, 23) 

La documentación afirma:

Devuelve un objeto Range que representa todas las celdas que coinciden con el tipo y valor especificado.

Pero en realidad devuelve un objeto byRef y es por eso que tengo que usar Set .

¿Qué extraño aquí?

Aquí está la Range.SpecialCells método Range.SpecialCells en Excel:

enter image description here

 Range a = Selection.SpecialCells(xlCellTypeConstants, 23) 

Esto no es VBA válido, independientemente del tipo de datos. No declara el tipo de variable delante del nombre de la variable, como lo haría en C #, y no inicializa la variable en el punto de statement, como haría en VB.NET.

Tu puedes hacer:

 Dim a As Range Set a = Selection.SpecialCells(xlCellTypeConstants, 23) 

Esto guardará una referencia al rango en a .

También puedes hacer:

 Dim a As Variant a = Selection.SpecialCells(xlCellTypeConstants, 23) 

Esto guardará en a matriz 2D de valores de celdas en el rango.

Devuelve un objeto Range que representa todas las celdas que coinciden con el tipo y valor especificado.

Pero en realidad devuelve un objeto byRef y es por eso que tengo que usar Set.

No hay objetos de byval en VBA. Todos los objetos son byref, y cuando quiere copiar una referencia a un objeto, siempre usa Set . La razón por la que necesita Set es propiedades predeterminadas. Cada objeto puede tener una propiedad predeterminada que se solicita cuando solo se proporciona el nombre del objeto. Esto crea ambigüedad, por lo que debe decir Set cuando necesite manipular la referencia del objeto por su cuenta, y omita Set cuando desee la propiedad predeterminada de un objeto. La propiedad predeterminada de Range es Value .

Las variables de objeto se asignan usando la palabra clave Set. Las variables no objeto (ignoremos las variantes por ahora) no usan la palabra clave Establecer

 dim a as int dim b as string dim c as boolean a = 1 b = "hello" c = false dim a as Range dim b as Worksheet dim c as PivotTable set a = ActiveSheet.Range("a1") set b = ActiveSheet set c = ActiveSheet.PivotTables(1) 

enter image description here

El método Range.SpecialCells devuelve un objeto Range que representa todas las celdas que coinciden con el tipo y valor especificado. set keyworkd se usa para asignar una referencia a un objeto.

Hay dos tipos de asignaciones en VBA: una para variables ordinarias, que utilizan Let, y otra para variables de objeto, que usan Set.

Una variable ordinaria (cadena, lógica, numérica) es aquella que apunta a la ubicación en la memoria donde se almacena la variable.

Una variable de objeto (todas las cosas que se encuentran en la referencia del lenguaje en Objetos) es aquella que apunta a una estructura en la memoria (una tabla V) que a su vez contiene punteros a las propiedades y métodos del objeto.

Referencia http://www.excelforum.com/excel-programming-vba-macros/693357-when-to-use-the-keyword-set.html

No sé si esto importa, pero el Value no es propiedad predeterminada de Range . La propiedad predeterminada de Range es _Default .

enter image description here

Se define así _Default([in, optional] VARIANT RowIndex, [in, optional] VARIANT ColumnIndex) y representa la matriz de valores de un rango particular.

 Sub test() Dim rng As Range Set rng = ActiveSheet.Range("A1:C3") ' all cells in range rng become value of 1 rng.Value = 1 ' all cells in range rng become now value of 2 rng.[_Default] = 2 ' first cell in range rng become value of 3 rng.[_Default](1, 1) = 3 ' nothing changes rng.Value()(1, 1) = 4 Dim a1, a2 ' however both Value and _Default return same array of variants a1 = rng.Value a2 = rng.[_Default] End Sub