Data Analytics

Managing Pivot Table and Excel Charts with VBA | by Himalaya Bir Shrestha | Jun, 2024


Data

I took the sample data from the website of Excel-Easy. This is a nice website containing beginner-friendly tutorials on basic Excel and VBA functionalities. The dataset contains records of fruit and vegetable sales in specific countries in 2016 and 2017. The dataset contains six fields: Order ID, Product, Category, Amount, Date, and Country. I divided this dataset into 2 csv files called results1.csv and results2.csv for creating pivot tables.

Structure of dataset. Illustration by Author.

I pulled this dataset in the RawData worksheet. I created a dynamic range called raw_data_source with the following formula:

=OFFSET(RawData!$A$1, 0, 0, COUNTA(RawData!$A:$A), COUNTA(RawData!$1:$1))

The reason for creating a dynamic range was that the size (number of rows) of the dataset was different in different CSV files, and I wanted to use the entire dataset as source of the pivot table.

Creating a dynamic named range as source for the pivot table. Illustration by Author.

Pivot tables and charts

The dataset in the raw_data_source range in the RawData sheet was used as a data source to create two simple pivot tables and charts.

Specifying the source of the pivot table. Illustration by Author.

The first one portrayed total fruits and vegetable sales by individual products filterable by country with the field settings as shown.

First pivot chart and its settings. Illustration by Author.

The second one portrayed total fruit and vegetable sales by countries.

Second pivot chart and its settings. Illustration by Author.

1. Automating refreshing pivot tables based on a new dataset

In this step, I wanted to automate the refreshing of the datasets from the file I specified. I created a placeholder in the Admin sheet to place the path of the CSV data whose dataset I wanted to pull and refresh the pivot tables with. I named the cell A2 as filepath as shown below:

Placeholder for file pathname with dataset. Illustration by Author.

The code for this step is given below in the UpdateRawData subroutine. I declared the variables wb, ws_admin, ws_rawdata, and filepath for the names of the workbook, Admin sheet, RawData sheet, and path of the file containing the dataset respectively. First I cleared the contents of the RawData sheet. Then I went to the source workbook based on the filename, selected the corresponding sheet, copied its contents, returned to the ws_rawdata sheet, and pasted the contents as values. Finally, I refreshed the workbook using the code wb.RefreshAll that refreshed the entire workbook including the sheets with the pivot table and chart respectively.

Sub UpdateRawData()

Dim wb As Workbook
Dim ws_admin As Worksheet
Dim ws_rawdata As Worksheet
Dim filepath As String

Set wb = ThisWorkbook
Set ws_admin = wb.Worksheets(“Admin”)
Set ws_rawdata = wb.Worksheets(“RawData”)

'Clear Rawdata sheet
ws_rawdata.Activate
Cells.Clear

'get file path
filepath = ws_admin.Range(“filepath”)

Application.DisplayAlerts = False

'Open source file and select all contents
Dim src_wb As Workbook
Dim src_ws As Worksheet

Set src_wb = Workbooks.Open(filepath)
Set src_ws = src_wb.Sheets(1)
src_ws.UsedRange.Select

'Copy all
Selection.Copy

'Paste all
ws_rawdata.Range(“A1”).PasteSpecial xlPasteValues

'Close source file
src_wb.Close SaveChanges:=False

wb.RefreshAll

Application.DisplayAlerts = True

End Sub

I linked this subroutine to the Refresh files and charts button. Once I specified the filename in the placeholder and clicked on the button, the dataset and pivot tables were updated automatically.

2. Creating a colors table using VBA

I created a table in the Admin sheet containing the list of the specific fruits and vegetables available in the dataset. In column F, I specified the tentative hexadecimal color codes for the color of each fruit or vegetable. I wanted to use these colors to update the colors in pivot charts. First, I wanted to paint column F with the color I specified in each cell.

Creating a list of available fruits and vegetables in the dataset along with their corresponding hexadecimal color codes. Illustration by Author.

Hexadecimal color code

The hexadecimal code for each color is a 6-digit hexadecimal number (0 to 9 or A to F) with base 16. In a hexadecimal color code RRGGBB, each pair of two letters represents the various shades of red, green, and blue color. In a Red Green Blue (RGB) system, the value of each shade ranges from 0 to 255.

For example, for a hexadecimal color code ffab23, I calculated the corresponding RGB code with the following calculation. ffab23 in the hexadecimal system translates to (255, 171, 35) in the RGB system referring to the Red, Green, and Blue color components respectively.

Calculating RGB code for a hexadecimal color code ffab23 manually. Illustration by Author.

This can also be visualized by going to the Custom Colors option in Excel as shown below:

Demonstrating RGB components and actual color for the hexadecimal color code ffab23. Illustration by Author.

In Excel VBA, using &H in combination with a value implies that it is a hexadecimal number and the Val() function returns the corresponding decimal number. In the Immediate Window below, r, g, and b represent the corresponding decimal values for each shade of Red, Green, and Blue respectively.

Immediate window displaying how the corresponding decimal values are derived in VBA from hexadecimal code. Illustration by Author.

In the code below, I created a named range color_code_range for the table containing the hexadecimal color code for each fruit or vegetable. I looped through each cell in the selection, derived the red, green, and blue components in decimal numbers, and painted the interior of the cell with the same RGB color code.

Sub refresh_color_table()

Dim wb As Workbook
Dim ws_admin As Worksheet

Set wb = ThisWorkbook
Set ws_admin = wb.Sheets(“Admin”)
ws_admin.Range("color_code_range").Select

Dim c As Range
Dim r, g, b As Long
Dim Hex As String

For Each c In Selection

Hex = c.Value

r = Val("&H" & Mid(Hex, 1, 2))
g = Val("&H" & Mid(Hex, 3, 2))
b = Val("&H" & Mid(Hex, 5, 2))
c.Interior.Color = RGB(r, g, b)

Next c

End Sub

When I ran the above subroutine, the column F gets painted with the same color as the color code as shown:

Painting the cells with the color code mentioned in it. Illustration by Author.

If the color code is changed, and the code is run again, it will generate new colors in the table. Isn’t that cool?

3. Working with a dictionary in VBA

In the next step, I wanted to assign the colors in the pivot charts based on the custom colors I chose above. For this purpose, I created a dictionary containing the product name as keys and the corresponding hexadecimal color codes as values.

The pre-requisite for creating a dictionary object in VBA is to activate the Microsoft Scripting Runtime beforehand. For this, you can go to Tools -> References -> Check the box next to Microsoft Scripting Runtime and click on ok.

Pre-requisite for working with a dictionary in Excel VBA. Illustration by Author.

In the code below, I created a dictionary object called colorMap. I looped through the Range E2:F10 in the Admin sheet. I added the contents in column E as keys, and the contents in column F as their corresponding values.

Sub create_dict()

Dim wb As Workbook
Dim ws_admin As Worksheet

Set wb = ThisWorkbook
Set ws_admin = wb.Sheets(“Admin”)

Dim colorMap As Dictionary
Set colorMap = New Dictionary

Dim i As Integer

For i = 2 To 10
If Not colorMap.Exists(Range("E" & i).Value) Then
colorMap.Add Range("E" & i).Value, Range("F" & i).Value
End If
Next i

For Each Key In colorMap.Keys()
Debug.Print Key & ": " & colorMap(Key)
Next Key

End Sub

In the second for loop above, I looped through each key of the colorMap dictionary and printed the keys and values in the immediate window as shown below:

Printing the contents of the colorMap dictionary object. Illustration by Author.

4. Managing pivot chart elements using VBA

Based on the learnings from the previous steps, I wanted to go one step further and update the pivot chart elements using VBA. In this case, I wanted to set the chart title automatically based on a cell value and apply the colors of specific fruits and vegetables defined in the Admin sheet to the pivot charts.

In this step, I assigned Plot1 and Plot2 sheets as an array called sheetNames. I declared chartObj as ChartObject. Within each sheet, I looped through each ChartObject among all ChartObjects.

Note: ChartObject acts as a container for a Chart object in VBA that controls the size and appearance of the embedded chart in a worksheet. It is a member of the ChartObjects collection. It is important to understand the differences in the methods and properties of each of these objects in VBA.

After going through each chartObj, I set the title for each chart based on the value in cell E1. Next, I looped through each series in the overall Series Collection of the Chart object. I assigned the series name (i.e., name of fruit or vegetable) to a variable called itemName, and got the corresponding color code from the colorMap dictionary. Similar to step 2, I got the red, green, and blue components of the color code in decimal numbers, and filled the series bar with the RGB colors.

Sub refresh_plots()

Dim wb As Workbook
Dim ws_admin As Worksheet
Dim ws As Worksheet

Set wb = ThisWorkbook
Set ws_admin = wb.Sheets("Admin")

Dim colorMap
Set colorMap = CreateObject("Scripting.Dictionary")
Dim i As Integer

For i = 2 To 10
If Not colorMap.Exists(Range("E" & i).Value) Then
colorMap.Add Range("E" & i).Value, Range("F" & i).Value
End If
Next i

Dim sheetNames As Variant
Dim sheetName As Variant
sheetNames = Array("Plot1", "Plot2")

Dim hex_color_code As String
Dim r, g, b As Integer

Dim chartObj As ChartObject

For Each sheetName In sheetNames
Set ws = wb.Sheets(sheetName)

For Each chartObj In ws.ChartObjects

chartObj.Chart.HasTitle = True
chartObj.Chart.ChartTitle.Text = ws.Range("E1").Value

For Each Series In chartObj.Chart.SeriesCollection

itemName = Series.Name
hex_color_code = colorMap(itemName)

r = Val("&H" & Mid(hex_color_code, 1, 2))
g = Val("&H" & Mid(hex_color_code, 3, 2))
b = Val("&H" & Mid(hex_color_code, 5, 2))
Series.Format.Fill.ForeColor.RGB = RGB(r, g, b)

Next Series
Next chartObj
Next sheetName

End Sub

An illustration of the use of this code is depicted below.

Transformation of pivot chart elements using the VBA code. Illustration by Author.

Conclusion

In this post, I illustrated how one can customize and automate working with pivot tables and charts using VBA. I have demonstrated the automation of four key tasks: refreshing pivot tables and charts with new datasets; creating color tables based on hexadecimal color code; how to work with dictionaries in VBA; and managing and updating pivot chart elements using VBA. In the second step, I have elaborated the conversion of hexadecimal color codes to the corresponding RGB color codes using both Excel and VBA, and used this technique in the subsequent steps.

The code and Excel file for this post are present in this GitHub repository. Thank you for reading!



Source

Related Articles

Back to top button