Diccionarios (Dictionaries) en VBA

Al igual que las Colecciones, los diccionarios son un tipo de arreglo que nos permite almacenar todo tipo de variables como números, textos, objetos y combinación de ellas. En este tutorial verás por qué consideramos esta estructura muy útil.

Su forma de trabajo hace que el Dictionary sea muy similar al Collection; sin embargo tienen algunas diferencias en sus estructuras. Aquí te mostramos un resumen con las características de los Diccionarios, Colecciones y Arreglos:

 ArreglosColeccionesDiccionarios
Facilidad de programaciónX  
Ordenamiento de elementos internosXX 
Edición de elementos internosX X
Eliminación de elementos intermedios XX
Buen desempeño en grandes bases de datos XX
Manejo de información a través de claves (Keys) XX

En este tutorial te explicaremos las formas más generales de trabajar con los diccionarios para la cantidad de variables que tú decidas. Existen unos pasos que podríamos omitir cuando tu diccionario almacene sólo una variable, pero nuestra intención es enseñarte todo!.

1. Declaración de diccionarios

Microsoft nos provee dos modalidades para la declaración: Early Binding y Late Binding.

La modalidad Early Binding necesita que actives la referencia “Microsoft Scripting Runtime”, lo cual podría no ser del agrado para algunos usuarios finales de nuestras herramientas, debido a que muchos no estarán familiarizados con VBA.

El Late Binding resulta ventajoso en el sentido de que la declaración la harás directamente en el código, sin labores extras para el usuario final, por ello trabajaremos bajo esta modalidad. La única desventaja de esta opción es que perderás la ayuda de escritura que el código muestra en los procedimientos disponibles, sin embargo con la explicación que te daremos, esa ayuda no sería necesaria 🙂

En este tutorial iremos desarrollando un ejemplo de creación de un diccionario que almacene la información de la nómina de una empresa.

1.1. Creación de módulo de clases

Aunque este paso no es obligatorio, es altamente recomendado para poder tener un mejor tratamiento y manejo de la información en el diccionario. Te recomendamos crear un módulo de clases donde almacenaremos todas las variables que estarán en el diccionario. Para ello haz clic sobre el menú “Insertar” de VBE y selecciona la opción “Módulo de clase”.

Si decides no usar el módulo de clases, tendrás que tener ciertas consideraciones (que aprenderás más adelante) a la hora de acceder al diccionario.

Es buena práctica renombrar el módulo de clases para relacionarlo con el diccionario que crearemos. Para ello debes dirigirte al nombre de la clase y escribir el nombre que desees.  Dado que haremos un diccionario de nómina, le colocaremos “clsNom” (las tres primeras letras para diferenciar nemotécnicamente que es un módulo de clases).

Dentro del módulo de clases declararemos los ítems o variables (según su tipo) con las que trabajaremos en nuestro diccionario, bajo la siguiente estructura:

Option Explicit
Public NombreDeVariable As TipodeVariable

Ejemplo de creación de módulo de clase para un diccionario VBA:

Option Explicit
Public Name As String   'Worker’s name
Public Age As Long      'Worker’s age
Public Gen As String    'Worker’s genre

1.2. Declaración del diccionario

La declaración de nuestro diccionario se hace bajo la siguiente estructura:

Set NombreDeDiccionario = CreateObject(“Scripting.Dictionary”)

Ejemplo de declaración de un diccionario en VBA:

Set Nomina = CreateObject("Scripting.Dictionary")

2. Añadir elementos al Diccionario

En muchas ocasiones necesitaremos añadir elementos al diccionario a partir de la información de una hoja Excel. Al tomar los datos de la hoja de cálculo, debemos definir cuál columna representará nuestro identificador único o Key y cuáles serán las variables agregadas o Ítems que pertenecerán a dicho Key.

Debemos recordar que el Key es un identificador único, así que en este ejemplo el nombre de la persona no sería un buen identificador, ya que en algún momento podría repetirse (en nuestra tabla existen dos personas distintas llamadas Ana). Te sugerimos usar el número de identificación (Columna A en este caso) como Key.

Debemos entonces hacer un recorrido por todas las filas llenas, para lo cual recurrimos a un Loop.

