Para practicar el uso de arreglos, crearemos nuestra propia versión de la macro que usamos para demostrar la ventaja de velocidad de los arreglos, paso a paso...
Aquí está el punto de partida para este ejercicio (verá que el conjunto de datos se ha reducido a 1000 filas):
Aquí puede descargar el archivo de ejemplo Excel: matrices_ejercicio.xls
Objetivo del ejercicio: El procedimiento debe procesar los datos en el conjunto de datos utilizando un bucle y contar el número de respuestas SÍ o NO para cada año y para cada número de cliente (ya sea SÍ o NO, según la elección del usuario) e ingresar esta cantidad en la celda especificada de la hoja de cálculo.
Complete la siguiente macro para guardar datos de la hoja de cálculo "DS" en una matriz:
Sub actualize() Dim last_row As Integer 'La última fila del conjunto de datos. '... 'Guardar un conjunto de datos en una matriz dinámica Dim array_db() '... End Sub
Aquí hay una solución de ejemplo:
Sub actualize() Dim last_row As Integer 'La última línea de la base de datos. last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Guardar un conjunto de datos en una matriz dinámica Dim array_db() ReDim array_db(last_row - 2, 2) For row_number = 2 To last_row array_db(row_number - 2, 0) = Sheets("DS").Range("A" & row_number) array_db(row_number - 2, 1) = Sheets("DS").Range("B" & row_number) array_db(row_number - 2, 2) = Sheets("DS").Range("C" & row_number) Next End Sub
Esto básicamente repite lo que hicimos en la lección anterior...
Pero ahora necesitamos modificar nuestra macro agregando las siguientes acciones:
Aquí hay una solución de ejemplo:
Sub actualize() Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer 'La última línea de la base de datos. last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Buscar valor (SI o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If 'El número de respuestas SÍ o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value) 'Guardar un conjunto de datos en una matriz Dim array_db() ReDim array_db(rows_number - 1, 1) insert_row = 0 For row_number = 2 To last_row value_yes_no = Sheets("DS").Range("C" & row_number) If value_yes_no = search_value Then array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) insert_row = insert_row + 1 End If Next End Sub
La búsqueda por elección del usuario se determina al comienzo del procedimiento mediante el siguiente código:
'Buscar valor (SI o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If
Usaremos la función CountIF para determinar el número de respuestas "SÍ" o "NO":
'El número de respuestas SÍ o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)
La matriz se ha redimensionado para ajustarse al número de respuestas SÍ o NO y se ha reducido a dos columnas:
ReDim array_db(rows_number - 1, 1)
Estos datos ahora se almacenarán en la matriz cuando su tercera columna coincida con la selección del usuario:
'Insertar un número en una matriz insert_row = 0 'Procesamiento de conjuntos de datos For row_number = 2 To last_row 'Valor de la columna C (SI o NO) value_yes_no = Sheets("DS").Range("C" & row_number) 'Si el valor coincide con la selección del usuario, la cadena se almacena en la matriz If value_yes_no = search_value Then 'Guardar el valor en la columna A array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) 'Guardando el valor en la columna B array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) 'Se ha guardado una fila => el número de inserción en la matriz se incrementa en 1 insert_row = insert_row + 1 End If Next
Nuestra matriz contiene solo los datos que nos interesan.
Todo lo que queda por hacer es:
Aquí hay una solución de ejemplo:
'Número de respuestas "SÍ"/"NO" For no_years = 2011 To 2026 For no_client = 1 To 30 counter = 0 For i = 0 To UBound(array_db) If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then counter = counter + 1 End If Next Cells(no_years - 2009, no_client + 1) = counter Next Next
Problema resuelto con comentarios explicándolo en detalle:
'Bucle para cada fila For no_years = 2011 To 2026 'Bucle para cada columna For no_client = 1 To 30 'Puesta a cero del contador counter = 0 'Procesamiento de matriz For i = 0 To UBound(array_db) 'Comprobando que la fila de la tabla corresponde al año y número de cliente If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then 'Si el año y el número de cliente coinciden, el contador aumenta en 1 counter = counter + 1 End If Next 'Después de procesar la matriz, el resultado se ingresa en la celda correspondiente Cells(no_years - 2009, no_client + 1) = counter Next Next
Y finalmente, el código para toda nuestra macro:
Sub actualize() Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer, counter As Integer 'Eliminación de contenido Range("B2:AE17").ClearContents 'La última fila en el conjunto de datos. last_row = Sheets("DS").Range("A1").End(xlDown).Row 'Buscar valor (SI o NO) If Sheets("RES").OptionButton_yes.Value = True Then search_value = "YES" Else search_value = "NO" End If 'El número de respuestas SÍ o NO rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value) 'Guardar valores en una matriz Dim array_db() ReDim array_db(rows_number - 1, 1) insert_row = 0 For row_number = 2 To last_row value_yes_no = Sheets("DS").Range("C" & row_number) If value_yes_no = search_value Then array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number) array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number) insert_row = insert_row + 1 End If Next 'Contando respuestas SÍ o NO For no_years = 2011 To 2026 For no_client = 1 To 30 counter = 0 For i = 0 To UBound(array_db) If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then counter = counter + 1 End If Next Cells(no_years - 2009, no_client + 1) = counter Next Next End Sub
Aquí puede descargar el archivo de ejemplo Excel: matrices_ejercicio_completado.xls