In Build an Excel Add-In 1 – Basic Routine I coded a procedure in VBA to create a regular chart from an arbitrary rectangular range, including from a pivot table. In Build an Excel Add-In 2 – Enhanced Functionality I turned this routine into a modular function, that could be called from any code which passed in the appropriate settings as arguments to the function.
In this post I present an example of another modular function. I say “modular” because the function is not integrated into any other code, and thus can be called from any procedure that needs its functionality.
One big advantage of modular functions like this is that they can be called from many other procedures, and each time they execute the same way. If I want to make an adjustment to the function, I can make the change in one place, and the change is reflected every time it is run.
Another advantage of such modular functions is that they can be copied from one project and pasted into another, and you don’t have to carry out extensive testing to make sure that it works. A quick run through the code is usually sufficient to ensure proper execution.
The New Function
This rudimentary function is still a very useful one. It takes a chart as its sole argument, applies some formatting to the chart, then returns the chart as its value.
Given a chart variable called TheChart, the function is called like this:
Set TheChart = CleanUpChart(TheChart)
The function removes the borders on the chart area, plot area, and legend. It applies a uniform, non-auto-scaling font to all text elements. It removes borders on bar and column chart series and changes the gap spacing to 100%. It also widens the plot area to redue the wasted white space around the chart.
Here is the function in all of its glory. Feel free to adapt it to your own needs, using your own preferred formatting.
An alternate version of this function may convert 3D charts to their 2D equivalents, for example.
Function CleanUpChart(cht As Chart) As Chart
' PRETTIFY THIS CHART
' ' chart area: remove border, fix font size, disable font autoscaling
' ' legend: remove border, resize, reposition
' ' plot area: remove border and fill, maximize size, minimize margins
' ' gridlines: remove
Dim dLgndWidth As Double
Dim iLgndEntry As Long
Dim iAxType As XlAxisType
Dim iAxGroup As XlAxisGroup
Dim iSrs As Long
Dim bScreenUpdating As Boolean
bScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
With cht
With .ChartArea
.Border.LineStyle = xlNone
.AutoScaleFont = False
.Font.Size = 8
End With
With .Legend
.Border.LineStyle = xlNone
.Left = 0
.Width = cht.ChartArea.Width
dLgndWidth = .LegendEntries(1).Width
For iLgndEntry = 2 To .LegendEntries.Count
If dLgndWidth < .LegendEntries(iLgndEntry).Width Then
dLgndWidth = .LegendEntries(iLgndEntry).Width
End If
Next
.Width = dLgndWidth
.Left = cht.ChartArea.Width
End With
With .PlotArea
.Border.LineStyle = xlNone
.Interior.ColorIndex = xlNone
.Top = 0
.Left = 0
.Height = cht.ChartArea.Height
.Width = cht.Legend.Left - 2
End With
For iAxGroup = xlPrimary To xlSecondary
For iAxType = xlCategory To xlValue
If .HasAxis(iAxType, iAxGroup) Then
If .Axes(iAxType, iAxGroup).HasMajorGridlines Then
.Axes(iAxType, iAxGroup).MajorGridlines.Delete
End If
If .Axes(iAxType, iAxGroup).HasMinorGridlines Then
.Axes(iAxType, iAxGroup).MinorGridlines.Delete
End If
End If
Next
Next
If .ChartType = xlColumnClustered Or .ChartType = xlBarClustered Then
.ChartGroups(1).GapWidth = 100
For iSrs = 1 To .SeriesCollection.Count
.SeriesCollection(iSrs).Border.LineStyle = xlNone
Next
End If
End With
Set CleanUpChart = cht
Application.ScreenUpdating = bScreenUpdating
End Function
Contents: How to Build an Excel Add-In
- Build an Excel Add-In 1 – Basic Routine
- Build an Excel Add-In 2 – Enhanced Functionality
- Build an Excel Add-In 3 – Auxiliary Modular Functions
- Build an Excel Add-In 4 – Create the Dialog
- Build an Excel Add-In 5 – Tie the Code Together
- Build an Excel Add-In 6 – Interface for 2003
- Build an Excel Add-In 7 – Interface for 2007
- Build an Excel Add-In 8 – Last Steps
- Build an Excel Add-In 9 – Deployment
Matt says
Great idea – I do this all the time, but have never thought of creating a routine to automate this repetitive re-formatting! … will be adding a version of this to my add-in.
Any chance you could extrapolate (with an example?) on how the function is called, as I am having trouble with this…
Jon Peltier says
Matt –
In a couple more installments, I’ll have the whole code ready, which will show how this is used.
But it’s really easy enough. You pass a reference to the chart you want cleaned up to the function, and it returns a reference to the now cleaned up chart.
You call it like this:
You could take it a step further. Say you want a routine to clean up the active chart. If you call this CleanUpChart function, it will produce charts formatted just like any other routine that calls CleanUpChart.
DaleW says
Nice example! (I’ll need to update some code in my PERSONAL.xls workbook.)
Since not every chart needs a legend, I imagine your final example will include more error trapping, such as a block or two that I needed to add, beginning:
If cht.HasLegend Then . . .
Jon Peltier says
Dale –
Yes, as I said, this is a preliminary kind of chart cleansing function. There are a lot of places to test for chart features or offer user options to make the function more powerful and flexible.
Jeff Weir says
Slight improvement suggestion
‘ PRETTIFY THIS CHART
‘ ‘ chart area: remove border, fix font size, disable font autoscaling
‘ ‘ legend: remove border, resize, reposition
‘ ‘ plot area: remove border and fill, maximize size, minimize margins
‘ ‘ gridlines: remove
‘ ‘ chart type: if Pie Chart, delete chart and/or crash application to teach user a lesson
meyer garber says
The ? indicates my ignorance to begin with. A simple question :
suppose I have a cell, say A33, with this text or whatever you call it in it:
$B11:$B21,$A11:$A21.
Legitimate x-y data are in these ranges. You cannot now type =slope(A33) in some other cell and get the slope. Why not? and how could you do it?
Many thanks. Maybe the answer is somewhere in your wonderful site.
mg
Jon Peltier says
You have to use
=SLOPE($B11:$B21,$A11:$A21)
with the cell addresses in the SLOPE function. Or you can use INDIRECT as follows. Suppose A1 contains “$A11:$A21” and B1 contains “$B11:$B21” (without quotes). This will give you the slope you want:
=SLOPE(INDIRECT(B1),INDIRECT(A1))
Stella Maris Gonzalez says
I need to build an Excel Add-In component to get the list of all the conditional formatting in a workbook.
Can you help me?
Thanks!
Jon Peltier says
Stella –
You have to figure out what to put into the add-in to enumerate the conditional formatting. I have never tried this; perhaps you could Google ‘list conditional formatting in Excel’. Once you get that, use these pages to help develop it into an add-in.