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