🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Dictionary en Excel — búsquedas, eliminar duplicados y agrupar (6 ejemplos)

|

VBA Dictionary en Excel — búsquedas, eliminar duplicados y agrupar (6 ejemplos)

Probado en: Excel 365 v2509 · Excel 2021 · Excel 2019 · última verificación 05/06/2026

En resumen — Un Dictionary guarda pares clave → valor y encuentra cualquier valor por su clave al instante — sin bucles. Se crea, se llena y se consulta:

Sub FundamentosDict()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    dict("AAPL") = 182.5          ' añadir o actualizar por clave
    dict("MSFT") = 410.2

    If dict.Exists("AAPL") Then    ' comprobar antes de leer
        MsgBox "AAPL = " & dict("AAPL")
    End If
End Sub

Donde una matriz te obliga a recorrer cada elemento para encontrar uno, un Dictionary va directo. Por eso los analistas lo usan sobre todo para dos cosas: eliminar duplicados y contar/agrupar. Ambas están abajo.

Por qué un Dictionary — y qué es una clave

Una clave es una etiqueta única; un valor es lo que guardas bajo ella. Las claves deben ser únicas, así que el Dictionary es perfecto siempre que la pregunta sea «¿lo he visto ya?» o «¿cuántos de cada uno?». La búsqueda por clave es O(1) — prácticamente instantánea — sin importar cuántas entradas tenga.

Ejemplo 1 — Preparación: enlace tardío frente a anticipado

Hay dos formas de crear un Dictionary, y confundirlas provoca el temido error «Tipo definido por el usuario no definido».

' ── Enlace tardío (sin preparación, funciona en todas partes) ──
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' ── Enlace anticipado (más rápido + IntelliSense) ──
' Primero: Herramientas ▸ Referencias ▸ marcar "Microsoft Scripting Runtime"
Dim dict As New Scripting.Dictionary

¿Cuál usar? El enlace tardío para código que compartes (nada que configurar en el otro equipo). El enlace anticipado al desarrollar, por el autocompletado. Esta guía usa enlace tardío para que cada ejemplo funcione tal cual.

Ejemplo 2 — Añadir, actualizar y el truco del «añadido silencioso»

Hay dos formas de meter datos, y la diferencia importa:

dict.Add "AAPL", 182.5      ' explícito — ERROR si "AAPL" ya existe
dict("MSFT") = 410.2        ' asignación — añade si es nuevo, actualiza si existe

Esa segunda forma es el añadido silencioso: asignar a una clave que no existe la crea. Nunca falla con duplicados, que es justo lo que hace tan limpios los dos patrones siguientes.

Ejemplo 3 — .Exists antes de leer (evitar claves fantasma)

Leer una clave inexistente con dict(key) la crea silenciosamente (vacía). Para comprobar pertenencia sin añadir nada, usa siempre .Exists:

Dim sku As String
sku = Range("A2").Value

If dict.Exists(sku) Then
    Range("B2").Value = dict(sku)        ' seguro — la clave está de verdad
Else
    Range("B2").Value = "no encontrado"
End If

Ejemplo 4 — Construir una lista única (deduplicar en una pasada) ⭐

La tarea clásica: la columna A tiene miles de filas con repeticiones; quieres cada valor una vez. El añadido silencioso colapsa los duplicados automáticamente:

Sub ValoresUnicos()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim celda As Range
    For Each celda In Range("A2:A10000")
        If celda.Value <> "" Then dict(celda.Value) = 1   ' los duplicados se sobrescriben, la lista queda única
    Next celda

    ' dict.Keys es ahora la lista sin duplicados — escribirla en la columna D:
    Range("D2").Resize(dict.Count).Value = Application.Transpose(dict.Keys)
    MsgBox dict.Count & " valores únicos"
End Sub

Sin bucles anidados, sin ordenar, sin columna auxiliar — y sigue siendo rápido con 100.000 filas.

Ejemplo 5 — Contar / agrupar (un recuento de frecuencias) ⭐

¿Quieres «cuántos pedidos por región»? Suma uno al valor cada vez que veas la clave. El añadido silencioso inicia una clave inexistente en 0, así que el primer + 1 ya funciona:

Sub ContarPorRegion()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim celda As Range
    For Each celda In Range("A2:A10000")             ' columna A = Región
        dict(celda.Value) = dict(celda.Value) + 1    ' primera vez: 0 + 1
    Next celda

    ' Volcar el recuento en las columnas F:G
    Dim k As Variant, f As Long
    f = 2
    For Each k In dict.Keys
        Cells(f, 6).Value = k                        ' F = región
        Cells(f, 7).Value = dict(k)                  ' G = recuento
        f = f + 1
    Next k
End Sub

Es el equivalente a una tabla dinámica en 12 líneas — y controlas exactamente qué ocurre.

Ejemplo 6 — Recorrer claves y valores a la vez

.Keys e .Items devuelven cada una una matriz base 0, alineadas por posición:

Dim keys As Variant, items As Variant, i As Long
keys = dict.Keys
items = dict.Items
For i = 0 To dict.Count - 1
    Debug.Print keys(i) & " => " & items(i)
Next i

¿Necesitas claves sin distinguir mayúsculas (para que «AAPL» y «aapl» sean iguales)? Ajusta dict.CompareMode = vbTextCompare antes de añadir nada.

Dictionary frente a Collection — cuál usar

VBA también tiene una Collection integrada. Recurre a un Dictionary cuando necesites acceso por clave; una Collection basta para una simple lista ordenada.

Necesidad Dictionary Collection
Comprobar si una clave existe .Exists(key) ninguna — atrapar un error
Actualizar un valor en su sitio dict(key) = x quitar + volver a añadir
Obtener todas las claves / valores .Keys / .Items no disponible
Contar elementos .Count .Count
Preparación necesaria referencia Scripting.Dictionary o CreateObject integrada, ninguna

Errores frecuentes con Dictionary (y la solución)

Síntoma Causa Solución
«Tipo definido por el usuario no definido» As New Scripting.Dictionary sin la referencia Añadir la referencia, o enlace tardío CreateObject(...)
«Esta clave ya está asociada…» .Add sobre una clave que existe Usar dict(key) = value para añadir-o-actualizar
La comprobación de pertenencia hace crecer el dict If dict(key) <> "" Then crea la clave Comprobar con dict.Exists(key) en su lugar
Transpose de las claves falla / trunca Por encima de ~65.536 claves se topa con el límite de Transpose Recorrer las claves y escribirlas una a una
«aapl» y «AAPL» contados por separado La comparación de claves distingue mayúsculas por defecto Ajustar dict.CompareMode = vbTextCompare antes de añadir

Sáltate el enlace y el andamiaje — pide solo el resultado

Los Dictionaries son la herramienta correcta para deduplicar y agrupar — pero enlace anticipado/tardío, guardas .Exists y límites de Transpose son mucha ceremonia para «dame las regiones únicas y su recuento». ExcelMaster Agent te deja decir justo eso en español sencillo — «lista cada región única de la columna A y cuántas filas tiene» — y construye el diccionario, la guarda y la salida por ti. Pruébalo gratis →

Guías relacionadas

Preguntas frecuentes

¿Qué es un Dictionary en VBA? Un Dictionary (Scripting.Dictionary) guarda pares clave → valor y recupera cualquier valor por su clave al instante, sin bucles. Las claves son únicas, lo que lo hace ideal para deduplicar y para contar o agrupar.

¿Cómo creo un Dictionary en Excel VBA? El enlace tardío no necesita preparación: Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary"). Para enlace anticipado e IntelliSense, marca Microsoft Scripting Runtime en Herramientas ▸ Referencias y luego Dim dict As New Scripting.Dictionary.

¿Cuál es la diferencia entre un Dictionary y una Collection en VBA? Un Dictionary tiene .Exists, permite actualizar valores en su sitio y expone .Keys/.Items. Una Collection es una lista ordenada integrada más simple, sin comprobación de existencia de clave ni forma de leer sus claves. Usa un Dictionary siempre que necesites búsquedas por clave.

¿Cómo compruebo si una clave existe en un Dictionary VBA? Usa dict.Exists(key), que devuelve True/False sin cambiar el diccionario. Evita If dict(key)…, porque leer una clave inexistente la crea silenciosamente.

¿Cómo obtengo una lista única con un Dictionary VBA? Recorre el rango de origen y asigna dict(celda.Value) = 1. Las claves duplicadas se sobrescriben, así que dict.Keys queda como la lista sin duplicados — luego reescríbela con Range("D2").Resize(dict.Count).Value = Application.Transpose(dict.Keys).