Para evitar errores en nuestra rutina, es conveniente revisar si el Key ha sido previamente utilizado en el diccionario, es decir, debemos verificar si la persona fue previamente registrada. Esto lo podremos hacer siguiendo la estructura:

Dim DeclaraciónVariables As Nombre de módulo de clase
Abrir Loop que barre la columna
Asigna Key  
If (Revisa si el Key ya esté utilizado) Then
  Acción si el Key fue utilizado
Else  (Acción si el Key está libre)  
  Set ObjetoDeClase = New NombreDeModuloDeClase           NombreDeDiccionario.Add Key, ObjetoDeClase(Ítems) o arreglo de items  
End If
ObjetoDeClase.NombreDeItem = CeldaQueContieneEseItem.Value (subItem) 
Cerrar el Loop

2.1. Ejemplo para añadir elementos al Diccionario sin módulo de clases

En lugar de un módulo de clases, esta modalidad hace uso de un Array auxiliar para almacenar la información de los ítems. Bajo este concepto, cuando queramos acceder a los elementos del Dictionary debemos hacerlo a través de la posición que cada ítem ocupa en el mismo. En este ejemplo, la primera posición la ocupa el ítem “Person”, la segunda el ítem “Age” y la tercera el elemento “Gen”.

'Declaración de diccionario
Dim key As Variant, listItem() As Variant
Set WorkerList = CreateObject("Scripting.Dictionary")
'-----------------------------------------------------------------------------
'--- Añadir elementos al Diccionario -
i = 2
Do While IsEmpty(ws.Cells(i, 1)) = False '--->Loop through "A" Column
 IDPerson = ws.Cells(i, 1).Value        '--->Key
 '---> Revisa si el key fue añadido al diccionario
 If WorkerList.Exists(IDPerson) = True Then
  MsgBox ("Key " & IDPerson & "is already used")
 Else
 '---> Asigna Items
    ReDim listItem(i - 1, 3)
    listItem(i - 1, 1) = ws.Cells(i, 2).Value '-->Person
    listItem(i - 1, 2) = ws.Cells(i, 3).Value '---> Age
    listItem(i - 1, 3) = ws.Cells(i, 4).Value '---> Gen
    WorkerList.Add IDPerson, listItem
 End If
 i = i + 1
Loop

2.2. Ejemplo para añadir elementos al diccionario con módulo de clases

Para implementar esta opción, deberás haber creado previamente el módulo de clases. La ventaja de este método es que posteriormente podrás acceder a cada elemento del diccionario solo con conocer su nombre, sin necesidad de conocer su posición.

La información que continua en el tutorial es basada en la estructura del módulo de clases, sin embargo, si tienes dudas con la otra modalidad, no dejes de contactarnos.

Dim key As Variant
Dim oNom As clsNom
'-----------------------------------------------------------------------------
'Declaración de diccionario
Set WorkerList = CreateObject("Scripting.Dictionary")
'-----------------------------------------------------------------------------
'--- Añadir elementos al Diccionario -
i = 2
Do While IsEmpty(ws.Cells(i, 1)) = False '--->Loop through "A" Column
 IDPerson = ws.Cells(i, 1).Value        '--->Key
'---> Revisa si el key fue añadido al diccionario
 If WorkerList.Exists(IDPerson) = True Then
  MsgBox ("Key " & IDPerson & "is already used")
 Else '---> Crea el objeto de clase (ClsNom)
  Set oNom = New clsNom
  WorkerList.Add IDPerson, oNom
 End If
 '---> Asigna Items
 oNom.Name = ws.Cells(i, 2).Value
 oNom.Age = ws.Cells(i, 3).Value
 oNom.Gen = ws.Cells(i, 4).Value
 i = i + 1
Loop

3. Acceder a elementos del diccionario

Al igual que las Colecciones, los diccionarios tienen un excelente desempeño para manejar grandes cantidades de datos que se relacionan con el identificador único (Key). Así, cuando necesitamos acceder a alguna información para luego actualizarla, eliminarla o sencillamente visualizarla, las instrucciones de VBA hacen una búsqueda en el diccionario por Key  o palabra clave.

