Un objeto ArrayList es similar a un objeto Collection, pero tiene muchos más métodos y propiedades y, por lo tanto, una flexibilidad mucho mayor desde el punto de vista de la programación.
Un objeto Collection solo tiene dos métodos (Agregar, Eliminar) y dos propiedades (Recuento, Elemento), mientras que una Lista de matriz tiene muchas más. Además, el objeto Collection es de solo lectura. Una vez que se han agregado los valores, el valor indexado no se puede cambiar, mientras que en una Lista de matrices, es posible editar.
Muchos de los métodos Array List utilizan parámetros. A diferencia de muchos de los métodos estándar de VBA, ninguno de estos parámetros es opcional. Además, algunos de los métodos y propiedades no siempre se escriben en mayúsculas cuando se ingresan de la misma manera que lo hacen en Excel VBA. Sin embargo, todavía funcionan.
El objeto ArrayList se expande y contrae de tamaño según la cantidad de elementos que contiene. No es necesario dimensionarlo antes de usarlo como una matriz.
La Lista de matrices es unidimensional (igual que el objeto Colección) y el tipo de datos predeterminado es Variante, lo que significa que aceptará cualquier tipo de datos, ya sean numéricos, de texto o de fecha.
En muchos sentidos, la Lista de matrices aborda una serie de deficiencias del objeto Colección. Sin duda, es mucho más flexible en lo que puede hacer.
El objeto Array List no forma parte de la biblioteca VBA estándar. Puede usarlo en su código Excel VBA mediante el enlace tardío o temprano
1234 | Sub LateBindingExample ()Atenuar MyList como objetoEstablecer MyList = CreateObject ("System.Collections.ArrayList")End Sub |
123 | Sub EarlyBindingExample ()Atenuar MyList como nueva ArrayListEnd Sub |
Para usar el ejemplo de enlace temprano, primero debe ingresar una referencia en VBA al archivo "mscorlib.tlb"
Para ello, seleccione "Herramientas | Referencias 'de la ventana del Editor de Visual Basic (VBE). Aparecerá una ventana emergente con todas las referencias disponibles. Desplácese hacia abajo hasta "mscorlib.dll" y marque la casilla junto a él. Haga clic en Aceptar y esa biblioteca ahora es parte de su proyecto:
Uno de los grandes inconvenientes de un objeto Array List es que no tiene "Intellisense". Normalmente, cuando esté utilizando un objeto en VBA, como un rango, verá una lista emergente de todas las propiedades y métodos disponibles. No obtiene esto con un objeto Array List y, a veces, necesita una verificación cuidadosa para asegurarse de que haya escrito correctamente el método o la propiedad.
Además, si presiona F2 en la ventana de VBE y busca en "lista de matrices", no se mostrará nada, lo que no es muy útil para un desarrollador.
Su código se ejecutará considerablemente más rápido con el enlace temprano, porque todo está compilado por adelantado. Con el enlace tardío, el objeto debe compilarse a medida que se ejecuta el código.
Distribución de su aplicación de Excel que contiene una lista de matrices
Como ya se señaló, el objeto ArrayList no es parte de Excel VBA. Esto significa que cualquiera de sus colegas a los que distribuya la aplicación debe tener acceso al archivo "mscorlib.tlb".
Este archivo normalmente se encuentra en:
C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319
Podría valer la pena escribir algún código (usando el método Dir) para verificar que este archivo existe cuando un usuario carga la aplicación, de modo que experimente un "aterrizaje suave" si no lo encuentra. Si no está presente y el código se ejecuta, se producirán errores.
Además, el usuario debe tener instalada la versión de .Net Framework correcta. Incluso si el usuario tiene una versión posterior, se debe instalar V3.5; de lo contrario, su aplicación no funcionará
Alcance de un objeto de lista de matriz
En términos de alcance, el objeto Lista de matrices solo está disponible mientras el libro de trabajo está abierto. No se guarda cuando se guarda el libro. Si se vuelve a abrir el libro de trabajo, el objeto Lista de matrices debe volver a crearse con el código VBA.
Si desea que su Lista de matrices esté disponible para todo el código en su módulo de código, entonces debe declarar el objeto Lista de matrices en la sección Declarar en la parte superior de la ventana del módulo
Esto asegurará que todo su código dentro de ese módulo pueda acceder a la Lista de matrices. Si desea que cualquier módulo dentro de su libro de trabajo acceda al objeto Lista de matrices, defínalo como un objeto global
1 | MyCollection global como nueva ArrayList |
Rellenar y leer desde su lista de matrices
La acción más básica que desea realizar es crear una lista de matrices, poner algunos datos en ella y luego demostrar que los datos se pueden leer. Todos los ejemplos de código de este artículo asumen que está utilizando el enlace temprano y ha agregado "mscorlib.tlb" a las referencias de VBA, como se describe anteriormente.
123456789101112 | Sub ArrayListExample ()"Crear un nuevo objeto de lista de matricesAtenuar MyList como nueva ArrayList"Agregar elementos a la listaMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Iterar a través de la lista de matrices para probar los valoresPara N = 0 a MyList.Count - 1MsgBox MyList (N)Siguiente NEnd Sub |
Este ejemplo crea un nuevo objeto ArrayList, lo llena con 3 elementos y recorre la lista mostrando cada elemento.
Tenga en cuenta que el índice ArrayList comienza en 0, no 1, por lo que debe restar 1 del valor de Count
También puede utilizar un bucle "For … Each" para leer los valores:
123456789101112 | Sub ArrayListExample ()"Crear un nuevo objeto de lista de matricesAtenuar MyList como nueva ArrayList"Agregar elementos a la listaMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Iterar a través de la lista de matrices para probar los valoresPara cada yo en mi listaMsgBox ISiguiente yoEnd Sub |
Editar y cambiar elementos en una lista de matriz
Una de las principales ventajas de una lista de matrices sobre una colección es que los elementos de la lista se pueden editar y cambiar dentro de su código. El objeto Collection es de solo lectura, mientras que el objeto Array List es de lectura / escritura
123456789101112131415 | Sub ArrayListExample ()"Crear un nuevo objeto de lista de matricesAtenuar MyList como nueva ArrayList"Agregar elementos a la listaMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"‘Cambiar elemento 1 de" Elemento2 "a" Modificado "MyList (1) = "Cambiado""Itere a través de la lista de matrices para demostrar que el cambio funcionóPara cada yo en mi lista‘Mostrar nombre del elementoMsgBox ISiguiente yoEnd Sub |
En este ejemplo, el segundo elemento, "Elemento2" se modifica por el valor "Cambiado" (recuerde que el índice comienza en 0). Cuando la iteración se ejecuta al final del código, se mostrará el nuevo valor
Adición de una matriz de valores a una lista de matrices
Puede ingresar valores en su Lista de matrices utilizando una matriz que contenga una lista de estos valores o referencias a valores de celda en una hoja de trabajo
123456789101112131415161718 | Sub AddArrayExample ()"Crear objeto de lista de matrizAtenuar MyList como nueva ArrayList"Iterar a través de los valores de la matriz y agregarlos a la lista de la matrizPara cada v en matriz ("A1", "A2", "A3")"Agregue cada valor de matriz a la listaMyList.Add vpróximo‘Iterar a través de los valores de la matriz con referencias de la hoja de trabajo agregándolos a la lista de la matrizPara cada v en matriz (rango ("A5"). Valor, rango ("A6"). Valor)MyList.Add vpróximo"Iterar a través de la lista de matrices para probar los valoresPara N = 0 a MyList.Count - 1‘Mostrar elemento de listaMsgBox MyList.Item (N)Siguiente NEnd Sub |
Leer / recuperar un rango de elementos de una lista de matriz
Al utilizar el método GetRange en una lista de matrices, puede especificar una serie de elementos consecutivos que se recuperarán. Los dos parámetros necesarios son la posición inicial del índice y el número de elementos que se recuperarán. El código llena un segundo objeto Array List con el subconjunto de elementos que luego se pueden leer por separado.
123456789101112131415161718 | Sub ReadRangeExample ()"Definir objetosAtenuar MyList como nuevo ArrayList, MyList1 como objeto"Agregar elementos al objeto" MyList "MyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item6"MyList.Add "Item4"MyList.Add "Item7""Capture 4 elementos en" MyList "comenzando en la posición del índice 2Establecer MyList1 = MyList.GetRange (2, 4)"Itere a través del objeto" MyList1 "para mostrar el subconjunto de elementosPara cada yo en MyList1‘Mostrar nombre del elementoMsgBox ISiguiente yoEnd Sub |
Búsqueda de elementos dentro de una lista de matrices
Puede probar si un elemento con nombre está en su lista mediante el método "Contiene". Esto devolverá Verdadero o Falso
1 | MsgBox MyList.Contains ("Item2") |
También puede encontrar la posición del índice real utilizando el método "IndexOf". Debe especificar el índice de inicio de la búsqueda (generalmente 0). El valor de retorno es el índice de la primera instancia del elemento encontrado. Luego, puede usar un bucle para cambiar el punto de inicio al siguiente valor de índice para buscar más instancias si hay varios valores duplicados.
Si no se encuentra el valor, se devuelve un valor de -1
Este ejemplo demuestra el uso de "Contiene", elemento no encontrado y recorrer la lista de matrices para encontrar la posición de todos los elementos duplicados:
1234567891011121314151617181920212223242526 | Sub SearchListExample ()"Definir lista de matrices y variablesAtenuar MyList como New ArrayList, Sp como entero, Pos como entero"Agregar elementos nuevos, incluido un duplicadoMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1""Prueba para que" Item2 "esté en la lista: devuelve TrueMsgBox MyList.Contains ("Item2")‘Obtener índice de valor inexistente: devuelve -1MsgBox MyList.IndexOf ("Elemento", 0)‘Establecer la posición de inicio de la búsqueda en ceroSp = 0"Itere a través de la lista para obtener todas las posiciones de" Item1 "Hacer"Obtenga la posición de índice del siguiente" Item1 "según la posición en la variable" Sp "Pos = MyList.IndexOf ("Item1", Sp)"Si no se encuentran más instancias de" Item1 ", salga del cicloSi Pos = -1 Entonces Salir Hacer‘Mostrar la siguiente instancia encontrada y la posición del índiceMsgBox MyList (Pos) y "en el índice" y Pos"Agregue 1 al último valor de índice encontrado; ahora se convierte en la nueva posición de inicio para la siguiente búsquedaSp = Pos + 1CírculoEnd Sub |
Tenga en cuenta que el texto de búsqueda utilizado distingue entre mayúsculas y minúsculas y no se aceptan comodines.
Insertar y quitar elementos
Si no desea agregar sus elementos al final de la lista, puede insertarlos en una posición de índice particular para que el nuevo elemento esté en el medio de la lista. Los números de índice se ajustarán automáticamente para los elementos siguientes.
123456789101112131415 | Sub InsertExample ()"Definir objeto de lista de matrizAtenuar MyList como nueva ArrayList"Agregar elementos a la lista de arreglosMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1""Insertar" Elemento6 "en la posición del índice 2MyList.Insert 2, "Item6""Itere los elementos de la lista de matrices para mostrar el nuevo orden y la posición del índicePara N = 0 a MyList.Count - 1MsgBox MyList (N) & "Index" & NSiguiente NEnd Sub |
En este ejemplo, "Item6" se agrega a la lista en la posición de índice 2, por lo que el "item3" que estaba en la posición de índice 2 ahora se mueve a la posición de índice 3
Se puede eliminar un elemento individual mediante el método "Eliminar".
1 | MyList.Eliminar "Elemento" |
Tenga en cuenta que no se produce ningún error si no se encuentra el nombre del elemento. Todos los números de índice posteriores se cambiarán para adaptarse a la eliminación.
Si conoce la posición de índice del artículo, puede utilizar el método "RemoveAt", p. Ej.
1 | MyList.RemoveAt 2 |
Tenga en cuenta que si la posición del índice dada es mayor que el número de elementos en la lista de la matriz, se devolverá un error.
Puede eliminar un rango de valores de la lista mediante el método "RemoveRange". Los parámetros son el índice inicial y luego el número de elementos a eliminar, p. Ej.
1 | MyList.RemoveRange 3, 2 |
Tenga en cuenta que obtendrá un error en su código si el número de elementos desplazados desde el valor inicial es mayor que el número de elementos en la lista de la matriz.
Tanto en el método "RemoveAt" como en el "RemoveRange", sería aconsejable utilizar algún código para comprobar si los números de índice especificados son mayores que el número total de elementos en la lista de la matriz para detectar posibles errores. La propiedad "Recuento" dará el número total de elementos en la lista de matrices.
12345678910111213141516171819202122232425 | Sub RemoveExample ()"Definir objeto de lista de matrizAtenuar MyList como nueva ArrayList"Agregar elementos a la lista de arreglosMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3"MyList.Add "Item1"MyList.Add "Item4"MyList.Add "Item5""Insertar" Elemento6 "en la posición del índice 2MyList.Insert 2, "Item6""Quitar" Item2 "MyList.Eliminar "Item2""Eliminar" elemento ": esto no existe en la lista de la matriz, pero no es un error.MyList.Eliminar "Elemento"‘Quite el artículo en la posición de índice 2MyList.RemoveAt 2‘Quite 2 elementos consecutivos comenzando en la posición del índice 2MyList.RemoveRange 3, 2"Itere a través de la lista de matrices para mostrar lo que queda y en qué posición de índice se encuentra ahoraPara N = 0 a MyList.Count - 1MsgBox MyList (N) & "Index" & NSiguiente NEnd Sub |
Tenga en cuenta que si está utilizando "RemoveAt" para eliminar un elemento en una posición específica, tan pronto como se elimine ese elemento, se modificarán todas las posiciones de índice posteriores. Si tiene varias eliminaciones utilizando la posición de índice, entonces una buena idea es comenzar con el número de índice más alto y retroceder hasta la posición cero para que siempre esté eliminando el artículo correcto. De esta forma no tendrás el problema
Ordenar una lista de matrices
Otra gran ventaja sobre una colección es que puede ordenar los elementos en orden ascendente o descendente.
El objeto Array List es el único objeto en Excel VBA con un método de clasificación. El método de clasificación es muy rápido y esto puede ser una consideración importante para usar una lista de matrices.
En el objeto de colección, se requirió algo de pensamiento "fuera de la caja" para ordenar todos los elementos, pero con una lista de matriz, es muy simple.
El método "Ordenar" ordena en orden ascendente y el método "Inverso" ordena en orden descendente.
12345678910111213141516171819202122 | Sub ArrayListExample ()"Crear objeto de lista de matricesAtenuar MyList como nueva ArrayList"Agregar elementos en un orden no clasificadoMyList.Add "Item1"MyList.Add "Item3"MyList.Add "Item2""Clasifique los elementos en orden ascendenteMyList.Sort"Itere a través de los elementos para mostrar el orden ascendentePara cada yo en mi lista‘Mostrar nombre del elementoMsgBox ISiguiente yo"Ordena los elementos en orden descendenteMyList.Reverse"Itere a través de los elementos para mostrar el orden descendentePara cada yo en mi lista‘Mostrar nombre del elementoMsgBox ISiguiente yoEnd Sub |
Clonación de una lista de matrices
Una lista de matrices tiene la posibilidad de crear un clon o una copia de sí misma. Esto es útil si un usuario realiza cambios en los elementos utilizando una interfaz y su código VBA, pero necesita mantener una copia de los elementos en su estado original como copia de seguridad.
Esto podría proporcionar al usuario una función "Deshacer". Es posible que hayan realizado los cambios y deseen volver a la lista original.
123456789101112131415 | Sub CloneExample ()"Defina dos objetos: lista de matrices y un objetoAtenuar MyList como nuevo ArrayList, MyList1 como objeto"Rellenar el primer objeto con elementosMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Copiar Mylist en MyList1Establecer MyList1 = MyList.Clone"Itere a través de MyList1 para probar la clonaciónPara cada yo en MyList1‘Mostrar nombre del elementoMsgBox ISiguiente yoEnd Sub |
"MyList1" ahora contiene todos los elementos de "MyList" en el mismo orden
Copiar una matriz de lista en un objeto de matriz VBA convencional
Puede usar un método simple para copiar la lista de matrices en una matriz VBA normal:
123456789101112131415 | Sub ArrayExample ()"Crea un objeto de lista de matriz y un objeto de matriz estándarAtenuar MyList como nueva ArrayList, NewArray como variante"Completar la lista de matrices con elementosMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Copie la lista de matrices en la nueva matrizNewArray = MyList.ToArray"Itere a través de la nueva matriz: tenga en cuenta que el recuento de la lista de matrices proporciona el índice máximoPara N = 0 a MyList.Count - 1‘Mostrar nombre del elementoMsgBox NewArray (N)Siguiente NEnd Sub |
Copiar una matriz de lista en un rango de hoja de trabajo
Puede copiar su lista de matrices en una hoja de trabajo y una referencia de celda específicas sin la necesidad de recorrer la lista de matrices. Solo necesita especificar la primera referencia de celda
123456789101112131415 | SubrangoEjemplo ()"Crear un nuevo objeto de lista de matricesAtenuar MyList como nueva ArrayList"Agregar elementos a la listaMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Limpiar la hoja de destinoHojas ("Hoja1"). Rango usado.Borrar"Copiar elementos en una filaHojas ("Hoja1"). Rango ("A1"). Cambiar tamaño (1, MyList.Count) .Value = MyList.toArray"Copiar elementos en una columnaHojas ("Hoja1"). Rango ("A5"). Cambiar tamaño (MyList.Count, 1) .Value = _WorksheetFunction.Transpose (MyList.toArray)End Sub |
Vaciar todos los elementos de una lista de matriz
Hay una función simple (Borrar) para borrar la lista de matrices por completo
1234567891011121314 | Sub ClearListExample ()"Crear objeto de lista de matrizAtenuar MyList como nueva ArrayList"Agregar elementos nuevosMyList.Add "Item1"MyList.Add "Item2"MyList.Add "Item3""Mostrar recuento de artículosMsgBox MyList.Count"Borrar todos los elementosMyList.Clear"Muestre el recuento de elementos para demostrar que Clear ha funcionadoMsgBox MyList.CountEnd Sub |
Este ejemplo crea elementos en una lista de matrices y luego borra la lista de matrices. Los cuadros de mensaje prueban antes y después del número de elementos en la lista de arreglos.
Resumen de métodos de lista de matrices para Excel VBA
Tarea | Parámetros | Ejemplos de |
Agregar / editar elemento | Valor | MyList.Add "Item1" |
MyList (4) = "Item2" | ||
Clonar una lista de matrices | Ninguno | Atenuar MyList como objeto |
Establecer MyList2 = MyList.Clone | ||
Copiar en matriz | Ninguno | Atenuar MyArray como variante |
MyArray = MyList.ToArray | ||
Copiar a un rango de hoja de trabajo (fila) | Ninguno | Hojas ("Hoja1"). Rango ("A1"). Cambiar tamaño (1, MyList.Count) .Value = MyList.ToArray |
Copiar a un rango de hoja de trabajo (columna) | Ninguno | Hojas ("Hoja1"). Rango ("A3"). Cambiar tamaño (MyList.Count, 1) .Value = WorksheetFunction.Transpose (MyList.ToArray) |
Crear | "System.Collections.ArrayList" | Atenuar MyList como objeto |
Establecer MyList = CreateObject ("System.Collections.ArrayList") | ||
Declarar | N / A | Atenuar MyList como objeto |
Buscar / verificar si el artículo existe | Artículo para encontrar | MyList.Contains ("Item2") |
Encuentra la posición de un elemento en ArrayList | 1. Artículo para buscar. | Dim Index No tan largo |
2. Posición desde la que empezar a buscar. | IndexNo = MyList.IndexOf ("Item3", 0) | |
IndexNo = MyList.IndexOf ("Item5", 3) | ||
Obtener número de artículos | Ninguno | MsgBox MyList.Count |
Insertar artículo | 1. Índice: posición en la que insertar. | MyList.Insert 0, "Item5" |
2 Valor: objeto o valor para insertar. | MyList.Insert 4, "Item7" | |
Leer artículo | Índice - entero largo | MsgBox MyList.Item (0) |
MsgBox MyList.Item (4) | ||
Leer el último elemento agregado | Índice - entero largo | MsgBox MyList.Item (list.Count - 1) |
Leer el elemento agregado primero | Índice - entero largo | MsgBox MyList.Item (0) |
Leer todos los elementos (para cada uno) | N / A | Elemento de atenuación como variante |
Para cada elemento en MyList | ||
Elemento MsgBox | ||
Siguiente elemento | ||
Leer todos los elementos (para) | Índice - entero largo | Dim i tan largo |
Para i = 0 a MyList.Count - 1 | ||
MsgBox i | ||
Siguiente yo | ||
Eliminar todos los elementos | Ninguno | MyList.Clear |
Quitar artículo en la posición | Posición del índice donde está el artículo | MyList.RemoveAt 5 |
Eliminar elemento por nombre | El elemento para eliminar de ArrayList | MyList.Eliminar "Item3" |
Eliminar una variedad de elementos | 1. Índice - posición inicial. | MyList.RemoveRange 4,3 |
2. Recuento: la cantidad de elementos que se eliminarán. | ||
Ordenar en orden descendente | Ninguno | MyList.Reverse |
Ordenar en orden ascendente | No | MyList.Sort |