Entendiendo el uso de diccionarios vba

Para mi amigo Dante Amor

Me gustaría que ayudaras a comprender la lógica, o el paso a paso de las sintaxis de esta macro, el cual me ayudo un experto de nick jindom de otro foro, y el cual me ha despertado gran intereses por aprender su uso ya que tiene gran potencia y rapidez.

De igual manera se lo envío al correo para mejor comprensión.

1 Respuesta

Respuesta
2

Puedes poner el código, pero utiliza el icono para insertar código

Aquí puedes encontrar información del Dictionary

https://excelmacromastery.com/vba-dictionary/

Al momento de iniciar la pregunta no pude colocar el código porque no me dejaba publicar la pregunta. 

Sale error al publicarla, por eso te anexe el archivo al correo 

Tampoco me deja escribir el código

¿Hiciste privada la pregunta o modificaste algo de la pregunta?

Sub Consolidartes()
    Dim a, i As Long, ii As Long, txt As String
    '
    Sheets("RegSS1").Range("A10:R" & Rows. Count). ClearContents
    '
    'Carga en el arreglo ( a ) la información desde la celda A9 hasta la celda G y última fila con datos
    'No recomiendo utilizar .CurrentRegion, porque si hay información en las celdas A8, A7, también serían cargadas
 'o si existen filas en blanco, no contemplaría más información.
    'revisa información sobre currentegion y usedrange.
    With Sheets("Unir").Range("A10").CurrentRegion.Resize(, 6)
      a = Application.Index(.Value, Evaluate("row(1:" & .Rows.Count & ")"), Array(1, 1, 2, 3, 4, 5, 6))
    End With

s

para nada, hice la pregunta como siempre la he realizado. No se si hay algún problema con el servidor 

Parte 2

 '
    'pone en la posición (1, 1) del arreglo ( a )
    a(1, 1) = "REG"
    '
    With CreateObject("Scripting.Dictionary")
      'comienza en el fila 2 del arrreglo, es decir, empieza en la fila 10 de la hoja,
 'recuerda que en el arreglo se cargó la fila 9 de los títulos en la fila 1 del arreglo
        For i = 2 To UBound(a, 1)  'significa que toma la cantidad de filas del arreglo
        'ubound(a, 2) 'es la cantidad de columna del arreglo
        'el arreglo es una matriz de filas y columnas, (a, 1) es para filas y (a, 2) es para columnas
        '

Parte 3

For i = 2 To UBound(a, 1) 'significa que toma la cantidad de filas del arreglo

Parte 4

'ubound(a, 2) 'es la cantidad de columna del arreglo
'el arreglo es una matriz de filas y columnas, (a, 1) es para filas y (a, 2) es para columnas
'
'concatena las columnas 2, 3, 4, 5 y 6 y las separa por el caracter (2)

Parte 5

'
'
If Not .exists(txt) Then
'crea en dictionary un índice
'agrega como llave lo que concatenó en la variable txt
'en el índice no existen llaves duplicadas,
'automáticamente el dictinary elimina las llaves duplicadas
'
'en esta sección escribe, o más bien dicho sobre escribe los datos en la misma matriz ( a )
.Item(txt) = .Count + 2
'le suma 2 porque .count = 0, en 1 tienes el encabezado, entonces el primer registro es el 2
'
'aquí pasa las columnas de ( a ) a la misma variable ( a )
For ii = 1 To UBound(a, 2)
a(.Count + 1, ii) = a(i, ii)
Next
a(.Count + 1, 1) = .Count
Else
a(.Item(txt), UBound(a, 2)) = a(. Item(txt), UBound(a, 2)) + a(i, UBound(a, 2)) 'acumula el valor de la columna F
End If
Next
i = .Count + 1
End With
With Sheets("RegSS1").Range("A9").CurrentRegion.Resize(, 7)
.ClearContents
With .Resize(i)
.NumberFormat = "": .Value2 = a 'así de simple, redimensionas el lugar de la salida y ahí pones la matriz a
End With
End With

'
'' Set h2 = Sheets("RegSS1")
'' For fila = 150 To 1 Step -1
'' If Cells(fila, 7).Value = "0" Then
'' Rows(fila).Delete
'' End If
'' Next fila
End Sub

Parte completa

Sub Consolidartes()
    Dim a, i As Long, ii As Long, txt As String
    '
    Sheets("RegSS1").Range("A10:R" & Rows. Count). ClearContents
    '
    'Carga en el arreglo ( a ) la información desde la celda A9 hasta la celda G y última fila con datos
    'No recomiendo utilizar .CurrentRegion, porque si hay información en las celdas A8, A7, también serían cargadas
 'o si existen filas en blanco, no contemplaría más información.
    'revisa información sobre currentegion y usedrange.
    With Sheets("Unir").Range("A10").CurrentRegion.Resize(, 6)
      a = Application.Index(.Value, Evaluate("row(1:" & .Rows.Count & ")"), Array(1, 1, 2, 3, 4, 5, 6))
    End With
    '
    'pone en la posición (1 , 1) del arreglo ( a )
    a(1, 1) = "REG"
    '
    With CreateObject("Scripting.Dictionary")
      'comienza en el fila 2 del arrreglo, es decir, empieza en la fila 10 de la hoja,
 'recuerda que en el arreglo se cargó la fila 9 de los títulos en la fila 1 del arreglo