Para acceder a los elementos del diccionario debemos seguir la siguiente estructura:

Abrir Loop que busca por cada key del diccionario  
With
NombreDeDiccionario(key)   
Acciones  
End With
Cerrar el Loop

Ejemplo para acceder a elementos de un diccionario VBA:

'--- Acceder al diccionario ---
For Each key In WorkerList.Keys '---> Busca en cada elemento del diccionario
With Nomina(key)            '---> Con el Key de objeto de clase: Acciones
  Debug.Print key, .Name, .Age, .Gen'---> Acción: Imprimir Key e ítems
 End With
Next key

4. Modificar el Diccionario

Sabiendo ya como acceder a los elementos del diccionario, para la modificación sólo restaría encontrar la entrada que deseamos modificar y hacer las respectivas acciones. Veamos ejemplos con las dos modificaciones más comunes: Actualización y Eliminación de entradas.

4.1. Actualizar entradas del diccionario

Identificar el key que deseamos modificar
Abrir Loop que busca por cada key del diccionario
Revisar si el key de loop es el que deseamos modificar  
With NombreDeDiccionario(key)   
Acciones sobre el ítem que seleccionamos en el loop  
End With
Cerrar el Loop

Ejemplo para actualizar datos en un diccionario VBA:

Dim ws As Worksheet
Dim i As Long
Dim oNom As clsNom
Dim key As Variant
 
Set ws = DictionaryWS
'-----------------------------------------------------------------------------
'Declaración de diccionario
Set WorkerList = CreateObject("Scripting.Dictionary")
'-----------------------------------------------------------------------------
'--- Añadir elementos al Diccionario -
i = 2
Do While IsEmpty(ws.Cells(i, 1)) = False '--->Recorrido por toda la columna A
 IDPerson = ws.Cells(i, 1).Value        '--->Key
'---> Revisa si el key fue añadido al diccionario
 If WorkerList.Exists(IDPerson) = True Then
  MsgBox ("Key " & IDPerson & "is already used")
 Else                                    '---> Crea Objeto de clase (ClsNom)
  Set oNom = New clsNom
  WorkerList.Add IDPerson, oNom
 End If
' ---> Asigna valores a los Items
 oNom.Name = ws.Cells(i, 2).Value
 oNom.Age = ws.Cells(i, 3).Value
 oNom.Gen = ws.Cells(i, 4).Value
 i = i + 1
Loop
'-----------------------------------------------------------------------------
'--- Actualización de diccionario ---
Query = "ID 09"              '---> Key a modificar
For Each key In WorkerList.Keys
    If key = Query Then     '---> Modifica si ek key es Query
      '---> Modificación de la entrada <---
      With WorkerList(key)
       .Age = .Age + 1 '---> Actualiza la Edad
      End With
    End If
Next key

Si deseamos limpiar o borrar la información de un ítem, debemos asignarle la el valor “Clear” a la entrada. Aquí te mostramos el ejemplo con el elemento “Age” (edad):

.Age = Clear    '---> Actualiza la Edad

4.2. Borrar Entradas del diccionario

Cuando necesitemos eliminar la información de una entrada del diccionario (por ejemplo, cuando la persona deje de prestar servicio en la empresa),  sería una acción similar a borrar una fila de la hoja de Excel:

La estructura es:

Identificar el key que deseamos eliminar 
NombreDeDiccionario.Remove key 

Ejemplo para eliminar entradas de un diccionario VBA:

'--- Borrar key & Items seleccionado ---
Query = "ID 09"              '---> Key a eliminar
For Each key In WorkerList.Keys
    If key = Query Then     '---> Elimina si el key es Query
       WorkerList.Remove key
    End If
Next key

Ahora bien, si lo que deseas es limpiar toda la información del diccionario, puedes utilizar la siguiente instrucción:

NombreDeDiccionario.RemoveAll

Ejemplo para limpiar información de un diccionario VBA:

'--- Borrar todo el diccionario --- 
WorkerList.RemoveAll

Quieres saber mas? Contáctanos…

Diccionarios (Dictionaries) en VBA

También te puede interesar

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *