How to Automatically Split Excel Data into Multiple Sheets Using VBA

Last updated on October 4, 2024 By Victor Chan

Imagine your Excel worksheet is like a cluttered bookshelf, with all your books jumbled together. Finding what you need can be a real chore.


Now, what if you could magically organize those books into neat sections, making everything easy to find?


In Excel, this is like splitting your data into separate sheets based on categories. And guess what? There's a way to do this automatically and super fast using a bit of VBA magic!


In this tutorial, we'll show you how to use VBA (Visual Basic for Applications) to automatically split your data into multiple worksheets based on unique values in a category column.


Whether you're managing sales data, inventory lists, or personnel records, this method will save you time and effort.

Download FREE Excel Workbook

Step 1: Sign up for free Click Here

Step 2: Log in for access Click Here

Step 3: Download file Excel Table Splitter (VBA).zip

Are you new to Excel VBA Macros?

• Find out how to enable and disable macros in Excel with this tutorial

• Save time and effort by copying VBA macros from one workbook to another with these instructions

1. Why Split Data into Multiple Sheets?

When working with large datasets, it's often helpful to split data into separate sheets based on categories. For example:

  • Departments: Sending each department its list of employees.
  • Product Categories: Analyzing sales data for each product type.
  • Regions: Distributing regional reports to local managers.

Splitting data manually is time-consuming and prone to errors. Automating this task not only saves time but also ensures consistency and accuracy.

2. The Manual Method (And Its Drawbacks)

Let's start by looking at how most people might approach this task manually.

Steps to Manually Split Data:

  • 1. Create a Table: Convert your data range into an Excel table.
  • 2. Filter Data: Use the filter feature to display only the rows matching a specific category.
  • 3. Copy and Paste: Copy the filtered data and paste it into a new worksheet.
  • 4. Repeat: Do this for each unique category.

Example:

Suppose you have a list of employees from different departments, and you want to create a separate sheet for each department.

  • Select 'Finance': Filter the table to show only Finance department employees.
  • Copy Data: Copy and paste this data into a new worksheet named 'Finance'.
  • Adjust Formatting: Auto-fit columns and adjust formatting as needed.
  • Repeat: Do the same for 'Marketing', 'Operations', 'Sales', etc.

Drawbacks:

  • Time-Consuming: With many categories, this process can take a lot of time.
  • Error-Prone: Manual copying and pasting increase the chance of mistakes.
  • Inefficient: Repeating the same steps over and over is not efficient.

3. Introducing VBA: Your Automated Assistant

VBA stands for Visual Basic for Applications. It's like having a personal assistant inside Excel that can perform tasks for you.

Benefits of Using VBA:

  • Automation: Performs repetitive tasks quickly.
  • Accuracy: Reduces human errors.
  • Efficiency: Saves time, especially with large datasets.

By writing a simple VBA script, you can automatically split your data into multiple sheets based on unique categories.

4. Preparing Your Data as an Excel Table

Before using VBA, it's important to format your data as an Excel Table.

Why Use Excel Tables?

  • Structured Data: Tables make it easier to manage and analyze data.
  • Dynamic Range: Tables automatically adjust when new data is added.
  • Easier Coding: VBA can easily reference and manipulate table data.

How to Create an Excel Table:

  • 1. Select Your Data: Click anywhere inside your data range.
  • 2. Insert Table:
  • - Go to the Insert tab.
  • - Click on Table.
  • 3. Confirm Table Range: Ensure the correct range is selected and that 'My table has headers' is checked.
  • 4. Click OK: Your data is now formatted as an Excel Table.

5. Setting Up the VBA Code

Now, let's set up the VBA code that will do the heavy lifting.

Step 1: Access the Developer Tab

If you don't see the Developer tab in Excel:

  • 1. Right-Click on the Ribbon: Choose Customize the Ribbon.
  • 2. Check 'Developer': In the right pane, find and check the Developer option.
  • 3. Click OK: The Developer tab will now appear in the Ribbon.

Step 2: Enable the Personal Macro Workbook

The Personal Macro Workbook is a hidden workbook that loads whenever you open Excel. It stores macros that you can use in any workbook.

  • 1. Record a Dummy Macro:
  • - Go to the Developer tab.
  • - Click Record Macro.
  • - In the 'Store macro in' dropdown, select Personal Macro Workbook.
  • - Click OK.
  • 2. Stop Recording:
  • - Click Stop Recording on the Developer tab.
  • 3. Access the VBA Editor:
  • - Click on Visual Basic in the Developer tab.
  • 4. Locate the Personal Workbook:
  • - In the Project Explorer, find VBAProject (PERSONAL.XLSB).

Step 3: Insert the VBA Code

  • 1. Insert a New Module:
  • - Right-click on Modules under PERSONAL.XLSB.
  • - Select Insert > Module.
  • 2. Name the Module:
  • - Click on the module to select it.
  • - In the Properties window, change the name to Filter_Table_To_Sheets.
  • 3. Copy the Code:
  • - Use the code provided below.
  • 4. Paste the Code:
  • - Paste the code into the module window of Filter_Table_To_Sheets that’s in your Personal Macro Workbook. You can also get this code from the downloadable workbook.

[VBA Code Box]

Option Explicit 

' *** Module Overview *** 
' This module automates filtering data in a table and copying the filtered results 
' to new worksheets. 
' 
' ### Subroutines and Functions ### 
' 
' - Sub Filter_Table_To_Sheets: 
'   - Prompts the user to select a column to filter by. 
'   - Filters the table based on unique values in the selected column. 
'   - Creates new sheets for each unique value, copying the filtered data to them. 
'   - Handles user input for sorting and manages existing sheets with matching names. 
' 
' - Sub SortArray: 
'   - Sorts an array of values in either ascending or descending order using a 
'     simple sorting algorithm. 
' 
' - Function GetUniqueArray: 
'   - Extracts unique values from a specified range and returns them in an array. 
' 
' - Function CleanSheetName: 
'   - Cleans up sheet names by truncating to Excel's 31 character limit and 
'     replacing invalid characters to make them valid Excel sheet names. 
' 
' - Function EnsureUniqueSheetName: 
'   - Ensures that a sheet name is unique by adding a numeric suffix if needed. 
' 
' - Function SheetExists: 
'   - Checks if a worksheet with a given name already exists in the workbook. 
' 
' *** End of Module Overview *** 

Sub Filter_Table_To_Sheets() 
    Dim selectedCell As Range 
    Dim selectedTable As ListObject 
    Dim ws As Worksheet 
    Dim filterColumn As Range 
    Dim uniqueValues() As Variant 
    Dim i As Long 
    Dim newSheet As Worksheet 
    Dim copyRange As Range 
    Dim headerRange As Range 
    Dim existingSheetNames As Collection 
    Dim sheetName As Variant 
    Dim userResponse As VbMsgBoxResult 
    Dim cleanedSheetName As String 
    Dim sortOrder As String 
     
    ' Step 1: Ask the user to select a cell in the column they want to filter by 
    On Error Resume Next 
    Set selectedCell = Application.InputBox("Please select a cell in the column you want to filter by:", Type:=8) 
    On Error GoTo 0 
     
    ' Check if the user selected a cell 
    If selectedCell Is Nothing Then 
        MsgBox "No cell was selected. Exiting.", vbExclamation 
        Exit Sub 
    End If 
     
    ' Step 2: Check if the selected cell is part of a table 
    On Error Resume Next 
    Set selectedTable = selectedCell.ListObject 
    On Error GoTo 0 
     
    If selectedTable Is Nothing Then 
        MsgBox "The selected cell is not part of a table. Please select a valid table cell.", vbExclamation 
        Exit Sub 
    End If 
     
    ' Determine the column to filter by based on the selected cell 
    Set filterColumn = selectedTable.ListColumns(selectedCell.Column - selectedTable.Range.Column + 1).DataBodyRange 
     
    ' Step 3: Get all unique values in the selected column 
    uniqueValues = GetUniqueArray(filterColumn) 
     
    ' Step 4: Prompt the user to choose the sorting order (1 = A-Z, 2 = Z-A, 3 = Original) 
    sortOrder = Application.InputBox("Choose sorting order: 1 = A-Z, 2 = Z-A, 3 = Original", Type:=1) 
     
    ' Step 5: Handle the user's choice and sort accordingly 
    Select Case sortOrder 
        Case "1" 
            Call SortArray(uniqueValues, True) 
        Case "2" 
            Call SortArray(uniqueValues, False) 
        Case "3" 
            ' No sorting, keep original order 
        Case Else 
            ' Default to A-Z and notify the user 
            MsgBox "Invalid choice, defaulting to A-Z sorting.", vbInformation 
            Call SortArray(uniqueValues, True) 
    End Select 
     
    ' Step 6: Check for existing sheets with names matching the unique values 
    Set existingSheetNames = New Collection 
    For i = LBound(uniqueValues) To UBound(uniqueValues) 
        cleanedSheetName = CleanSheetName(CStr(uniqueValues(i))) 
        If SheetExists(cleanedSheetName) Then 
            existingSheetNames.Add cleanedSheetName 
        End If 
    Next i 
     
    ' Step 7: Ask the user if it's okay to delete the existing sheets 
    If existingSheetNames.Count > 0 Then 
        userResponse = MsgBox("There are existing sheets with the same names as the values in the chosen column. " &_ 
                              "Would you like to delete these sheets before proceeding?", vbYesNo + vbExclamation, "Delete Sheets") 
        If userResponse = vbYes Then 
            For Each sheetName In existingSheetNames 
                Application.DisplayAlerts = False ' Disable the prompt for deleting the sheet 
                ActiveWorkbook.Worksheets(sheetName).Delete 
                Application.DisplayAlerts = True ' Re-enable alerts after deletion 
            Next sheetName 
        Else 
            MsgBox "Process aborted. No sheets were deleted.", vbInformation 
            Exit Sub 
        End If 
    End If 
     
    ' Step 8: Get the header row of the table (if it exists) 
    Set headerRange = selectedTable.HeaderRowRange 
     
    ' Step 9: Create new sheets for each unique value and copy the filtered data 
    Application.ScreenUpdating = False 
    For i = LBound(uniqueValues) To UBound(uniqueValues) 
        cleanedSheetName = CleanSheetName(CStr(uniqueValues(i))) 
         
        ' Ensure unique sheet names 
        cleanedSheetName = EnsureUniqueSheetName(cleanedSheetName) 
         
        ' Apply filter based on the unique value 
        selectedTable.Range.AutoFilter Field:=filterColumn.Column - selectedTable.Range.Column + 1, Criteria1:=uniqueValues(i) 
         
        ' Identify the visible range after filtering 
        On Error Resume Next ' Handle case where no rows are visible 
        Set copyRange = selectedTable.DataBodyRange.SpecialCells(xlCellTypeVisible) 
        On Error GoTo 0 
         
        If Not copyRange Is Nothing Then 
            ' Create a new sheet and copy the filtered data 
            Set newSheet = ActiveWorkbook.Worksheets.Add(After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)) 
            newSheet.Name = cleanedSheetName 
             
            ' Copy the header row to the new sheet 
            If Not headerRange Is Nothing Then 
                headerRange.Copy Destination:=newSheet.Range("A1") 
            End If 
             
            ' Copy the filtered data to the new sheet 
            copyRange.Copy Destination:=newSheet.Range("A2") 
             
            ' Auto-fit columns in the new sheet 
            newSheet.Columns.AutoFit 
        End If 
    Next i 
    Application.ScreenUpdating = True 
     
    ' Clear the filter on the original table 
    selectedTable.AutoFilter.ShowAllData 
     
    MsgBox "Filtered data copied to new sheets for each unique value.", vbInformation 
End Sub 

Sub SortArray(ByRef arr() As Variant, ascending As Boolean) 
    ' Sorts an array either A-Z or Z-A 
    Dim i As Long, j As Long 
    Dim temp As Variant 
     
    ' Perform a simple bubble sort on the array 
    For i = LBound(arr) To UBound(arr) - 1 
        For j = i + 1 To UBound(arr) 
            If (ascending And arr(i) > arr(j)) Or (Not ascending And arr(i) < arr(j)) Then 
                ' Swap values in the array 
                temp = arr(i) 
                arr(i) = arr(j) 
                arr(j) = temp 
            End If 
        Next j 
    Next i 
End Sub 

Function GetUniqueArray(rng As Range) As Variant() 
    ' Function to retrieve unique values from a range and store them directly in an array 
    Dim cell As Range 
    Dim uniqueValues() As Variant 
    Dim isUnique As Boolean 
    Dim i As Long, j As Long 
    Dim currentValue As Variant 
     
    ' Initialize the uniqueValues array with an initial size of 1 
    ReDim uniqueValues(1 To 1) 
    i = 0 ' This will keep track of the number of unique values 
     
    ' Loop through each cell in the range 
    For Each cell In rng 
        currentValue = cell.value 
        If currentValue <> "" Then 
            ' Check if the value is already in the uniqueValues array 
            isUnique = True 
            For j = 1 To i 
                If uniqueValues(j) = currentValue Then 
                    isUnique = False 
                    Exit For 
                End If 
            Next j 
             
            ' If the value is unique, add it to the array 
            If isUnique Then 
                i = i + 1 
                ReDim Preserve uniqueValues(1 To i) 
                uniqueValues(i) = currentValue 
            End If 
        End If 
    Next cell 
     
    ' Return the array with unique values 
    GetUniqueArray = uniqueValues 
End Function 

Function CleanSheetName(sheetName As String) As String 
    ' Truncate the sheet name to 31 characters 
    sheetName = Left(sheetName, 31) 
     
    ' Replace invalid characters with underscores 
    sheetName = Replace(sheetName, "/", "_") 
    sheetName = Replace(sheetName, "\", "_") 
    sheetName = Replace(sheetName, "?", "_") 
    sheetName = Replace(sheetName, "*", "_") 
    sheetName = Replace(sheetName, ":", "_") 
    sheetName = Replace(sheetName, "[", "_") 
    sheetName = Replace(sheetName, "]", "_") 
     
    ' Remove apostrophes at the beginning or end of the name 
    If Left(sheetName, 1) = "'" Then sheetName = Mid(sheetName, 2) 
    If Right(sheetName, 1) = "'" Then sheetName = Left(sheetName, Len(sheetName) - 1) 
     
    ' Ensure the name is not blank 
    If sheetName = "" Then sheetName = "Sheet" 
     
    ' Avoid the reserved word "History" 
    If UCase(sheetName) = "HISTORY" Then sheetName = "History_Sheet" 
     
    CleanSheetName = sheetName 
End Function 

Function EnsureUniqueSheetName(sheetName As String) As String 
    Dim originalName As String 
    Dim counter As Integer 
     
    originalName = sheetName 
    counter = 1 
     
    ' Keep adding numbers until a unique name is found 
    While SheetExists(sheetName) 
        sheetName = originalName &"_" &counter 
        counter = counter + 1 
    Wend 
     
    EnsureUniqueSheetName = sheetName 
End Function 

Function GetUniqueValues(rng As Range) As Collection 
    ' Function to retrieve unique values from a range 
    Dim cell As Range 
    Dim uniqueValues As New Collection 
    Dim item As Variant 
     
    On Error Resume Next 
    For Each cell In rng 
        If cell.value <> "" Then 
            ' Attempt to add the item to the collection 
            uniqueValues.Add cell.value, CStr(cell.value) 
        End If 
    Next cell 
    On Error GoTo 0 
     
    Set GetUniqueValues = uniqueValues 
End Function 

Function SheetExists(sheetName As String) As Boolean 
    ' Function to check if a sheet with a given name exists 
    Dim ws As Worksheet 
    On Error Resume Next 
    Set ws = Worksheets(sheetName) 
    SheetExists = Not ws Is Nothing 
    On Error GoTo 0 
End Function 



Note: Ensure you include the supporting functions (SortArray, GetUniqueArray, CleanSheetName, EnsureUniqueSheetName, SheetExists) as they are essential for the macro to work. Include them in the same module after the main subroutine.

6. Running the VBA Macro

With the code in place, you're ready to run the macro.

Steps to Run the Macro:

  • 1. Return to Excel: Close the VBA editor to go back to your worksheet.
  • 2. Prepare Your Data: Make sure your data is formatted as an Excel Table.
  • 3. Run the Macro:
  • - Go to the Developer tab.
  • - Click Record Macro.
  • - Select Filter_Table_To_Sheets.
  • - Click Run.
  • 4. Follow the Prompts:
  • - Select Cell: The macro will prompt you to select a cell within the column you want to filter by. Ensure you select a cell in the correct column.
  • - Choose Sorting Order: Enter 1 for A-Z, 2 for Z-A, or 3 for original order.

What Happens Next?

  • - New Sheets Created: The macro creates new worksheets for each unique category.
  • - Data Copied: Filtered data is copied into the corresponding sheets.
  • - Formatting Applied: Columns are auto-fitted for better readability
  • - Confirmation: A message box confirms that the process is complete.

7. Adding a Button to the Ribbon for Easy Access

To make running the macro even easier, you can add a custom button to the Excel Ribbon.

Steps to Add a Custom Button:

  • 1. Customize the Ribbon:
  • - Right-click on the Ribbon.Select
  • - Customize the Ribbon.
  • 2. Create a New Tab:
  • - Click on New Tab.
  • - Rename it (e.g. "Custom Tools").
  • 3. Add a New Group:
  • - Under your new tab, select New Group.
  • - Rename it if desired.
  • 4. Add the Macro:
  • - In the Choose commands from dropdown, select Macros.
  • - Find your macro (PERSONAL.XLSB!Filter_Table_To_Sheets).
  • - Select your new group and click Add.
  • 5. Customize the Button:
  • - Select the macro under your new group.
  • - Click Rename.
  • - Choose an icon and set the display name (e.g., "Split Data to Sheets").
  • 6. Click OK: Your new tab with the custom button will appear in the Ribbon.

Using the Button:

  • - Simply click on your new tab.
  • - Click the custom button to run the macro anytime.
  • - Follow the prompts to select your column and choose a sorting order.

8. What Next

Now that you see how it’s possible to split an Excel table to many sheets using VBA, why not take your skills to the next level? If you’re ready to unlock the full potential of Excel, check out my online VBA course.


Over 500 students have already transformed their Excel abilities with this course, and it's received excellent reviews on Trustpilot. Whether you’re new to VBA or looking to sharpen your skills, this course is designed to help you automate your Excel tasks with confidence and ease.


Don't miss out on this opportunity to supercharge your Excel productivity. Click here to enroll and start your journey today!


Connect on YouTube, LinkedIn, Twitter.

Hi, I'm Victor!

Are you struggling with complex Excel tasks? Feeling overwhelmed by spreadsheets that are hard to use?

Many people believe mastering Excel is about learning shortcuts, functions, and formulas. But this overlooks the importance of building practical, real-world applications. It's not just about knowing the tools. It's about using them effectively.

That's where I come in. You'll get a unique perspective to Excel training from me. I have over 20 years of experience at Deloitte and two global tech companies. And I know what can make a difference in your career.

Let me help you integrate Excel into your professional life. Starting today. Read one of my articles, watch one of my videos. Then apply the new technique to your work. You'll see the difference immediately!


Download FREE Excel Workbook

Step 1: Sign up for free Click Here

Step 2: Log in for access Click Here

Step 3: Download file Excel Table Splitter (VBA).zip

Discover the PROVEN Blueprint for transforming your Excel skills, supercharging your productivity, and standing out in your career! My course helps you to learn Excel VBA and save hours of time even if you have zero prior experience with programming.

Solve tricky Excel problems and take your work to the next level! Get customized solutions for your unique needs. Save time and gain insights with truly expert Excel solutions from only $97 per task.

Get a clear overview of your project progress using the Excel project timeline. Use it to communicate the big picture, track task progress, and stay on top of your project goals. Stay organized with our project timeline!

Our cheat sheets provide quick and easy reference to commonly used Excel VBA concepts and code snippets.

Unlock new levels of productivity and efficiency with our cheat sheets, and write VBA code like a pro in no time.

RECOMMENDED READING

Are you looking to upskill and stay ahead of the curve? Excel is a powerful tool that keeps growing in demand. We round up the best online courses for learning Excel.

Are you looking to up your spreadsheet game? Excel is an invaluable tool that can help you stay organized and save time. From data analysis to budgets, Excel can do it all!

Today, having Excel skills is more critical than ever. Those who know how to use Excel are more likely to find higher-paying jobs. And get promoted faster.

JOIN FREE EMAIL NEWSLETTER

Step up your Excel game! Join our free email newsletter and get updates on how to become more awesome at Excel.