For i = 2 To UBound(a, 1)  'significa que toma la cantidad de filas del arreglo
'ubound(a, 2) 'es la cantidad de columna del arreglo
'el arreglo es una matriz de filas y columnas, (a, 1) es para filas y (a, 2) es para columnas
'
'concatena las columnas 2, 3, 4, 5 y 6 y las separa por el caracter (2)
          '
          '
            If Not .exists(txt) Then
              'crea en dictionary un índice
              'agrega como llave lo que concatenó en la variable txt
              'en el índice no existen llaves duplicadas,
              'automáticamente el dictinary elimina las llaves duplicadas
              '
              'en esta sección escribe, o más bien dicho sobre escribe los datos en la misma matriz ( a )
                .Item(txt) = .Count + 2
                'le suma 2 porque .count = 0, en 1 tienes el encabezado, entonces el primer registro es el 2
                '
                'aquí pasa las columnas de ( a ) a la misma variable ( a )
                For ii = 1 To UBound(a, 2)
                    a(.Count + 1, ii) = a(i, ii)
                Next
                a(.Count + 1, 1) = .Count
            Else
                a(.Item(txt), UBound(a, 2)) = a(. Item(txt), UBound(a, 2)) + a(i, UBound(a, 2)) 'acumula el valor de la columna F
            End If
        Next
        i = .Count + 1
    End With
    With Sheets("RegSS1").Range("A9").CurrentRegion.Resize(, 7)
        .ClearContents
        With .Resize(i)
            .NumberFormat = "": .Value2 = a   'así de simple, redimensionas el lugar de la salida y ahí pones la matriz a
        End With
    End With
'
''   Set h2 = Sheets("RegSS1")
''      For fila = 150 To 1 Step -1
''         If Cells(fila, 7).Value = "0" Then
''            Rows(fila).Delete
''         End If
''      Next fila
End Sub

El editor de la página no permite poner la línea que tiene la instrucción: "J o i n", supongo que es una palabra reservada.

en la última parte el vuelca toda la información que tiene almacenada en la variable a, wow si que que es poderosa y simple como dices.

Otra inquietud,

a(.Item(txt), UBound(a, 2)) = a(. Item(txt), UBound(a, 2)) + a(i, UBound(a, 2)) 'acumula el valor de la columna F

como entender o saber que se le esta ordenando que el valor que tiene que acumular es el de la columna F o si quiero que acumule otra columna que tenga datos ?

Se que este tema es más avanzado, y para ello he estado consultado y estudiando todo lo que aparezca sobre diccionarios, incluso ya tenía conocimiento del link que me sugeriste.  Pero realmente no hay mucho sobre el tema, lo que encuentro es muy básico en sus ejemplos, pero al querer ahondar mas me freno, ya que lo quiero aplicar para casos prácticos de la vida real, donde se manipulan datos y se analiza información.

Como comenté

UBound(a, 2)

En (a, 2) tienes la cantidad de columnas, luego entonces

a(. Item(txt), UBound(a, 2)) + a(i, UBound(a, 2))

En la fila del arreglo ( a ) acumula lo que tiene en la última columna del arreglo, es algo como:

x = x  + 2

Si quiero acumular 3

x = 2 + 3

x = 5

___________________________

Toma en cuenta que en el arreglo ( a ) tienes filas y columnas.

En la macro está utilizando un arreglo para los índices, eso lo controla con el Dictionary.

Pero también tiene otro arreglo que es donde está poniendo los valores.

Entonces tiene 2 arreglos.

En el arreglo ( a ), en las coordenadas fila, columna pone los valores.

Después de llenar el arreglo ( a ) simplemente lo deposita en las celdas.

Si, es que las dudas son porque usa la misma variable o letra ( a ) para trabajar todos los datos, pero con tus explicaciones ya considero que he avanzado un poco más.

acá hay otros links que he consultado, sobre todo para los que también les interese el tema:

http://www.snb-vba.eu/VBA_Dictionary_en.html 

https://www.experts-exchange.com/articles/3391/Using-the-Dictionary-Class-in-VBA.html

Realiza este pequeño ejercicio para que veas el contenido de un arreglo:

ejecuta este código en Debug

Sub test1()
  Dim a As Variant
  a = Range("A2:C6").Value2
End Sub

Cuando llegues a "End Sub" abre la "Ventana de Locales"

Verás del lado derecho superior, que el arreglo tiene 5 filas y 3 columnas.

Si abres cada vector, verás 3 columnas en cada uno de ellos.


Ahora ejecuta esta macro

Sub test1()
  Dim a As Variant
  a = Range("A2:C6").Value2
  '
  Range("E2").Resize(5, 3).Value = a
End Sub

Ya sabemos que tenemos 5 filas y 3 columnas en el arreglo ( a ) , entonces vamos a depositar el arreglo empezando en la celda E2, pero estoy creciendo la salida a 5 filas y  3 columnas para recibir el arreglo.


Nota importante, el arreglo ( a ) está en memoria, todos los cambios que se hacen en el arreglo son en memoria, por eso el proceso es más rápido que si lo haces en la hoja.

Ahora prueba el siguiente código

Sub test1()
  Dim a As Variant
  a = Range("A2:C6").Value2
  '
  a(4, 2) = "Hola"
  Range("E2").Resize(5, 3).Value = a
End Sub

Lo que estoy haciendo es, poner "Hola" en la fila 4 columna 2 del arreglo.

Juega un rato con eso para que practiques.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas