Automating Survey Data Visualisation with VBA Charts & Statistics

By Andyb 15 min read 2,810 words
vba charts automation excel survey visualization automate bar charts calculate statistics vba pdf export excel mac dynamic charts vba
Transform raw survey data into polished feedback reports with automated charts, statistics, and PDF export. Complete guide with Pro template for production-ready survey processing.

This is the final post in our 4-part series on Automating Student Feedback Processing with VBA. In Post 2, we cleaned the data. In Post 3, we created individual worksheets. Today, we're completing the automation with charts, statistics, and PDF export.



The Final Step: From Raw Data to Distributable Reports

You've automated the hard part: cleaning data and creating individual sheets for each student. But if you stopped there, you'd still need to:

  1. Manually create charts on 100 worksheets (30-45 minutes)
  2. Manually calculate statistics (averages, totals) for each student (20-30 minutes)
  3. Manually export 100 PDFs for distribution (15-20 minutes)

Total additional manual work: 65-95 minutes

This post shows you how to automate these final steps, transforming raw survey data into production-ready feedback reports with one click.



What We're Automating: Survey Data Visualisation

The End Goal

For each student's individual worksheet, we want to automatically:

  • Calculate summary statistics: Average score, total responses, min/max ratings
  • Generate a bar chart: Visual representation of rating distribution
  • Format professionally: Clean layout, clear labels, consistent styling
  • Export to PDF: Individual files for each student (Mac-compatible)

Why Charts Matter for Survey Feedback

Raw numbers in a spreadsheet are hard to interpret quickly. But a chart instantly shows:

  • Patterns: Are most ratings high (4-5) or distributed across the scale?
  • Outliers: Did one evaluator give significantly lower/higher scores?
  • Trends: Which criteria received the strongest/weakest feedback?

For student feedback, this transforms "here's a spreadsheet" into "here's a professional performance summary".



VBA Code: Generate Bar Charts for Each Sheet Automatically

Step 1: Calculate Summary Statistics

Before creating charts, let's add summary statistics to each student's worksheet:

Sub AddSummaryStatistics()
    ' Add summary statistics to each student sheet
    ' Run this AFTER creating individual sheets (Post 3)

    Dim ws As Worksheet
    Dim lastRow As Long
    Dim scoreColumn As Long
    Dim avgScore As Double
    Dim minScore As Double
    Dim maxScore As Double
    Dim responseCount As Long

    Application.ScreenUpdating = False

    ' Process each worksheet (skip the first sheet which contains source data)
    For Each ws In ThisWorkbook.Worksheets
        If ws.Index > 1 Then  ' Skip source data sheet
            With ws
                ' Find last row with data
                lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row

                ' Assuming scores are in column 3 (adjust for your data structure)
                scoreColumn = 3

                ' Skip if no data rows (only header)
                If lastRow > 1 Then
                    ' Calculate statistics
                    avgScore = Application.WorksheetFunction.Average(.Range(.Cells(2, scoreColumn), .Cells(lastRow, scoreColumn)))
                    minScore = Application.WorksheetFunction.Min(.Range(.Cells(2, scoreColumn), .Cells(lastRow, scoreColumn)))
                    maxScore = Application.WorksheetFunction.Max(.Range(.Cells(2, scoreColumn), .Cells(lastRow, scoreColumn)))
                    responseCount = lastRow - 1  ' Exclude header row

                    ' Add summary section (3 rows below data)
                    Dim summaryRow As Long
                    summaryRow = lastRow + 3

                    .Cells(summaryRow, 1).Value = "Summary Statistics"
                    .Cells(summaryRow, 1).Font.Bold = True
                    .Cells(summaryRow, 1).Font.Size = 12

                    .Cells(summaryRow + 1, 1).Value = "Average Score:"
                    .Cells(summaryRow + 1, 2).Value = Round(avgScore, 2)
                    .Cells(summaryRow + 1, 2).NumberFormat = "0.00"

                    .Cells(summaryRow + 2, 1).Value = "Highest Score:"
                    .Cells(summaryRow + 2, 2).Value = maxScore

                    .Cells(summaryRow + 3, 1).Value = "Lowest Score:"
                    .Cells(summaryRow + 3, 2).Value = minScore

                    .Cells(summaryRow + 4, 1).Value = "Total Responses:"
                    .Cells(summaryRow + 4, 2).Value = responseCount

                    ' Format summary section
                    .Range(.Cells(summaryRow + 1, 1), .Cells(summaryRow + 4, 1)).Font.Bold = True
                    .Range(.Cells(summaryRow + 1, 2), .Cells(summaryRow + 4, 2)).Interior.Color = RGB(217, 225, 242)  ' Light blue
                End If
            End With
        End If
    Next ws

    Application.ScreenUpdating = True

    MsgBox "Summary statistics added to " & (ThisWorkbook.Worksheets.Count - 1) & " student sheets.", vbInformation
