Create a “Chart Index”, Excel worksheet

This Excel macro creates a “Chart Index” worksheet that auto-generates a centralised listing of all the workbook’s charts, creates a preview icon and hyperlinks to the original.

You can add this macro to any workbook and running it will give you an Index sheet for all those charts for quick, easy access.

Example “Chart Index”Chart Index2 - James Follett

 
Step 1: Hold down the ALT + F11 keys in Excel, and it opens the Microsoft Visual Basic for Applications window.

Step 2: Click Insert > Module, and paste the following macro in the Module Window.

Option Explicit

Public Sub CreateChartIndex()
' Macro to create a "Chart Index" worksheet that auto generates a listing of all
' the workbook's Charts, creates a preview icon and hyperlinks to the original

' Set these inputs here (or set them as procedural inputs)
Const SHEET_NAME_CHART_INDEX As String = "Chart Index"
Const RANGE_ROW_CHART_INDEX As String = 7
Const CHART_PREVIEW As Boolean = True

Dim count As Integer
Dim sht As Worksheet
Dim shtIndex As Worksheet
Dim strSheetName As String

Dim cht As Chart
Dim chtObj As ChartObject
Dim shtChartTitle As String
Dim srs As Series
Dim strSeriesNames As String
Dim shp1 As ShapeRange
Dim shp2 As ShapeRange
Dim pic As Picture

Application.ScreenUpdating = False ' Speed optimisation
Application.EnableCancelKey = xlDisabled ' Excel Bug Fix for preventing random "Code execution has been interrupted" errors

' Create "Chart Index" sheet
If WorksheetExists(SHEET_NAME_CHART_INDEX) = False Then
Sheets.Add Before:=Sheets(1)
Set shtIndex = Sheets(1)
shtIndex.Name = SHEET_NAME_CHART_INDEX
Else
Set shtIndex = Sheets(SHEET_NAME_CHART_INDEX)
End If

' Delete All
Cells.Select
Selection.Delete
For Each pic In ActiveSheet.Pictures
pic.Delete
Next pic

' Add macro button (to run this macro)
shtIndex.Buttons.Add(20, 20, 130, 30).Select
shtIndex.Buttons(1).Name = "CreateChartIndex"
Selection.OnAction = "CreateChartIndex"
Selection.Characters.Text = "Create Chart Index"
Selection.Characters(Start:=1, Length:=18).Font.Size = 14

count = RANGE_ROW_CHART_INDEX

shtIndex.Select
shtIndex.Range("A1").Select

' Clear any previous Chart Index and create new Headers
With shtIndex
.Range("A" & count).Value = "Preview"
.Range("B" & count).Value = "Sheet (and graph link)"
.Range("C" & count).Value = "Chart Title"
.Range("D" & count).Value = "Chart Series"

.Range("A" & count).Font.Bold = True
.Range("B" & count).Font.Bold = True
.Range("C" & count).Font.Bold = True
.Range("D" & count).Font.Bold = True
End With

' Cycle Sheets
For Each sht In ActiveWorkbook.Sheets
strSheetName = sht.Name

If strSheetName <> SHEET_NAME_CHART_INDEX Then
' Cycle Charts
For Each chtObj In sht.ChartObjects
count = count + 1
Set cht = chtObj.Chart

If cht.HasTitle Then
shtChartTitle = cht.ChartTitle.Text
Else
shtChartTitle = "NA"
End If

' Find Top Left cell under chart (to act as a hyperlink ref)
Dim rge As Range
Set rge = Range(Cells(chtObj.TopLeftCell.Row, chtObj.TopLeftCell.Column), _
Cells(chtObj.BottomRightCell.Row, chtObj.BottomRightCell.Column))

' Cycle Chart Series
' Get List of Series for a given chart
strSeriesNames = ""
For Each srs In cht.SeriesCollection
strSeriesNames = strSeriesNames & srs.Name & ", "
Next
strSeriesNames = Left(strSeriesNames, Len(strSeriesNames) - 2)

' Print information for a particular graph to "Chart Index"
shtIndex.Hyperlinks.Add Anchor:=shtIndex.Range("B" & count), Address:="", SubAddress:="'" & _
strSheetName & "'!" & rge.Address, TextToDisplay:=strSheetName
shtIndex.Range("C" & count).Value = shtChartTitle
shtIndex.Range("D" & count).Value = strSeriesNames

' Create a chart preview
If CHART_PREVIEW Then
' Copy chart and paste as a GIF
cht.ChartArea.Copy
Range("A1").Select
shtIndex.PasteSpecial Format:="Picture (Enhanced Metafile)", Link:=False _
, DisplayAsIcon:=False
' Resize chart (smaller)
Set shp1 = Selection.ShapeRange
shp1.Height = shtIndex.Rows(count).Height
shp1.LockAspectRatio = msoFalse
shp1.Width = shtIndex.Columns(1).Width
' Copy paste GIF (to make underlying object size small (memory saving))
Selection.Copy
Range("A1").Select ' object deselection loses reference to original larger chart
shtIndex.PasteSpecial Format:="Picture (GIF)", Link:=False _
, DisplayAsIcon:=False

Set shp2 = Selection.ShapeRange
shp1.Delete

' Set location
shp2.Left = shtIndex.Range("A" & count).Left '- shp2.Width
shp2.Top = shtIndex.Range("A" & count).Top
Range("A1").Select

End If
Next
End If
Next sht

' Sheet Formating
Columns("B:C").EntireColumn.AutoFit
ActiveSheet.Shapes("CreateChartIndex").Width = 140

Application.ScreenUpdating = True
Application.EnableCancelKey = xlInterrupt ' Excel Bug Fix for preventing random "Code execution has been interrupted" errors
End Sub

Private Function WorksheetExists(shtName As String) As Boolean
' Check if a worksheet already exists (not an in-built, excel function)
Dim sht As Worksheet
Dim rtn As Boolean

rtn = False

shtName = UCase(shtName)
For Each sht In ThisWorkbook.Sheets
If UCase(sht.Name) = shtName Then
rtn = True
Exit For
End If
Next

WorksheetExists = rtn

End Function

Step 3: Press the F5 key to run this macro (“CreateChartIndex”).

This entry was posted in VBA and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *