TOP

VBA-Lesson 13.3. Using Arrays (Exercises)

To practice using arrays, we'll create our own version of the macro we used to demonstrate the speed advantage of arrays, step by step...

The following is the starting point for this exercise (you'll see that the dataset has been reduced to 1000 rows):

Here you can download an Excel file with an example: arrays_exercise.xls

Purpose of the exercise: the procedure should process the data in the dataset using a loop and count the number of YES or NO responses for each year and for each customer number (either YES or NO, depending on the user's choice) and enter this amount in the indicated cell of the worksheet.

Complete the following macro to save the data from the "DS" worksheet to an array:

  1. Sub actualize()  
  2.       Dim last_row As Integer  
  3.        
  4.       'The last line of the data set  
  5.       '...  
  6.           
  7.       "Saving a set of data in a dynamic array  
  8.       Dim array_db()  
  9.       '...  
  10.           
  11. End Sub  

Here is one example of a solution:

  1. Sub actualize()  
  2.       Dim last_row As Integer  
  3.        
  4.       'The last line of the database  
  5.       last_row = Sheets("DS").Range("A1").End(xlDown).Row  
  6.   
  7.       "Saving a set of data in a dynamic array  
  8.       Dim array_db()  
  9.       ReDim array_db(last_row - 2, 2)  
  10.        
  11.       For row_number = 2 To last_row  
  12.           array_db(row_number - 2, 0) = Sheets("DS").Range("A" & row_number)  
  13.           array_db(row_number - 2, 1) = Sheets("DS").Range("B" & row_number)  
  14.           array_db(row_number - 2, 2) = Sheets("DS").Range("C" & row_number)  
  15.       Next  
  16. End Sub  

This basically repeats what we did in the previous lesson...

But now we need to modify our macro by adding the following actions:

Define user choice ("YES" or "NO");

Count the number of answers "YES" or "NO" in the data set, in order to determine the size of the array (Redim);

We save only those rows from the data set that contain the answers "YES" or "NO" in the array (this means that we do not need to save data from the third column).

Here is one example of a solution:

  1. Sub actualize()  
  2.       Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer  
  3.        
  4.       'The last line of the database  
  5.       last_row = Sheets("DS").Range("A1").End(xlDown).Row  
  6.   
  7.       'Search for value (YES or NO)  
  8.       If Sheets("RES").OptionButton_yes.Value = True Then  
  9.           search_value = "YES"  
  10.       Else  
  11.           search_value = "NO"  
  12.       End If  
  13.        
  14.       The number of YES or NO answers  
  15.       rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)  
  16.        
  17.       'Saving a set of data into an array  
  18.       Dim array_db()  
  19.       ReDim array_db(rows_number - 1, 1)  
  20.   
  21.       insert_row = 0  
  22.        
  23.       For row_number = 2 To last_row  
  24.           value_yes_no = Sheets("DS").Range("C" & row_number)  
  25.           If value_yes_no = search_value Then  
  26.               array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)  
  27.               array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)  
  28.               insert_row = insert_row + 1  
  29.           End If  
  30.       Next  
  31. End Sub  

The user's choice of search is determined at the beginning of the procedure by the following code:

  1. 'Search for value (YES or NO)  
  2. If Sheets("RES").OptionButton_yes.Value = True Then  
  3.       search_value = "YES"  
  4. Else  
  5.       search_value = "NO"  
  6. End If  

We will use the CountIF function to determine the number of "YES" or "NO" answers:

  1. The number of YES or NO answers  
  2. rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)  

The array has been resized to fit the number of YES or NO responses and reduced to two columns:

  1. ReDim array_db(rows_number - 1, 1)  

This data will now be stored in the array when its third column matches the user's selection:

  1. 'Inserting a number into an array  
  2. insert_row = 0  
  3.   
  4. 'Data set processing  
  5. For row_number = 2 To last_row  
  6.       'The value of column C (YES or NO)  
  7.       value_yes_no = Sheets("DS").Range("C" & row_number)  
  8.       'If the value matches the user's choice, the string is stored in the array  
  9.       If value_yes_no = search_value Then  
  10.           'Saving the value to column A  
  11.           array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)  
  12.           'Saving value to column B  
  13.           array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)  
  14.           'One row has been saved => the insertion number in the array is increased by 1  
  15.           insert_row = insert_row + 1  
  16.       End If  
  17. Next  

Our array contains only the data we are interested in.

All that remains to be done is:

Process each element of the table in the "RES" worksheet using 2 loops (same idea as on the right with the checkerboard);

Insert the total number of occurrences on this sheet for each year by each customer number for each cell.

Here is one example of a solution:

  1. 'Number of "YES"/"NO" responses  
  2. For no_years = 2011 To 2026  
  3.       For no_client = 1 To 30  
  4.           counter = 0  
  5.           For i = 0 To UBound(array_db)  
  6.               If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then  
  7.                   counter = counter + 1  
  8.               End If  
  9.           Next  
  10.           Cells(no_years - 2009, no_client + 1) = counter  
  11.       Next  
  12. Next  

Solved problem with comments explaining it in detail:

  1. 'Loop for each row  
  2. For no_years = 2011 To 2026  
  3.       'Loop for each column  
  4.       For no_client = 1 To 30  
  5.           'Counter reset  
  6.           counter = 0  
  7.           'Array processing  
  8.           For i = 0 To UBound(array_db)  
  9.               Checking that the row in the table corresponds to the year and the number of the client  
  10.               If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then  
  11.                   If the year and customer number match, the counter increases by 1  
  12.                   counter = counter + 1  
  13.               End If  
  14.           Next  
  15.           After processing the array, the result is entered in the corresponding cell  
  16.           Cells(no_years - 2009, no_client + 1) = counter  
  17.       Next  
  18. Next  

And finally, the code for our entire macro:

  1. Sub actualize()  
  2.       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  
  3.        
  4.       'Remove content  
  5.       Range("B2:AE17").ClearContents  
  6.        
  7.       'The last row in the data set  
  8.       last_row = Sheets("DS").Range("A1").End(xlDown).Row  
  9.   
  10.       'Search for value (YES or NO)  
  11.       If Sheets("RES").OptionButton_yes.Value = True Then  
  12.           search_value = "YES"  
  13.       Else  
  14.           search_value = "NO"  
  15.       End If  
  16.        
  17.       The number of YES or NO answers  
  18.       rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)  
  19.        
  20.       "Saving values in an array."  
  21.       Dim array_db()  
  22.       ReDim array_db(rows_number - 1, 1)  
  23.   
  24.       insert_row = 0  
  25.        
  26.       For row_number = 2 To last_row  
  27.           value_yes_no = Sheets("DS").Range("C" & row_number)  
  28.           If value_yes_no = search_value Then  
  29.               array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)  
  30.               array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)  
  31.               insert_row = insert_row + 1  
  32.           End If  
  33.       Next  
  34.        
  35.       Counting YES or NO answers  
  36.       For no_years = 2011 To 2026  
  37.           For no_client = 1 To 30  
  38.               counter = 0  
  39.               For i = 0 To UBound(array_db)  
  40.                   If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then  
  41.                       counter = counter + 1  
  42.                   End If  
  43.               Next  
  44.               Cells(no_years - 2009, no_client + 1) = counter  
  45.           Next  
  46.       Next  
  47. End Sub  

Here you can download an Excel file with an example: arrays_exercise_completed.xls

Articles on the topic:

  • VBA-Lesson 13.2. Arrays (Continued)
  • VBA-Lesson 14.1. Using Excel functions