End Sub

Step 2: Create Bar Charts Showing Rating Distribution

Now let's automatically generate a bar chart on each worksheet:

Sub CreateChartsForAllSheets()
    ' Create bar charts for each student sheet
    ' Run this AFTER adding summary statistics

    Dim ws As Worksheet
    Dim chartObj As ChartObject
    Dim lastRow As Long
    Dim scoreColumn As Long
    Dim questionColumn As Long
    Dim chartTitle As String

    Application.ScreenUpdating = False

    For Each ws In ThisWorkbook.Worksheets
        If ws.Index > 1 Then  ' Skip source data sheet
            With ws
                lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row

                ' Column configuration (adjust for your data)
                questionColumn = 2  ' Column B = Question/Criteria
                scoreColumn = 3     ' Column C = Score

                ' Skip if no data
                If lastRow > 1 Then
                    ' Delete existing chart if any (for re-running macro)
                    Dim chtObj As ChartObject
                    For Each chtObj In .ChartObjects
                        chtObj.Delete
                    Next chtObj

                    ' Create new chart
                    Set chartObj = .ChartObjects.Add(Left:=300, Top:=(lastRow * 15) + 100, Width:=450, Height:=280)

                    With chartObj.Chart
                        ' Set data source (Questions in col B, Scores in col C)
                        .SetSourceData Source:=ws.Range(ws.Cells(1, questionColumn), ws.Cells(lastRow, scoreColumn))

                        ' Chart type and styling
                        .ChartType = xlColumnClustered  ' Vertical bar chart

                        ' Chart title
                        .HasTitle = True
                        chartTitle = "Feedback Summary: " & ws.Name
                        .ChartTitle.Text = chartTitle
                        .ChartTitle.Font.Size = 14
                        .ChartTitle.Font.Bold = True

                        ' Remove legend (not needed for single data series)
                        .HasLegend = False

                        ' Format axes
                        .Axes(xlCategory).TickLabels.Orientation = 45  ' Angle labels for readability
                        .Axes(xlValue).MinimumScale = 0
                        .Axes(xlValue).MaximumScale = 5  ' Assuming 1-5 rating scale

                        ' Axis titles
                        .Axes(xlCategory).HasTitle = True
                        .Axes(xlCategory).AxisTitle.Text = "Feedback Criteria"
                        .Axes(xlValue).HasTitle = True
                        .Axes(xlValue).AxisTitle.Text = "Score"

                        ' Colour bars blue
                        .SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(68, 114, 196)

                        ' Add data labels on bars
                        .SeriesCollection(1).HasDataLabels = True
                        .SeriesCollection(1).DataLabels.Font.Bold = True
                    End With
                End If
            End With
        End If
    Next ws

    Application.ScreenUpdating = True

    MsgBox "Charts created for " & (ThisWorkbook.Worksheets.Count - 1) & " student sheets.", vbInformation
End Sub


Understanding the Chart Code: Key Concepts

Chart Positioning

Set chartObj = .ChartObjects.Add(Left:=300, Top:=(lastRow * 15) + 100, Width:=450, Height:=280)

Why dynamic positioning? (lastRow * 15) + 100 calculates the chart position based on how much data exists:

  • If student has 5 feedback rows → Chart appears after row 5
  • If student has 20 feedback rows → Chart appears after row 20
  • This prevents charts from overlapping with data

Chart Type Selection

.ChartType = xlColumnClustered  ' Vertical bar chart

Other chart types for survey data:

Chart Type VBA Constant Best For Vertical Bar Chart xlColumnClustered Comparing scores across criteria Horizontal Bar Chart xlBarClustered Long category names Line Chart xlLine Trends over time Pie Chart xlPie Percentage distribution

Axis Scaling

.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MaximumScale = 5  ' Assuming 1-5 rating scale

Why set fixed scale? Without this, Excel auto-scales each chart differently:

  • Student A's chart might show 3-5 range (all high scores)
  • Student B's chart might show 1-5 range (mixed scores)
  • Problem: Charts aren't comparable across students
  • Solution: Force all charts to use 0-5 scale for consistency


PDF Export: Distributing Individual Feedback Reports

The final step: export each student's worksheet as a PDF for distribution.

Mac-Compatible PDF Export

Sub ExportSheetsToPDF()
    ' Export each student sheet as individual PDF
    ' Mac-compatible approach (tested on Mac Excel)

    Dim ws As Worksheet
    Dim pdfPath As String
    Dim folderPath As String
    Dim exportCount As Long

    ' Create output folder
    folderPath = ThisWorkbook.Path & Application.PathSeparator & "Feedback_PDFs" & Application.PathSeparator

    ' Create folder if it doesn't exist
    On Error Resume Next
    MkDir folderPath
    On Error GoTo ErrorHandler

    Application.ScreenUpdating = False
    exportCount = 0

    For Each ws In ThisWorkbook.Worksheets
        If ws.Index > 1 Then  ' Skip source data sheet
            ' Build PDF filename
            pdfPath = folderPath & ws.Name & "_Feedback.pdf"

            ' Export worksheet as PDF
            On Error Resume Next
            ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath, Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False

            If Err.Number = 0 Then
                exportCount = exportCount + 1
            Else
                Debug.Print "Failed to export: " & ws.Name & " - " & Err.Description
            End If
            On Error GoTo ErrorHandler
        End If
    Next ws

    Application.ScreenUpdating = True

    MsgBox "Successfully exported " & exportCount & " PDFs to:" & vbCrLf & folderPath, vbInformation
    Exit Sub

ErrorHandler:
    Application.ScreenUpdating = True
    MsgBox "Error during PDF export: " & Err.Description, vbCritical
End Sub

Mac PDF Export: Important Notes

PDF export on Mac Excel has some quirks compared to Windows:

  • Works on Mac: ExportAsFixedFormat is supported
  • ⚠️ Print settings matter: Page setup (margins, orientation) must be configured first
  • ⚠️ No print preview: Mac doesn't show preview before export like Windows does
  • PathSeparator compatibility: Application.PathSeparator uses "/" on Mac, "\" on Windows automatically

Pro tip: Before running the PDF export macro, manually configure one worksheet's page setup (File → Page Setup), then copy those settings to all sheets with VBA.



The Complete Solution: Pro Template Overview

Our Survey Feedback Processor Pro Template combines all four posts into one streamlined workflow:

🔥 Pro Template: Survey Feedback Processor

What it does:

  1. Step 1: Cleans and standardises student names (Post 2)
  2. Step 2: Creates individual sheets for each student (Post 3)
  3. Step 3: Adds summary statistics to each sheet (Post 4)
  4. Step 4: Generates bar charts showing rating distribution (Post 4)
  5. Step 5: Exports all sheets as PDFs for distribution (Post 4)

Time savings:

  • Manual process: 3-4 hours for 100 students
  • With Pro template: 2 minutes (one click + coffee break)

What's included:

  • Complete VBA code combining all steps
  • Configurable settings (column numbers, chart types, rating scale)
  • Error handling for edge cases
  • Mac and Windows compatible
  • Professional formatting (blue headers, styled charts)
  • User guide with setup instructions

Get Pro Template (€15/month) →



Advanced Customizations: Beyond the Basics

Customization 1: Add Conditional Formatting to Charts

Colour bars differently based on score ranges (e.g., red for low scores, green for high):

' After creating chart, colour individual bars
Dim pointIndex As Long
Dim scoreValue As Double

For pointIndex = 1 To .SeriesCollection(1).Points.Count
    scoreValue = ws.Cells(pointIndex + 1, scoreColumn).Value

    ' Colour based on score
    If scoreValue >= 4 Then
        .SeriesCollection(1).Points(pointIndex).Format.Fill.ForeColor.RGB = RGB(0, 176, 80)  ' Green
    ElseIf scoreValue >= 3 Then
        .SeriesCollection(1).Points(pointIndex).Format.Fill.ForeColor.RGB = RGB(255, 192, 0)  ' Yellow
    Else
        .SeriesCollection(1).Points(pointIndex).Format.Fill.ForeColor.RGB = RGB(255, 0, 0)  ' Red
    End If
Next pointIndex

Customization 2: Create Multiple Chart Types

Add both a bar chart (score comparison) and a pie chart (score distribution):

' Create bar chart (as shown above)
Set chartObj1 = .ChartObjects.Add(Left:=300, Top:=(lastRow * 15) + 100, Width:=450, Height:=280)
' ... configure bar chart ...

' Create pie chart showing score distribution
Set chartObj2 = .ChartObjects.Add(Left:=780, Top:=(lastRow * 15) + 100, Width:=350, Height:=280)
With chartObj2.Chart
    .ChartType = xlPie
    .SetSourceData Source:=ws.Range(ws.Cells(2, scoreColumn), ws.Cells(lastRow, scoreColumn))
    .HasTitle = True
    .ChartTitle.Text = "Score Distribution"
    .HasLegend = True
End With

Customization 3: Email PDFs Automatically

For advanced users: automatically email each student their PDF feedback using Outlook automation (Windows only):

' Requires reference to Microsoft Outlook Object Library
Sub EmailPDFsToStudents()
    Dim outlookApp As Object
    Dim outlookMail As Object
    Dim ws As Worksheet
    Dim studentEmail As String
    Dim pdfPath As String

    Set outlookApp = CreateObject("Outlook.Application")

    For Each ws In ThisWorkbook.Worksheets
        If ws.Index > 1 Then
            ' Assuming email addresses in source sheet
            studentEmail = GetStudentEmail(ws.Name)  ' Custom function to lookup email
            pdfPath = ThisWorkbook.Path & "\Feedback_PDFs\" & ws.Name & "_Feedback.pdf"

            Set outlookMail = outlookApp.CreateItem(0)  ' olMailItem
            With outlookMail
                .To = studentEmail
                .Subject = "Your Peer Feedback Summary"
                .Body = "Hi " & ws.Name & "," & vbCrLf & vbCrLf & _
                        "Please find attached your peer feedback summary." & vbCrLf & vbCrLf & _
                        "Best regards"
                .Attachments.Add pdfPath
                .Send  ' Or .Display to review before sending
            End With
        End If
    Next ws

    MsgBox "Emails sent successfully!", vbInformation
End Sub

Note: Email automation requires Outlook installed and configured (Windows only). Mac users can export PDFs and distribute via their preferred email client manually.



Troubleshooting: Chart & PDF Export Issues

Problem: Charts appear but show no data

Cause: Incorrect data range or column references.

Solution:

  • Verify questionColumn and scoreColumn match your data structure
  • Check that data exists in those columns (not empty/blank)
  • Use Debug.Print to output the data range being used

Problem: PDF export fails on Mac

Cause: Page setup not configured or permissions issue.

Solution:

  • Manually set up page layout on one sheet first (File → Page Setup)
  • Grant Excel folder permissions if macOS prompts
  • Try exporting to Desktop first (guaranteed write access)

Problem: Charts overlap with data

Cause: Dynamic positioning calculation incorrect for your data.

Solution:

  • Increase the Top value: (lastRow * 20) + 150 instead of (lastRow * 15) + 100
  • Or use fixed positioning: Top:=500 (500 pixels from top)

Problem: Charts created but axis scale is wrong

Cause: Your rating scale differs from the assumed 1-5 scale.

Solution:

  • Adjust .Axes(xlValue).MaximumScale to match your scale (e.g., 10 for 1-10 ratings)
  • Consider using auto-scale for variable ranges: remove the MaximumScale line entirely


Real-World Results: Complete Time Comparison

Here's the full breakdown comparing manual work to the complete automated solution:

Task Manual (100 students) VBA Automation Time Saved Data cleanup (Post 2) 40 min 5 sec 40 min Create individual sheets (Post 3) 120 min 30 sec 119 min Add summary statistics 30 min 10 sec 30 min Create charts 45 min 15 sec 45 min Export PDFs 20 min 20 sec 20 min TOTAL 255 min (4.25 hrs) 80 sec (1.3 min) 254 min saved

Annual impact: If you process surveys 4 times per year:

  • Time saved per year: 1,016 minutes = 16.9 hours
  • Over 5 years: 84.5 hours = 2.1 working weeks reclaimed


Beyond Student Feedback: Other Use Cases

The techniques in this series apply to any scenario requiring automated reporting:

Employee Performance Reviews

  • Clean employee names and departments
  • Create individual sheets per employee with their 360° feedback
  • Generate charts showing scores across competencies
  • Export PDFs for HR distribution

Customer Satisfaction Surveys

  • Standardise product/service names
  • Create sheets per product category
  • Visualise satisfaction trends with line charts
  • Export executive summaries as PDFs

Sales Performance Dashboards

  • Clean sales region and rep names
  • Create individual sheets per sales rep
  • Generate bar charts comparing metrics (revenue, deals closed, conversion rate)
  • Automate monthly PDF reports


Series Recap: The Complete VBA Automation Journey

Over this 4-part series, we've built a production-ready survey feedback automation system:

📚 Complete Series Summary

Post 1: Introduction & Case Study

  • Identified the problem: 3 hours of manual work per survey
  • Broke down the solution into 3 manageable steps
  • Calculated ROI: 12 hours saved per year for one recurring task

Post 2: Data Cleanup

  • Why data cleaning prevents automation failures
  • VBA functions: Trim(), Proper(), Replace()
  • Edge case handling: hyphens, apostrophes, titles
  • Free template: Data Processing & Cleanup

Post 3: Creating Individual Sheets

  • Using Collections to extract unique values
  • Sheet naming rules and character limitations
  • Filtering and copying data programmatically
  • Free template: Create Sheet Per Unique Value

Post 4: Charts & Visualisation (this post)

  • Adding summary statistics to each sheet
  • Creating bar charts with VBA ChartObjects
  • Mac-compatible PDF export
  • Pro template: Survey Feedback Processor (complete solution)


Next Steps: Choose Your Path

Path 1: DIY with Free Templates

Download the free templates and run each step separately:

  1. Data Processing & Cleanup (Post 2)
  2. Create Sheet Per Unique Value (Post 3)
  3. Copy the chart code from this post and customise

Best for: Learning VBA, customising heavily, tight budget

Path 2: Get the Pro Template

One-click solution combining all 4 posts:

  • No setup required (just configure column numbers)
  • Professionally tested and optimised
  • Includes user guide and troubleshooting
  • Access to all Pro templates (40+ and growing)

Best for: Production use, recurring tasks, time-sensitive projects

🚀 Get Started with Pro Templates

Standard Plan (€15/month):

  • Access to all Pro templates including Survey Feedback Processor
  • 75 custom code generations per month
  • 5 code reviews when templates don't fit perfectly
  • Priority email support

Pro Plan (€30/month):

  • Everything in Standard, plus:
  • 250 custom code generations per month
  • Unlimited code reviews
  • Access to o1-mini AI model for complex VBA challenges
  • Early access to new templates

View Pricing & Upgrade →

Path 3: Generate Custom Code

Need something different from the templates? Describe your exact requirements and let AI generate VBA code tailored to your use case:

Example custom requests:

  • "Create sheets per student AND class, with pie charts showing score percentages, export to PowerPoint"
  • "Process employee survey data, create department summaries, generate line charts showing trends over 4 quarters"
  • "Split client feedback by region, create comparison charts across all regions, highlight top/bottom performers"

Generate Custom VBA Code →



Final Thoughts: VBA Automation as a Mindset

This series demonstrates that powerful automation doesn't require being a programmer. You just need:

  1. Recognition: Identify repetitive tasks that waste time
  2. Breakdown: Split complex problems into smaller steps
  3. Incremental progress: Start simple (data cleanup), build up (sheets, charts)
  4. Iteration: Test on small datasets first, refine, then scale

The student feedback case study is just one example. Look around your daily work:

  • What Excel tasks do you do every week or every month?
  • Which tasks involve copy-pasting the same actions repeatedly?
  • Where do manual errors cause rework and frustration?

Those are your automation opportunities. And now you have the tools to tackle them.



Thank you for following this series. Happy automating! 🚀

🚀 Want More VBA Tips Like This?

Join 1,000+ Excel professionals getting weekly VBA tutorials, free code templates, and automation strategies delivered to their inbox.

Free forever
No spam, ever
Unsubscribe anytime

Or generate VBA code instantly:

Try vbacode.io