I have a rather large Excel file that has changed over time, and I want to compare all of the objects in every sheet (charts, buttons, sliders, drop-downs) from an older version to see what has been added (or removed).
Is there a way to do this using VBA?
asked Aug 27, 2015 at 17:37
2
Something like this to go through each sheet and produce a list that can be sorted by sheet, object type or object name.
Sub Dump()
Dim ws As Worksheet
Dim objFSO As Object
Dim objFile As Object
Dim Sh As Shape
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:tempsummary.csv")
objFile.writeline "Sheet, Object Type, Object name"
For Each ws In ActiveWorkbook.Sheets
For Each Sh In ws.Shapes
objFile.writeline ws.Name & "," & TypeName(Sh) & "," & Sh.Name
Next
Next
objFile.Close
End Sub
hornetbzz
9,1285 gold badges35 silver badges53 bronze badges
answered Aug 28, 2015 at 8:09
brettdjbrettdj
54.6k16 gold badges113 silver badges176 bronze badges
Yes, but not as easily as you might hope.
You can’t just loop through «all objects». Because worksheets aren’t structured that way. Worksheets have ChartObjects
ListObjects
Shapes
etc.
For each of those you could loop using
for i = 1 to activesheet.chartobjects.count
debug.print chartobjects(i).name
next i
but you’d have to check that all of those objects have a name property or else your code will throw an error.
Best advice: Google for each specific object you have E.G. «How do I loop through all charts on a worksheet» (which will lead you back to ChartObjects
). Do this for all the types of objects you have. Then you can write a for
loop for each class of object.
answered Aug 27, 2015 at 17:52
KazKaz
1,3249 silver badges20 bronze badges
3
Here’s a macro that will loop through each shape (which includes charts and dropdowns), and write the name of that object to a new line in a Text file. Note, this text file doesn’t have to exist already, it will be created automatically:
Sub test()
Dim objFSO As Object, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:Users[whatever]Documentstext.txt", 2)
objFile.Write "" 'This clears the text file
Dim obj As Shape
For Each obj In ActiveSheet.Shapes
sWrite = obj.Name & "; height: " & obj.Height & "; width: " & obj.Width
Debug.Print sWrite
objFile.WriteLine sWrite
Next obj
objFile.Close
End Sub
answered Aug 27, 2015 at 17:54
BruceWayneBruceWayne
22.8k15 gold badges64 silver badges109 bronze badges
Adding some functionality (‘NEW) I found useful to the solution provided by brettdj.
If you want to include all ListObjects in your results, try this…
Simply adds a For Each loop which prints all ListObjects (like Tables) to the .csv output:
Sub Dump()
Dim ws As Worksheet
Dim objFSO As Object
Dim objFile As Object
Dim Sh As Shape
Dim Lo As ListObject 'NEW
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:tempsummary.csv")
objFile.writeline "Sheet, Object Type, Object name"
For Each ws In ActiveWorkbook.Sheets
For Each Sh In ws.Shapes
objFile.writeline ws.Name & "," & TypeName(Sh) & "," & Sh.Name
Next
For Each Lo In ws.ListObjects 'NEW
objFile.writeline ws.Name & "," & TypeName(Lo) & "," & Lo.Name 'NEW
Next 'NEW
Next
objFile.Close
End Sub
answered Dec 29, 2020 at 18:28
Содержание
- VBA Tables and ListObjects
- Structure of a table
- Range & Data Body Range
- Header and total rows
- List columns and list rows
- Referencing the parts of a table
- Select the entire table
- Select the data within a table
- Get a value from an individual cell within a table
- Select an entire column
- Select a column (data only)
- Select a specific column header
- Select a specific column within the totals section
- Select an entire row of data
- Select the header row
- Select the totals row
- Creating and converting tables
- Convert selection to a table
- Convert a table back to a range
- Resize the range of the table
- Table styles
- Change the table style
- Get the table style name
- Apply a style to the first or last column
- Adding or removing stripes
- Set the default table style
- Looping through tables
- Loop through all tables on a worksheet
- Loop through all tables in a workbook
- Adding & removing rows and columns
- Add columns into a table
- Add rows to the bottom of a table
- Delete columns from a table
- Delete rows from a table
- Add total row to a table
- Table header visability
- Remove auto filter
- Other range techniques
- Using the union operator
- Assign values from a variant array to a table row
- Reference parts of a table using the range object
- Counting rows and columns
- Counting rows
- Counting columns
- Useful table techniques
- Show the table data entry form
- Check if a table exists
- Find out if a table has been selected, if so which
- Method 1
- Method 2
- Conclusion
- Excel vba list all objects
- VBA and VB.Net Tutorials, Education and Programming Services
- VBA List – A Powerful Tool for Processing Tables in Excel
VBA Tables and ListObjects
Tables are one of the most powerful features of Excel. Controlling them using VBA provides a way to automate that power, which generates a double benefit 🙂
Excel likes to store data within tables. The basic structural rules, such as (a) headings must be unique (b) only one header row allowed, make tables compatible with more complex tools. For example, Power Query, Power Pivot, and SharePoint lists all use tables as either a source or an output. Therefore, it is clearly Microsoft’s intention that we use tables.
However, the biggest benefit to the everyday Excel user is much simpler; if we add new data to the bottom of a table, any formulas referencing the table will automatically expand to include the new data.
Whether you love tables as much as I do or not, this post will help you automate them with VBA.
Tables, as we know them today, first appeared in Excel 2007. This was a replacement for the Lists functionality found in Excel 2003. From a VBA perspective, the document object model (DOM) did not change with the upgraded functionality. So, while we use the term ‘tables’ in Excel, they are still referred to as ListObjects within VBA.
Download the example file
I recommend you download the example file for this post. Then you’ll be able to work along with examples and see the solution in action, plus the file will be useful for future reference.
Download the file: 0009 VBA tables and ListObjects.zip
Structure of a table
Before we get deep into any VBA code, it’s useful to understand how tables are structured.
Range & Data Body Range
The range is the whole area of the table.
The data body range only includes the rows of data, it excludes the header and totals.
Header and total rows
The header row range is the top row of the table containing the column headers.
The totals row range, if displayed, includes calculations at the bottom of the table.
List columns and list rows
The individual columns are known as list columns.
Each row is known as a list row.
The VBA code in this post details how to manage all these table objects.
Referencing the parts of a table
While you may be tempted to skip this section, I recommend you read it in full and work through the examples. Understanding Excel’s document object model is the key to reading and writing VBA code. Master this, and your ability to write your own VBA code will be much higher.
Many of the examples in this first section use the select method, this is to illustrate how to reference parts of the table. In reality, you would rarely use the select method.
Select the entire table
The following macro will select the whole table, including the totals and header rows.
Select the data within a table
The DataBodyRange excludes the header and totals sections of the table.
Get a value from an individual cell within a table
The following macro retrieves the table value from row 2, column 4, and displays it in a message box.
Select an entire column
The macro below shows how to select a column by its position, or by its name.
Select a column (data only)
This is similar to the macro above, but it uses the DataBodyRange to only select the data; it excludes the headers and totals.
Select a specific column header
This macro shows how to select the column header cell of the 5th column.
Select a specific column within the totals section
This example demonstrates how to select the cell in the totals row of the 3rd column.
Select an entire row of data
The macro below selects the 3rd row of data from the table.
The following macro selects the header section of the table.
Select the totals row
To select the totals row of the table, use the following code.
OK, now we know how to reference the parts of a table, it’s time to get into some more interesting examples.
Creating and converting tables
This section of macros focuses on creating and resizing tables.
Convert selection to a table
The macro below creates a table based on the currently selected region and names it as myTable. The range is referenced as Selection.CurrentRegion, but this can be substituted for any range object.
If you’re working along with the example file, this macro will trigger an error, as a table called myTable already exists in the workbook. A new table will still be created with a default name, but the VBA code will error at the renaming step.
Convert a table back to a range
This macro will convert a table back to a standard range.
Resize the range of the table
To following macro resizes a table to cell A1 – J100.
Table styles
There are many table formatting options, the most common of which are shown below.
Change the table style
Change the style of a table to an existing pre-defined style.
To apply different table styles, the easiest method is to use the macro recorder. The recorded VBA code will include the name of any styles you select.
Get the table style name
Use the following macro to get the name of the style already applied to a table.
Apply a style to the first or last column
The first and last columns of a table can be formatted differently using the following macros.
Adding or removing stripes
By default, tables have banded rows, but there are other options for this, such as removing row banding or adding column banding.
Set the default table style
The following macro sets the default table style.
Looping through tables
The macros in this section loop through all the tables on the worksheet or workbook.
Loop through all tables on a worksheet
If we want to run a macro on every table of a worksheet, we must loop through the ListObjects collection.
In the code above, we have set the table to a variable, so we must refer to the table in the right way. In the section labeled ‘Do something to the table…, insert the action to be undertaken on each table, using tbl to reference the table.
For example, the following will change the table style of every table.
Loop through all tables in a workbook
Rather than looping through a single worksheet, as shown above, the macro below loops through every table on every worksheet.
As noted in the section above, we must refer to the table using its variable. For example, the following will display the totals row for every table.
Adding & removing rows and columns
The following macros add and remove rows, headers, and totals from a table.
Add columns into a table
The following macro adds a column to a table.
Add rows to the bottom of a table
The next macro will add a row to the bottom of a table
Delete columns from a table
To delete a column, it is necessary to use either the column index number or the column header.
Delete rows from a table
In the table structure, rows do not have names, and therefore can only be deleted by referring to the row number.
Add total row to a table
The total row at the bottom of a table can be used for calculations.
Types of totals calculation
Table headers can be turned on or off. The following will hide the headers.
Remove auto filter
The auto filter can be hidden. Please note, the table header must be visible for this code to work.
I have a separate post about controlling auto filter settings – check it out here. Most of that post applies to tables too.
Other range techniques
Other existing VBA techniques for managing ranges can also be applied to tables.
Using the union operator
To select multiple ranges, we can use VBA’s union operator. Here is an example, it will select rows 4, 1, and 3.
Assign values from a variant array to a table row
To assign values to an entire row from a variant array, use code similar to the following:
Reference parts of a table using the range object
Within VBA, a table can be referenced as if it were a standard range object.
Counting rows and columns
Often, it is useful to count the number of rows or columns. This is a good method to reference rows or columns which have been added.
Counting rows
To count the number of rows within the table, use the following macro.
Counting columns
The following macro will count the number of columns within the table.
Useful table techniques
The following are some other useful VBA codes for controlling tables.
Show the table data entry form
If a table starts at cell A1, there is a simple data entry form that can be displayed.
The following screenshot shows the data form for the example table.
Check if a table exists
The following macro checks if a table already exists within a workbook. Change the tblName variable to adapt this to your requirements.
Find out if a table has been selected, if so which
The following macros find the name of the selected table.
Method 1
As you will see in the comments Jon Peltier had an easy approach to this, which has now become my preferred approach.
Method 2
This option, which was my original method, loops through each table on the worksheet and checks if they intersect with the active cell.
Conclusion
Wow! That was a lot of code examples.
There are over 30 VBA macros above, and even this does not cover everything, but hopefully covers 99% of your requirements. For your remaining requirements, you could try Microsoft’s VBA object reference library (https://docs.microsoft.com/en-us/office/vba/api/Excel.ListObject)
About the author
Hey, I’m Mark, and I run Excel Off The Grid.
My parents tell me that at the age of 7 I declared I was going to become a qualified accountant. I was either psychic or had no imagination, as that is exactly what happened. However, it wasn’t until I was 35 that my journey really began.
In 2015, I started a new job, for which I was regularly working after 10pm. As a result, I rarely saw my children during the week. So, I started searching for the secrets to automating Excel. I discovered that by building a small number of simple tools, I could combine them together in different ways to automate nearly all my regular tasks. This meant I could work less hours (and I got pay raises!). Today, I teach these techniques to other professionals in our training program so they too can spend less time at work (and more time with their children and doing the things they love).
Do you need help adapting this post to your needs?
I’m guessing the examples in this post don’t exactly match your situation. We all use Excel differently, so it’s impossible to write a post that will meet everybody’s needs. By taking the time to understand the techniques and principles in this post (and elsewhere on this site), you should be able to adapt it to your needs.
But, if you’re still struggling you should:
- Read other blogs, or watch YouTube videos on the same topic. You will benefit much more by discovering your own solutions.
- Ask the ‘Excel Ninja’ in your office. It’s amazing what things other people know.
- Ask a question in a forum like Mr Excel, or the Microsoft Answers Community. Remember, the people on these forums are generally giving their time for free. So take care to craft your question, make sure it’s clear and concise. List all the things you’ve tried, and provide screenshots, code segments and example workbooks.
- Use Excel Rescue, who are my consultancy partner. They help by providing solutions to smaller Excel problems.
What next?
Don’t go yet, there is plenty more to learn on Excel Off The Grid. Check out the latest posts:
Источник
Excel vba list all objects
VBA and VB.Net Tutorials, Education and Programming Services
The ListObjects property of the Worksheet object returns the ListObjects collection. The ListObjects collection contains all the list objects on a worksheet. The ListObject object is a member of the ListObjects collection. Each ListObject object represents a table (previously known as a list) in the worksheet.
An Excel table typically contains related data in a series of worksheet rows and columns that have been formatted as a table. By using the table features, you can then manage the data in the table rows and columns independently from the data in other rows and columns on the worksheet.
Here is how a table (list) looks like. It can be identified by a small blue arrow at the right-most bottom-most cell of the table.
Whenever you import data from a file (Excel / Text / XML / JSON) or from a database (SQL / Access), the imported data is always in the form of a table.
You can also convert the selected range in Excel to a table by using the Format as Table option. For that simply select your data range, in the home tab, go to “Format as Table” and select the desired formatting. You will asked to confirm the selected data range and whether your table has headers. Input the data and click on OK and a table will be created.
To convert a table back to normal range, use the convert to range option. For that, click anywhere on the table, the design tab will be visible. In the design tab, click on convert to range.
Now, that we know what is a table let us look at how to use VBA to modify these tables.
Example 1: Loop through all the tables (lists) in a worksheet
The code below creates a new ListObjects collection which represents all the tables in a worksheet and displays the name of each of the table in the collection. The code along with the comments is self-explanatory.
The name of the table can be seen in the design tab. Select any cell in the table and the design tab will be shown. The name of the selected table is seen in the left side of the tab. You can edit it from here. You can also see a list of all the tables in the workbook along with their names and ranges in the Name Manager (in the Formulas tab).
Example 2: Column operations on a table
In this example we will see few of the most common operations that you can perform on the table columns. Namely, looping through all the columns of a table and printing their names, inserting columns at the end or at a specified position, deleting a particular column and copying only the data from a particular column.
Here is how the above table will look after executing the code
Example 3: Row operations
In this example let us have a look at some of the row operations in a table. As with columns, you can loop through all the rows, add and delete rows, work with totals row and header row.
This is how the original table will look like after executing the code
Did you know you can convert this table into text using VBA? Read here to find out more.
Источник
The ListObjects property of the Worksheet object returns the ListObjects collection. The ListObjects collection contains all the list objects on a worksheet. The ListObject object is a member of the ListObjects collection. Each ListObject object represents a table (previously known as a list) in the worksheet.
An Excel table typically contains related data in a series of worksheet rows and columns that have been formatted as a table. By using the table features, you can then manage the data in the table rows and columns independently from the data in other rows and columns on the worksheet.
Here is how a table (list) looks like. It can be identified by a small blue arrow at the right-most bottom-most cell of the table.
Whenever you import data from a file (Excel / Text / XML / JSON) or from a database (SQL / Access), the imported data is always in the form of a table.
You can also convert the selected range in Excel to a table by using the Format as Table option. For that simply select your data range, in the home tab, go to “Format as Table” and select the desired formatting. You will asked to confirm the selected data range and whether your table has headers. Input the data and click on OK and a table will be created.
To convert a table back to normal range, use the convert to range option. For that, click anywhere on the table, the design tab will be visible. In the design tab, click on convert to range.
Now, that we know what is a table let us look at how to use VBA to modify these tables.
Example 1: Loop through all the tables (lists) in a worksheet
The code below creates a new ListObjects collection which represents all the tables in a worksheet and displays the name of each of the table in the collection. The code along with the comments is self-explanatory.
Sub excelLists() Dim dataSheet As Worksheet Dim tableList As ListObjects Dim table As ListObject Set dataSheet = Sheet1 'create a new ListObjects collection which represents all the tables in Sheet1 Set tableList = dataSheet.ListObjects 'Loop through each table in the tableList ListObjects collection For Each table In tableList 'Display the table name MsgBox table.Name Next table End SubThe name of the table can be seen in the design tab. Select any cell in the table and the design tab will be shown. The name of the selected table is seen in the left side of the tab. You can edit it from here. You can also see a list of all the tables in the workbook along with their names and ranges in the Name Manager (in the Formulas tab).
Example 2: Column operations on a table
In this example we will see few of the most common operations that you can perform on the table columns. Namely, looping through all the columns of a table and printing their names, inserting columns at the end or at a specified position, deleting a particular column and copying only the data from a particular column.
Sub ListCols() Dim dataSheet As Worksheet Dim table As ListObject Dim tblCols As ListColumns Dim tblCol As ListColumn Dim newCol As ListColumn Set dataSheet = Sheet1 'Refer a table by it's name Set table = dataSheet.ListObjects("Table2") 'Get all the columns of a table Set tblCols = table.ListColumns 'Loop through all the columns of a table For Each tblCol In tblCols MsgBox tblCol.Name Next tblCol 'Insert a column at the last position Set newCol = tblCols.Add newCol.Name = "Last" 'Insert a column at the third position (after title) Set newCol = tblCols.Add(3) newCol.Name = "Third" 'Delete the fifth column (i.e. DOB) table.ListColumns(5).Delete 'Copy only the data in column 1 (excluding the header) 'We are pasting it in the "Last" column for demo table.ListColumns(1).DataBodyRange.Copy (Cells(3, 9)) End SubHere is how the above table will look after executing the code
Example 3: Row operations
In this example let us have a look at some of the row operations in a table. As with columns, you can loop through all the rows, add and delete rows, work with totals row and header row.
Sub excelLists() Dim dataSheet As Worksheet Dim table As ListObject Dim tblRows As ListRows Dim tblRow As ListRow Dim newRow As ListRow Set dataSheet = Sheet2 Set table = dataSheet.ListObjects("Table5") 'Get all the Rows of a table Set tblRows = table.ListRows 'Loop through all the Rows of a table For Each tblRow In tblRows 'Display the value in each row for column 1 'The row index will always start at 1, irrespective of its 'position on the worksheet MsgBox table.DataBodyRange(tblRow.Index, 1) Next tblRow 'Insert a Row at the last position tblRows.Add 'Insert a Row at the third position (excluding header row) Set newRow = tblRows.Add(3) 'Delete the fifth Row (i.e. with ID 5148) table.ListRows(5).Delete 'Display the totals row at the bottom table.ShowTotals = True 'Change color of only the header row table.HeaderRowRange.Interior.Color = vbBlue End SubThis is how the original table will look like after executing the code
Did you know you can convert this table into text using VBA? Read here to find out more.
See Also:
Excel VBA, Find and List All Files in a Directory and its Subdirectories
Guide to Dictionary Objects
What are ListObjects in VBA?
In a Table, normally, what we see is a data set. Still, in VBA terminology, there are many more such as there is the range of the total data list range. The column is known as the list column, the row as the list row, and so on. To access these properties, we have an inbuilt function known as ListObjects, used with the worksheet function.
VBA ListObject is a way of referring to the Excel tables while writing the VBA code. Using VBA LISTOBJECTS, we can create and delete tables and play around with Excel Tables in VBA code. However, Excel Tables are tricky for beginners, and even to an extent, intermediate-level users find it difficult to work with Tables. Since this article talks about referencing excel tablesIn excel, tables are a range with data in rows and columns, and they expand when new data is inserted in the range in any new row or column in the table. To use a table, click on the table and select the data range.read more in VBA coding, you should have good knowledge about Tables in Excel.
When the data converts to tables, we may no longer work with a range of cells. Rather, we need to work with table ranges. So, this article will show you how to work with Excel Tables to write VBA codesVBA code refers to a set of instructions written by the user in the Visual Basic Applications programming language on a Visual Basic Editor (VBE) to perform a specific task.read more efficiently.
Table of contents
- What are ListObjects in VBA?
- Create Table Format Using ListObjects in Excel VBA
- Formatting Excel Tables with VBA ListObjects
- Things to Remember
- Recommended Articles
You are free to use this image on your website, templates, etc, Please provide us with an attribution linkArticle Link to be Hyperlinked
For eg:
Source: VBA ListObjects (wallstreetmojo.com)
Create Table Format Using ListObjects in Excel VBA
For example, look at the below Excel data.
Using the VBA ListObject code, we will create a table format for this data.
You can download this VBA ListObjects Excel Template here – VBA ListObjects Excel Template
- For this data, first, we need to find the last used row and column, so define two variables to find this.
Code:
Sub List_Objects_Example1() Dim LR As Long Dim LC As Long End Sub
- To find the last used row and column use the below code.
Code:
LR = Cells(Rows.Count, 1).End(xlUp).Row LC = Cells(1, Columns.Count).End(xlToLeft).Column
- Now define one more variable to hold the reference of the data.
Code:
Dim Rng As Range
- Now set the reference to this variable by using the below code.
Code:
Set Rng = Cells(1, 1).Resize(LR, LC)
We need to use the VBA “ListObject.Add” method to create a table; below is the same syntax.
ListObject.Add (Source, XlListObjectHasHeaders, Destination, TableStyleName)
Source: TThis is nothing for which range of cells we are inserting the table. So we can supply two arguments here, i.e., “xlSrcRange” and “xlSrcExternal.”
XlListObjectHasHeaders: If the table inserting data has headers or not. If yes, we can provide “xlYes.” If not, we can provide “xlNo.”
Destination: This is nothing but our data range.
Table Style: We can provide styles if you want to apply any table style.
- Now in the active sheet, we are creating the table, so the below code would create a table for us.
Code:
Dim Ws As Worksheet Set Ws = ActiveSheet Ws.ListObjects.Add xlSrcRange, xllistobjecthasheaders:=xlYes, Destination:=Rng
- After this, we need to give a name to this table.
Code:
Ws.ListObjects(1).name = "EmpTable"
- Below is the full code for your reference.
Code:
Sub List_Objects_Example1() Dim LR As Long Dim LC As Long LR = Cells(Rows.Count, 1).End(xlUp).Row LC = Cells(1, Columns.Count).End(xlToLeft).Column Dim Rng As Range Set Rng = Cells(1, 1).Resize(LR, LC) Dim Ws As Worksheet Set Ws = ActiveSheet Ws.ListObjects.Add xlSrcRange, xllistobjecthasheaders:=xlYes, Destination:=Rng Ws.ListObjects(1).name = "EmpTable" End Sub
Let us run the code and see the magic.
It has created the table to the mentioned data and given the table name “EmpTable.”
Formatting Excel Tables with VBA ListObjects
Once we create the Excel table, we can work with tables using the VBA ListObject collection.
- First, define the variable as “ListObject.”
Code:
Sub List_Objects_Example2() Dim MyTable As ListObject End Sub
- Now, set the reference to this variable by using the table name.
Code:
Sub List_Objects_Example2() Dim MyTable As ListObject Set MyTable = ActiveSheet.ListObjects("EmpTable") End Sub
Now, the variable “MyTable” holds the reference for the table “EmpTable.”
- Enter the variable name and put a dot to see the properties and methods of the VBA ListObject.
For example, if we want to select the entire table, then we need to use the “Range” object, and under this, we need to use the “Select” method.
Code:
MyTable.Range.Select
It would select the entire data table, including the heading.
- If you want to select only the table contents without headers, we need to use “DataBodyRange.”
Code:
MyTable.DataBodyRange.Select
Like this, we can play around with tables.
- Below is the list of activity codes for your reference.
Code:
Sub List_Objects_Example2() Dim MyTable As ListObject Set MyTable = ActiveSheet.ListObjects("EmpTable") MyTable.DataBodyRange.Select 'To Select data range without headers MyTable.Range.Select 'To Select data range with headers MyTable.HeaderRowRange.Select 'To Select table header rows MyTable.ListColumns(2).Range.Select 'To select column 2 including header MyTable.ListColumns(2).DataBodyRange.Select 'To select column 2 without header End Sub
Like this, we can use the “ListObject” collection to play around with Excel tables.
Things to Remember
- VBA ListObject is the collection of objects to reference excel tables.
- To access the ListObject collection, we need to specify what worksheet we are referring to.
Recommended Articles
This article has been a guide to VBA ListObject. Here, we discuss how to use the VBA ListObject.Add method to create a table in Excel using examples downloadable Excel sheet. You can learn more from the following VBA articles: –
- VBA Find Next
- VBA Object Required
- CreateObject in VBA
- GetObject in VBA
All About The Tables
For a data analyst, Excel Tables are a necessity! They are the most efficient way to organize your raw data and refer to data that contracts or expands on a regular basis. Likewise, Excel tables can be extremely useful in combination with VBA.
I personally use data tables as a way to store user settings without having to modify any VBA code. You can see examples of this in my Exporter Template where I use tables to store worksheet names and email addresses.
In this article, I wanted to bring all the common ways of referencing table data with VBA into one place. Hopefully, this will serve as a guide you can come back to again and again so you can easily and efficiently incorporate tables into your VBA macro coding. Enjoy!
Section Quick Links
-
Excel Tables Overview
-
Selecting Areas Of A Table With VBA
-
Inserting Rows and Columns Into The Table
-
Deleting Parts Of A Table
-
Deleting/Clearing The Data In A Table
-
Loop Through Each Table Column Or Row
-
Looking Up Values Within A Table
-
Apply A Sort Order To A Table Column
-
Reading Table Data Into An Array Variable
-
Resizing A Table
-
Change All Table Column’s Total Row Calculations
-
Getting To The ActiveTable
-
Additional Articles
Excel Tables Overview
What Is A Table?
A Table is simply a structured range where you can refer to different sections that are automatically mapped out (such as the Header Row or the column below the header «Amount»). Tables are an amazing feature that Microsoft added into Excel because they not only structure your data, but they also expand with your data as it grows. And if there is one thing you should know about creating a spreadsheet, it would be that making it as DYNAMIC as possible is always a good thing!
You can quickly create a Table by highlighting a range (with proper headings) and using the keyboard shortcut Ctrl + t. You can also navigate to the Insert tab and select the Table button within the Tables group.
The Parts of A Table
The below infographic will help you visualize the different parts of a Table object through the lens of the VBA coding language.
These parts of a ListObject Table include:
-
Range
-
HeaderRowRange
-
DataBodyRange
-
ListRows
-
ListColumns
-
TotalsRowRange
How Do I Find Existing Tables?
Tables can be a little tricky to find if you are not familiar working with them because they can blend in very well with the spreadsheet depending on the formatting that has been applied.
Let’s look at 4 different ways you can determine if you are working with cells in a Table Object.
1. The Table Design Tab Appears
If you click within a cell that is part of an Excel Table, you will immediately see the Table Design tab appear in the Ribbon. This is a contextual tab, which means it only appears when a specific object is selected on your spreadsheet (a similar tab appears when Pivot Tables or Shapes are selected on a spreadsheet).
This is a very quick tell-tail sign that the cell you are working on is part of a Table Object.
2. The Blue Corner Indicator
There is a small little indicator at the bottom right cell of a Table range to indicate there is a table. As you can see in the image below, this indicator can be very simple to find, but also can be easily missed due to its small size!
3. Use Excel’s Name Manager
Another great way to find a table (and its name) is to go into the Name Manager. You can get to the name manager by navigating to the Formulas tab and clicking the Name Manager button inside the Defined Names group.
By using the Filter menu in the right-hand corner of the Name Manager, you can narrow down your name list to just the Tables within the Workbook. The Name Manager will show you exactly where the tables are within the spreadsheet and also what the Table names are.
4. VBA Code To Check If Cell Is In A ListObject Table
There may be instances when you need to determine if a certain cell resides within a ListObject (Table). The below VBA code shows you how you can perform a test to see if the ActiveCell (selected cell) is part of any Excel Table on the spreadsheet.
Sub IsActiveCellInTable()
‘PURPOSE: Determine if the current selected cell is part of an Excel Table
‘SOURCE: www.TheSpreadsheetGuru.com
Dim TestForTable As String
‘Test To See If Cell Is Within A Table
On Error Resume Next
TestForTable = ActiveCell.ListObject.Name
On Error GoTo 0
‘Determine Results of Test
If TestForTable <> «» Then
‘ActiveCell is within a ListObject Table
MsgBox «Cell is part of the table named: » & TestForTable
Else
‘ActiveCell is NOT within a ListObject Table
MsgBox «Cell is not part of any table»
End If
End Sub
This is a great validation test if you are creating code that allows the user to manipulate an excel table. I’ve used this many times to create buttons that allow users to insert or delete specific rows within a table based on where they select on a password protected sheet.
Selecting Areas of a Table with VBA
Select | VBA Coding |
---|---|
Entire Table | ActiveSheet.ListObjects(«Table1»).Range.Select |
Table Header Row | ActiveSheet.ListObjects(«Table1»).HeaderRowRange.Select |
Table Data | ActiveSheet.ListObjects(«Table1»).DataBodyRange.Select |
Third Column | ActiveSheet.ListObjects(«Table1»).ListColumns(3).Range.Select |
Third Column (Data Only) | ActiveSheet.ListObjects(«Table1»).ListColumns(3).DataBodyRange.Select |
Select Row 4 of Table Data | ActiveSheet.ListObjects(«Table1»).ListRows(4).Range.Select |
Select 3rd Heading | ActiveSheet.ListObjects(«Table1»).HeaderRowRange(3).Select |
Select Data point in Row 3, Column 2 | ActiveSheet.ListObjects(«Table1»).DataBodyRange(3, 2).Select |
Subtotals | ActiveSheet.ListObjects(«Table1»).TotalsRowRange.Select |
Inserting Rows and Columns into the Table
Select | VBA Coding |
---|---|
Insert A New Column 4 | ActiveSheet.ListObjects(«Table1»).ListColumns.Add Position:=4 |
Insert Column at End of Table | ActiveSheet.ListObjects(«Table1»).ListColumns.Add |
Insert Row Above Row 5 | ActiveSheet.ListObjects(«Table1»).ListRows.Add (5) |
Add Row To Bottom of Table | ActiveSheet.ListObjects(«Table1»).ListRows.Add AlwaysInsert:= True |
Add Totals Row | ActiveSheet.ListObjects(«Table1»).ShowTotals = True |
Deleting Various Parts Of A Table
Sub RemovePartsOfTable()
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Remove 3rd Column
tbl.ListColumns(3).Delete
‘Remove 4th DataBody Row
tbl.ListRows(4).Delete
‘Remove 3rd through 5th DataBody Rows
tbl.Range.Rows(«3:5»).Delete
‘Remove Totals Row
tbl.TotalsRowRange.Delete
End Sub
Deleting/Clearing The Data In A Table
Delete all data rows from a table (except the first row)
Sub ResetTable()
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Delete all table rows except first row
With tbl.DataBodyRange
If .Rows.Count > 1 Then
.Offset(1, 0).Resize(.Rows.Count — 1, .Columns.Count).Rows.Delete
End If
End With
‘Clear out data from first table row
tbl.DataBodyRange.Rows(1).ClearContents
End Sub
If you have formulas in your table, you may want to keep those intact. The following modification will just remove constant values from the remaining first row in the Table Object.
Sub ResetTable()
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Delete all table rows except first row
With tbl.DataBodyRange
If .Rows.Count > 1 Then
.Offset(1, 0).Resize(.Rows.Count — 1, .Columns.Count).Rows.Delete
End If
End With
‘Clear out data from first table row (retaining formulas)
tbl.DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
End Sub
Loop Through Each Table Column Or Row
Sub LoopingThroughTable()
Dim tbl As ListObject
Dim x As Long
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Loop Through Each Column in Table
For x = 1 To tbl.ListColumns.Count
tbl.ListColumns(x).Range.ColumnWidth = 8
Next x
‘Loop Through Every Row in Table
For x = 1 To tbl.Range.Rows.Count
tbl.Range.Rows(x).RowHeight = 20
Next x
‘Loop Through Each DataBody Row in Table
For x = 1 To tbl.ListRows.Count
tbl.ListRows(x).Range.RowHeight = 15
Next x
End Sub
Apply Sort To Column In A Table
You may find yourself needing to sort your Table data in either Ascending or Descending order. The following VBA code will show you how to sort a column in your ListObject Table in either order.
Sub SortTableColumn()
‘PUPOSE: Sort Table in Ascending/Descending Order
‘SOURCE: www.TheSpreadsheetGuru.com
Dim tbl As ListObject
Dim SortOrder As Integer
‘Choose Sort Order
SortOrder = xlAscending ‘(or xlDescending)
‘Store Desired Excel Table to a variable
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Clear Any Prior Sorting
tbl.Sort.SortFields.Clear
‘Apply A Sort on Column 1 of Table
tbl.Sort.SortFields.Add2 _
Key:=tbl.ListColumns(1).Range, _
SortOn:=xlSortOnValues, _
Order:=SortOrder, _
DataOption:=xlSortNormal
‘Sort Options (if you want to change from default)
tbl.Sort.Header = xlYes
tbl.Sort.MatchCase = False
tbl.Sort.Orientation = xlTopToBottom
tbl.Sort.SortMethod = xlPinYin
‘Apply the Sort to the Table
tbl.Sort.Apply
End Sub
While the above VBA code has all the potential options written out for you to tweak, most of the time you will not need to stray away from the default sorting options.
Below is the same code, but with all the options you likely don’t need to change from their default setting value removed.
Sub SortTableColumn_Simple()
‘PUPOSE: Sort Table in Ascending/Descending Order
‘SOURCE: www.TheSpreadsheetGuru.com
Dim tbl As ListObject
Dim SortOrder As Integer
‘Choose Sort Order
SortOrder = xlDescending ‘(or xlAscending)
‘Store Desired Excel Table to a variable
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Clear Any Prior Sorting
tbl.Sort.SortFields.Clear
‘Apply A Sort on Column 1 of Table
tbl.Sort.SortFields.Add2 _
Key:=tbl.ListColumns(1).Range, _
Order:=SortOrder
‘Apply the Sort to the Table
tbl.Sort.Apply
End Sub
Looking Up Values Within A Table
If you are storing values inside a Table, there may be scenarios where you wish to look up or find a value. There are many different lookup scenarios one might have, but for simplicity, I will provide a generic example. The following code looks to find an ID string within a specific table’s first column and returns that ID’s table row number. Hopefully, you can use the logic within this example and apply it to your specific needs.
Sub LookupTableValue()
Dim tbl As ListObject
Dim FoundCell As Range
Dim LookupValue As String
‘Lookup Value
LookupValue = «ID-123»
‘Store Table Object to a variable
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘Attempt to find value in Table’s first Column
On Error Resume Next
Set FoundCell = tbl.DataBodyRange.Columns(1).Find(LookupValue, LookAt:=xlWhole)
On Error GoTo 0
‘Return Table Row number if value is found
If Not FoundCell Is Nothing Then
MsgBox «Found in table row: » & _
tbl.ListRows(FoundCell.Row — tbl.HeaderRowRange.Row).Index
Else
MsgBox «Value not found»
End If
End Sub
Store Table Data In An Array Variable
Pulling in data from tables is a great tactic to incorporate in your VBA coding. Tables are ideal because they:
-
Are always structured the same
-
Can be moved anywhere on the spreadsheet without affecting your code
-
Automatically adjust their range size
One example of using Tables as a data source in a macro is shown in one of my Code Vault snippets which allows you to filter your data based on the words in a specified table. There are tons of different ways you can use tables to store settings and preferences dynamically for your macros. The below code shows you how to load in data from a single column and a multi-column table.
Single Column Table
Sub SingleColumnTable_To_Array()
Dim myTable As ListObject
Dim myArray As Variant
Dim TempArray As Variant
Dim x As Long
‘Set path for Table variable
Set myTable = ActiveSheet.ListObjects(«Table1»)
‘Create Array List from Table
TempArray = myTable.DataBodyRange
‘Convert from vertical to horizontal array list
myArray = Application.Transpose(TempArray)
‘Loop through each item in the Table Array (displayed in Immediate Window [ctrl + g])
For x = LBound(myArray) To UBound(myArray)
Debug.Print myArray(x)
Next x
End Sub
Multiple Column Table
Sub MultiColumnTable_To_Array()
Dim myTable As ListObject
Dim myArray As Variant
Dim x As Long
‘Set path for Table variable
Set myTable = ActiveSheet.ListObjects(«Table1»)
‘Create Array List from Table
myArray = myTable.DataBodyRange
‘Loop through each item in Third Column of Table (displayed in Immediate Window [ctrl + g])
For x = LBound(myArray) To UBound(myArray)
Debug.Print myArray(x, 3)
Next x
End Sub
Resizing A Table
If needed, you can resize a table’s dimensions by declaring a new range area for the Excel table to shrink or expand. Below are a couple of examples showing how you can perform this sort of size adjustment.
(A special thanks to Peter Bartholomew for requesting this on LinkedIn)
Sub ResizeTable()
Dim rng As Range
Dim tbl As ListObject
‘Resize Table to 7 rows and 5 columns
Set rng = Range(«Table1[#All]»).Resize(7, 5)
ActiveSheet.ListObjects(«Table1»).Resize rng
‘Expand Table size by 10 rows
Set tbl = ActiveSheet.ListObjects(«Table1»)
Set rng = Range(tbl.Name & «[#All]»).Resize(tbl.Range.Rows.Count + 10, tbl.Range.Columns.Count)
tbl.Resize rng
End Sub
Change All Table Total Row Calculations
Sub ChangeAllColumnTotals()
Dim tbl As ListObject
Dim CalcType As Integer
Dim x As Long
Set tbl = ActiveSheet.ListObjects(«Table1»)
‘What calculation should the Totals Row Have?
CalcType = 1 ‘or: xlTotalsCalculationSum
‘Loop Through All Table Columns
For x = 1 To tbl.ListColumns.Count
tbl.ListColumns(x).TotalsCalculation = CalcType
Next x
‘___________________________________________
‘Members of xlTotalsCalculation
‘Enum Calculation
‘ 0 None
‘ 1 Sum
‘ 2 Average
‘ 3 Count
‘ 4 Count Numbers
‘ 5 Min
‘ 6 Max
‘ 7 Std Deviation
‘ 8 Var
‘ 9 Custom
‘___________________________________________
End Sub
Getting the ActiveTable
There may be instances where you want to make a personal macro that formats your selected table in a certain way or adds certain calculation columns. Since the Excel developers didn’t create an ActiveTable command in their VBA language, you have no straightforward way of manipulating a user-selected table. But with a little creativity, you can make your own ActiveTable ListObject variable and do whatever you want with the selected table!
Sub DetermineActiveTable()
Dim SelectedCell As Range
Dim TableName As String
Dim ActiveTable As ListObject
Set SelectedCell = ActiveCell
‘Determine if ActiveCell is inside a Table
On Error GoTo NoTableSelected
TableName = SelectedCell.ListObject.Name
Set ActiveTable = ActiveSheet.ListObjects(TableName)
On Error GoTo 0
‘Do something with your table variable (ie Add a row to the bottom of the ActiveTable)
ActiveTable.ListRows.Add AlwaysInsert:=True
Exit Sub
‘Error Handling
NoTableSelected:
MsgBox «There is no Table currently selected!», vbCritical
End Sub
Visual Learner? Download My Example Workbook
Screenshot from one of the tabs in the downloadable file
After many requests, I put together a fun little interactive workbook that will show you how a bunch of the code described in this article actually works on a spreadsheet. It also serves as a good reference that you can save to your computer so you don’t have to keep googling about Excel Tables whenever something slips your mind.
Download Example Excel File
If you would like to get a copy of the Excel file I used throughout this article, feel free to directly download the spreadsheet by clicking the download button below.
Anything Else About Tables I Missed?
Did you come to this page trying to find out how to do something with VBA and Excel tables and it wasn’t covered? If that is the case, let me know what you were looking for in the comment section below. If it makes sense to add it to this guide and will definitely add it to the content. I look forward to reading your thoughts and/or recommendations!
About The Author
Hey there! I’m Chris and I run TheSpreadsheetGuru website in my spare time. By day, I’m actually a finance professional who relies on Microsoft Excel quite heavily in the corporate world. I love taking the things I learn in the “real world” and sharing them with everyone here on this site so that you too can become a spreadsheet guru at your company.
Through my years in the corporate world, I’ve been able to pick up on opportunities to make working with Excel better and have built a variety of Excel add-ins, from inserting tickmark symbols to automating copy/pasting from Excel to PowerPoint. If you’d like to keep up to date with the latest Excel news and directly get emailed the most meaningful Excel tips I’ve learned over the years, you can sign up for my free newsletters. I hope I was able to provide you some value today and hope to see you back here soon! — Chris
Tables are one of the most powerful features of Excel. Controlling them using VBA provides a way to automate that power, which generates a double benefit 🙂
Excel likes to store data within tables. The basic structural rules, such as (a) headings must be unique (b) only one header row allowed, make tables compatible with more complex tools. For example, Power Query, Power Pivot, and SharePoint lists all use tables as either a source or an output. Therefore, it is clearly Microsoft’s intention that we use tables.
However, the biggest benefit to the everyday Excel user is much simpler; if we add new data to the bottom of a table, any formulas referencing the table will automatically expand to include the new data.
Whether you love tables as much as I do or not, this post will help you automate them with VBA.
Tables, as we know them today, first appeared in Excel 2007. This was a replacement for the Lists functionality found in Excel 2003. From a VBA perspective, the document object model (DOM) did not change with the upgraded functionality. So, while we use the term ‘tables’ in Excel, they are still referred to as ListObjects within VBA.
Download the example file
I recommend you download the example file for this post. Then you’ll be able to work along with examples and see the solution in action, plus the file will be useful for future reference.
Download the file: 0009 VBA tables and ListObjects.zip
Structure of a table
Before we get deep into any VBA code, it’s useful to understand how tables are structured.
Range & Data Body Range
The range is the whole area of the table.
The data body range only includes the rows of data, it excludes the header and totals.
Header and total rows
The header row range is the top row of the table containing the column headers.
The totals row range, if displayed, includes calculations at the bottom of the table.
List columns and list rows
The individual columns are known as list columns.
Each row is known as a list row.
The VBA code in this post details how to manage all these table objects.
Referencing the parts of a table
While you may be tempted to skip this section, I recommend you read it in full and work through the examples. Understanding Excel’s document object model is the key to reading and writing VBA code. Master this, and your ability to write your own VBA code will be much higher.
Many of the examples in this first section use the select method, this is to illustrate how to reference parts of the table. In reality, you would rarely use the select method.
Select the entire table
The following macro will select the whole table, including the totals and header rows.
Sub SelectTable() ActiveSheet.ListObjects("myTable").Range.Select End Sub
Select the data within a table
The DataBodyRange excludes the header and totals sections of the table.
Sub SelectTableData() ActiveSheet.ListObjects("myTable").DataBodyRange.Select End Sub
Get a value from an individual cell within a table
The following macro retrieves the table value from row 2, column 4, and displays it in a message box.
Sub GetValueFromTable() MsgBox ActiveSheet.ListObjects("myTable").DataBodyRange(2, 4).value End Sub
Select an entire column
The macro below shows how to select a column by its position, or by its name.
Sub SelectAnEntireColumn() 'Select column based on position ActiveSheet.ListObjects("myTable").ListColumns(2).Range.Select 'Select column based on name ActiveSheet.ListObjects("myTable").ListColumns("Category").Range.Select End Sub
Select a column (data only)
This is similar to the macro above, but it uses the DataBodyRange to only select the data; it excludes the headers and totals.
Sub SelectColumnData() 'Select column data based on position ActiveSheet.ListObjects("myTable").ListColumns(4).DataBodyRange.Select 'Select column data based on name ActiveSheet.ListObjects("myTable").ListColumns("Category").DataBodyRange.Select End Sub
Select a specific column header
This macro shows how to select the column header cell of the 5th column.
Sub SelectCellInHeader() ActiveSheet.ListObjects("myTable").HeaderRowRange(5).Select End Sub
Select a specific column within the totals section
This example demonstrates how to select the cell in the totals row of the 3rd column.
Sub SelectCellInTotal() ActiveSheet.ListObjects("myTable").TotalsRowRange(3).Select End Sub
Select an entire row of data
The macro below selects the 3rd row of data from the table.
NOTE – The header row is not included as a ListRow. Therefore, ListRows(3) is the 3rd row within the DataBodyRange, and not the 3rd row from the top of the table.
Sub SelectRowOfData() ActiveSheet.ListObjects("myTable").ListRows(3).Range.Select End Sub
Select the header row
The following macro selects the header section of the table.
Sub SelectHeaderSection() ActiveSheet.ListObjects("myTable").HeaderRowRange.Select End Sub
Select the totals row
To select the totals row of the table, use the following code.
Sub SelectTotalsSection() ActiveSheet.ListObjects("myTable").TotalsRowRange.Select End Sub
OK, now we know how to reference the parts of a table, it’s time to get into some more interesting examples.
Creating and converting tables
This section of macros focuses on creating and resizing tables.
Convert selection to a table
The macro below creates a table based on the currently selected region and names it as myTable. The range is referenced as Selection.CurrentRegion, but this can be substituted for any range object.
If you’re working along with the example file, this macro will trigger an error, as a table called myTable already exists in the workbook. A new table will still be created with a default name, but the VBA code will error at the renaming step.
Sub ConvertRangeToTable() tableName As String Dim tableRange As Range Set tableName = "myTable" Set tableRange = Selection.CurrentRegion ActiveSheet.ListObjects.Add(SourceType:=xlSrcRange, _ Source:=tableRange, _ xlListObjectHasHeaders:=xlYes _ ).Name = tableName End Sub
Convert a table back to a range
This macro will convert a table back to a standard range.
Sub ConvertTableToRange() ActiveSheet.ListObjects("myTable").Unlist End Sub
NOTE – Unfortunately, when converting a table to a standard range, the table formatting is not removed. Therefore, the cells may still look like a table, even when they are not – that’s frustrating!!!
Resize the range of the table
To following macro resizes a table to cell A1 – J100.
Sub ResizeTableRange() ActiveSheet.ListObjects("myTable").Resize Range("$A$1:$J$100") End Sub
Table styles
There are many table formatting options, the most common of which are shown below.
Change the table style
Change the style of a table to an existing pre-defined style.
Sub ChangeTableStyle() ActiveSheet.ListObjects("myTable").TableStyle = "TableStyleLight15" End Sub
To apply different table styles, the easiest method is to use the macro recorder. The recorded VBA code will include the name of any styles you select.
Get the table style name
Use the following macro to get the name of the style already applied to a table.
Sub GetTableStyleName() MsgBox ActiveSheet.ListObjects("myTable").TableStyle End Sub
Apply a style to the first or last column
The first and last columns of a table can be formatted differently using the following macros.
Sub ColumnStyles() 'Apply special style to first column ActiveSheet.ListObjects("myTable").ShowTableStyleFirstColumn = True 'Apply special style to last column ActiveSheet.ListObjects("myTable").ShowTableStyleLastColumn = True End Sub
Adding or removing stripes
By default, tables have banded rows, but there are other options for this, such as removing row banding or adding column banding.
Sub ChangeStripes() 'Apply column stripes ActiveSheet.ListObjects("myTable").ShowTableStyleColumnStripes = True 'Remove row stripes ActiveSheet.ListObjects("myTable").ShowTableStyleRowStripes = False End Sub
Set the default table style
The following macro sets the default table style.
Sub SetDefaultTableStyle() 'Set default table style ActiveWorkbook.DefaultTableStyle = "TableStyleMedium2" End Sub
Looping through tables
The macros in this section loop through all the tables on the worksheet or workbook.
Loop through all tables on a worksheet
If we want to run a macro on every table of a worksheet, we must loop through the ListObjects collection.
Sub LoopThroughAllTablesWorksheet() 'Create variables to hold the worksheet and the table Dim ws As Worksheet Dim tbl As ListObject Set ws = ActiveSheet 'Loop through each table in worksheet For Each tbl In ws.ListObjects 'Do something to the Table.... Next tbl End Sub
In the code above, we have set the table to a variable, so we must refer to the table in the right way. In the section labeled ‘Do something to the table…, insert the action to be undertaken on each table, using tbl to reference the table.
For example, the following will change the table style of every table.
tbl.TableStyle = "TableStyleLight15"
Loop through all tables in a workbook
Rather than looping through a single worksheet, as shown above, the macro below loops through every table on every worksheet.
Sub LoopThroughAllTablesWorkbook() 'Create variables to hold the worksheet and the table Dim ws As Worksheet Dim tbl As ListObject 'Loop through each worksheet For Each ws In ActiveWorkbook.Worksheets 'Loop through each table in worksheet For Each tbl In ws.ListObjects 'Do something to the Table.... Next tbl Next ws End Sub
As noted in the section above, we must refer to the table using its variable. For example, the following will display the totals row for every table.
tbl.ShowTotals = True
Adding & removing rows and columns
The following macros add and remove rows, headers, and totals from a table.
Add columns into a table
The following macro adds a column to a table.
Sub AddColumnToTable() 'Add column at the end ActiveSheet.ListObjects("myTable").ListColumns.Add 'Add column at position 2 ActiveSheet.ListObjects("myTable").ListColumns.Add Position:=2 End Sub
Add rows to the bottom of a table
The next macro will add a row to the bottom of a table
Sub AddRowsToTable() 'Add row at bottom ActiveSheet.ListObjects("myTable").ListRows.Add 'Add row at the first row ActiveSheet.ListObjects("myTable").ListRows.Add Position:=1 End Sub
Delete columns from a table
To delete a column, it is necessary to use either the column index number or the column header.
Sub DeleteColumnsFromTable() 'Delete column 2 ActiveSheet.ListObjects("myTable").ListColumns(2).Delete 'Delete a column by name ActiveSheet.ListObjects("myTable").ListColumns("Feb").Delete End Sub
Delete rows from a table
In the table structure, rows do not have names, and therefore can only be deleted by referring to the row number.
Sub DeleteRowsFromTable() 'Delete row 2 ActiveSheet.ListObjects("myTable").ListRows(2).Delete 'Delete multiple rows ActiveSheet.ListObjects("myTable").Range.Rows("4:6").Delete End Sub
Add total row to a table
The total row at the bottom of a table can be used for calculations.
Sub AddTotalRowToTable() 'Display total row with value in last column ActiveSheet.ListObjects("myTable").ShowTotals = True 'Change the total for the "Total Column" to an average ActiveSheet.ListObjects("myTable").ListColumns("TotalColumn").TotalsCalculation = _ xlTotalsCalculationAverage 'Totals can be added by position, rather than name ActiveSheet.ListObjects("myTable").ListColumns(2).TotalsCalculation = _ xlTotalsCalculationAverage End Sub
Types of totals calculation
xlTotalsCalculationNone xlTotalsCalculationAverage xlTotalsCalculationCount xlTotalsCalculationCountNums xlTotalsCalculationMax xlTotalsCalculationMin xlTotalsCalculationSum xlTotalsCalculationStdDev xlTotalsCalculationVar
Table header visability
Table headers can be turned on or off. The following will hide the headers.
Sub ChangeTableHeader() ActiveSheet.ListObjects("myTable").ShowHeaders = False End Sub
Remove auto filter
The auto filter can be hidden. Please note, the table header must be visible for this code to work.
Sub RemoveAutoFilter() ActiveSheet.ListObjects("myTable").ShowAutoFilterDropDown = False End Sub
I have a separate post about controlling auto filter settings – check it out here. Most of that post applies to tables too.
Other range techniques
Other existing VBA techniques for managing ranges can also be applied to tables.
Using the union operator
To select multiple ranges, we can use VBA’s union operator. Here is an example, it will select rows 4, 1, and 3.
Sub SelectMultipleRangesUnionOperator() Union(ActiveSheet.ListObjects("myTable").ListRows(4).Range, _ ActiveSheet.ListObjects("myTable").ListRows(1).Range, _ ActiveSheet.ListObjects("myTable").ListRows(3).Range).Select End Sub
Assign values from a variant array to a table row
To assign values to an entire row from a variant array, use code similar to the following:
Sub AssignValueToTableFromArray() 'Assing values to array (for illustration) Dim myArray As Variant myArray = Range("A2:D2") 'Assign values in array to the table ActiveSheet.ListObjects("myTable").ListRows(2).Range.Value = myArray End Sub
Reference parts of a table using the range object
Within VBA, a table can be referenced as if it were a standard range object.
Sub SelectTablePartsAsRange() ActiveSheet.Range("myTable[Category]").Select End Sub
Counting rows and columns
Often, it is useful to count the number of rows or columns. This is a good method to reference rows or columns which have been added.
Counting rows
To count the number of rows within the table, use the following macro.
Sub CountNumberOfRows() Msgbox ActiveSheet.ListObjects("myTable").ListRows.Count End Sub
Counting columns
The following macro will count the number of columns within the table.
Sub CountNumberOfColumns() Msgbox ActiveSheet.ListObjects("myTable").ListColumns.Count End Sub
Useful table techniques
The following are some other useful VBA codes for controlling tables.
Show the table data entry form
If a table starts at cell A1, there is a simple data entry form that can be displayed.
Sub ShowDataEntryForm() 'Only works if Table starts at Cell A1 ActiveSheet.ShowDataForm End Sub
The following screenshot shows the data form for the example table.
Check if a table exists
The following macro checks if a table already exists within a workbook. Change the tblName variable to adapt this to your requirements.
Sub CheckIfTableExists() 'Create variables to hold the worksheet and the table Dim ws As Worksheet Dim tbl As ListObject Dim tblName As String Dim tblExists As Boolean tblName = "myTable" 'Loop through eac worksheet For Each ws In ActiveWorkbook.Worksheets 'Loop through each table in worksheet For Each tbl In ws.ListObjects If tbl.Name = tblName Then tblExists = True End If Next tbl Next ws If tblExists = True Then MsgBox "Table " & tblName & " exists." Else MsgBox "Table " & tblName & " does not exists." End If End Sub
Find out if a table has been selected, if so which
The following macros find the name of the selected table.
Method 1
As you will see in the comments Jon Peltier had an easy approach to this, which has now become my preferred approach.
Sub SimulateActiveTable() Dim ActiveTable As ListObject On Error Resume Next Set ActiveTable = ActiveCell.ListObject On Error GoTo 0 'Confirm if a cell is in a Table If ActiveTable Is Nothing Then MsgBox "Select table and try again" Else MsgBox "The active cell is in a Table called: " & ActiveTable.Name End If End Sub
Method 2
This option, which was my original method, loops through each table on the worksheet and checks if they intersect with the active cell.
Sub SimulateActiveTable_Method2() Dim ActiveTable As ListObject Dim tbl As ListObject 'Loop through each table, check if table intersects with active cell For Each tbl In ActiveSheet.ListObjects If Not Intersect(ActiveCell, tbl.Range) Is Nothing Then Set ActiveTable = tbl MsgBox "The active cell is in a Table called: " & ActiveTable.Name End If Next tbl 'If no intersection then no tabl selected If ActiveTable Is Nothing Then MsgBox "Select an Excel table and try again" End If End Sub
Conclusion
Wow! That was a lot of code examples.
There are over 30 VBA macros above, and even this does not cover everything, but hopefully covers 99% of your requirements. For your remaining requirements, you could try Microsoft’s VBA object reference library (https://docs.microsoft.com/en-us/office/vba/api/Excel.ListObject)
About the author
Hey, I’m Mark, and I run Excel Off The Grid.
My parents tell me that at the age of 7 I declared I was going to become a qualified accountant. I was either psychic or had no imagination, as that is exactly what happened. However, it wasn’t until I was 35 that my journey really began.
In 2015, I started a new job, for which I was regularly working after 10pm. As a result, I rarely saw my children during the week. So, I started searching for the secrets to automating Excel. I discovered that by building a small number of simple tools, I could combine them together in different ways to automate nearly all my regular tasks. This meant I could work less hours (and I got pay raises!). Today, I teach these techniques to other professionals in our training program so they too can spend less time at work (and more time with their children and doing the things they love).
Do you need help adapting this post to your needs?
I’m guessing the examples in this post don’t exactly match your situation. We all use Excel differently, so it’s impossible to write a post that will meet everybody’s needs. By taking the time to understand the techniques and principles in this post (and elsewhere on this site), you should be able to adapt it to your needs.
But, if you’re still struggling you should:
- Read other blogs, or watch YouTube videos on the same topic. You will benefit much more by discovering your own solutions.
- Ask the ‘Excel Ninja’ in your office. It’s amazing what things other people know.
- Ask a question in a forum like Mr Excel, or the Microsoft Answers Community. Remember, the people on these forums are generally giving their time for free. So take care to craft your question, make sure it’s clear and concise. List all the things you’ve tried, and provide screenshots, code segments and example workbooks.
- Use Excel Rescue, who are my consultancy partner. They help by providing solutions to smaller Excel problems.
What next?
Don’t go yet, there is plenty more to learn on Excel Off The Grid. Check out the latest posts:
The VBA ArrayList is a much better alternative to the built-in VBA Collection. It contains much richer functionality such as sorting, converting to an array, removing all items etc.
Check out the quick guide for an overview of what the ArrayList does. The rest of this post provides examples of how to use the ArrayList.
Quick Guide to the VBA ArrayList
Task | Method | Parameters | Examples |
---|---|---|---|
Access item | Item | index — long integer | value = list.Item(0) value = list.Item(3) |
Access item added last | Item | index — long integer | value = list.Item(list.Count — 1) |
Access item added first | Item | index — long integer | value = list.Item(0) |
Access all items(For Each) | N/A | N/A | Dim element As Variant For Each element In fruit Debug.Print element Next element |
Access all items(For) | Item | index — long integer | Dim i As Long For i = 0 To list.Count — 1 Debug.Print list.item(i) Next i |
Add item | Add | object or value | list.Add «Apple» list.Add «Pear» |
Copy ArrayList to another ArrayList | Clone | None | Dim list2 As Object Set list2 = list.Clone |
Copy to Array | ToArray | None | Dim arr As Variant arr = list.ToArray |
Copy to a range(row) | ToArray | None | Sheet1.Range(«A1»).Resize(1, list.Count).Value = list.ToArray |
Copy to a range(column) | ToArray | None | Sheet1.Range(«A3»).Resize(list.Count, 1).Value = WorksheetFunction.Transpose(list.ToArray) |
Create | CreateObject | «System.Collections.ArrayList» | Dim list As Object Set list = CreateObject(«System.Collections.ArrayList») |
Declare | N/A | N/A | Dim list As Object |
Find — check if item exists | Contains | item to find | list.Contains(«Apple») |
Find the position of an item in the ArrayList | IndexOf | 1. Item to find. 2. Position to start searching from. |
Dim index As Long ‘ Search from 0 position index = fruit.IndexOf(«Pear», 0) |
Get number of items | Count | None | totalElements = list.Count |
Insert Item | Insert | 1. Index — position to insert at. 2 Value — object or value to insert. |
list.Insert 0, «Peach» ‘ First list.Insert 1, «Banana» ‘ Second list.Insert list.Count, «Orange» ‘ Last |
Remove all Items | Clear | None | list.Clear |
Remove item at position | RemoveAt | Index — position where the item is | list.RemoveAt 0 |
Remove item by name | Remove | Item — the item to remove from the ArrayList | list.Remove «Apple» |
Remove a range of Items | RemoveRange | 1. Index — starting postion. 2. Count — the number of items to remove. |
list.RemoveRange 1,3 |
Reverse the list | Reverse | None | list.Reverse |
Sort in ascending | Sort | None | list.Sort |
Description
The ArrayList is similar to the VBA built-in Collection. It is not part of VBA, but it is in an external library which we can access easily. The ArrayList is the same one that is used in the language C#. As you would expect, the ArrayList has a built-in sort, array conversion and other functionality that you would expect in a modern programming language. For the purpose of this article, I will refer to it as the VBA ArrayList.
Download the Source Code
Declare and Create the VBA ArrayList
Like all external libraries we can create the ArrayList using early and late binding.
Late Binding
We use CreateObject to create the ArrayList using late binding:
' https://excelmacromastery.com/ Sub UsingArrayList() Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") End Sub
The disadvantage of late binding is that we don’t have access to the Intellisense. The advantage is that it is better to use when distributing a VBA application to a user.
Early Binding
Update 12-Nov-2019: Intellisense doesn’t currently work for the ArrayList.
Early binding allows use to use the Intellisense to see what is available to use. We must first add the type library as a reference and then select it from the reference list. We can use the following steps to do this:
- Select Tools and then References from the menu.
- Click on the Browse.
- Find the file mscorlib.tlb and click Open. It should be in a folder like this C:WindowsMicrosoft.NETFrameworkv4.0.30319.
- Scroll down the list and check mscorlib.dll.
- Click Ok.
You can now use the following code to declare the ArrayList using early binding:
Dim coll As New ArrayList
VBA ArrayList Automation Error
You may encounter the VB Run-time Error ‘-2146232576 Automation Error’ when trying to get the ArrayList to work. Or sometimes your code has been working for a long time and then suddenly this error appears.
This is caused by not having the correct .Net Framework version installed. The correct version is 3.5. It doesn’t matter if you have a later version like 4.7, you must have 3.5 installed.
Adding Items to the VBA ArrayList
Adding items to the ArrayList is very similar to how we add them to the Collection. We use the Add method:
' https://excelmacromastery.com/ Sub AddingToList() Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' Add items coll.Add "Apple" coll.Add "Watermelon" coll.Add "Pear" coll.Add "Banana" ' Insert to first position coll.Insert 0, "Plum" End Sub
Reading through an ArrayList
We read through the ArrayList similar to the VBA Collection except that we read from zero to Count-1 rather than from one to Count.
Note: We will use this PrintToImmediateWindow sub in the follow examples to show the contents of the array after the various operations.
' Print all items to the Immediate Window(Ctrl + G) ' Items must be basic data type e.g. Long, String, Double ' https://excelmacromastery.com/ Sub PrintToImmediateWindow(coll As Object) Dim i As Long For i = 0 To coll.Count - 1 Debug.Print coll(i) Next i End Sub
We can use the For Each loop with the VBA ArrayList just like we use it with a Collection:
' Print all items to the Immediate Window(Ctrl + G) ' Items much be basic data type e.g. Long, String, Double ' https://excelmacromastery.com/ Sub PrintToImmediateWindowEach(coll As Object) Dim item As Variant For Each item In coll Debug.Print item Next item End Sub
You can download all the code examples at the top of this post.
Sorting
Sort will sort the VBA ArrayList in ascending order.
To sort in descending order simply use Reverse after Sort.
The following code shows an example of sorting in both ascending and descending order:
' https://excelmacromastery.com/ Sub Sorting() Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' Add items coll.Add "Apple" coll.Add "Watermelon" coll.Add "Pear" coll.Add "Banana" coll.Add "Plum" ' Sort coll.Sort Debug.Print vbCrLf & "Sorted Ascending" ' Add this sub from "Reading through the items" section PrintToImmediateWindow coll ' Reverse sort coll.Reverse Debug.Print vbCrLf & "Sorted Descending" PrintToImmediateWindow coll End Sub
' https://excelmacromastery.com/ Sub PrintToImmediateWindow(coll As Object) Dim i As Long For i = 0 To coll.Count - 1 Debug.Print coll(i) Next i End Sub
Cloning the VBA ArrayList
We can create a copy of the ArrayList by using the Clone method. This creates a brand new copy of the ArrayList.
It’s not the same as assigning the variable which means both variables point to the same ArrayList e.g.
' Both variables point to the same ArrayList Set coll2 = coll
We use Clone like this:
' https://excelmacromastery.com/ Sub Cloning() ' Create the ArrayList Dim coll1 As Object Set coll1 = CreateObject("System.Collections.ArrayList") ' Add items coll1.Add "Apple" coll1.Add "Watermelon" coll1.Add "Pear" coll1.Add "Banana" coll1.Add "Plum" ' Creates a copy of the original ArrayList Dim coll2 As Object Set coll2 = coll1.Clone ' Remove all items from coll1 coll1.Clear ' Add PrintToImmediateWindow sub from "Reading through the items" section Debug.Print vbCrLf & "coll1 Contents are:" PrintToImmediateWindow coll1 Debug.Print vbCrLf & "coll2 Contents are:" PrintToImmediateWindow coll2 End Sub
' https://excelmacromastery.com/ Sub PrintToImmediateWindow(coll As Object) Dim i As Long For i = 0 To coll.Count - 1 Debug.Print coll(i) Next i End Sub
Copying from an VBA ArrayList to an Array
We can copy from the ArrayList to an array in one line using the ToArray method:
' https://excelmacromastery.com/ Sub CopyToArray() ' Declare and Create ArrayList Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' Add items coll.Add "Apple" coll.Add "Watermelon" coll.Add "Pear" coll.Add "Banana" coll.Add "Plum" ' Copy to array Dim arr As Variant arr = coll.ToArray ' Print the array Debug.Print vbCrLf & "Printing the array contents:" PrintArrayToImmediate arr End Sub
' Prints the contents of a one dimensional array ' to the Immediate Window(Ctrl + G) ' https://excelmacromastery.com/ Sub PrintArrayToImmediate(arr As Variant) Dim i As Long For i = LBound(arr) To UBound(arr) Debug.Print arr(i) Next i End Sub
You can download all the code examples at the top of this post.
Writing Directly to a Range
One of the biggest advantages of the ArrayList is that we can write the contents directly to a range.
The code below writes the contents to both a row and a column:
' Writes the contents of an ArrayList to a worksheet range ' https://excelmacromastery.com/ Sub ClearArrayList() ' Declare and Create ArrayList Dim fruit As Object Set fruit = CreateObject("System.Collections.ArrayList") ' Add items fruit.Add "Apple" fruit.Add "Watermelon" fruit.Add "Pear" fruit.Add "Banana" fruit.Add "Plum" fruit.Add "Peach" ' ' Clean existing data Sheet1.Cells.ClearContents ' Write to a row Sheet1.Range("C1").Resize(1, fruit.Count).Value = fruit.toArray ' Write to a column Sheet1.Range("A1").Resize(fruit.Count, 1).Value = WorksheetFunction.Transpose(fruit.toArray) End Sub
Array to a VBA ArrayList(1D)
As we have seen, there is an in-built function ToArray which will copy from an ArrayList to an Array.
If we want to copy from an Array to an ArrayList we need to create our own function which I have done below. Because we read through the items one at a time, it may be a bit slow if we have a lot of data:
' https://excelmacromastery.com/ Function ArrayToArrayList(arr As Variant) As Object ' Check that array is One Dimensional On Error Resume Next Dim ret As Long ret = -1 ret = UBound(arr, 2) On Error Goto 0 If ret <> -1 Then Err.Raise vbObjectError + 513, "ArrayToArrayList" _ , "The array can only have one 1 dimension" End If ' Create the ArrayList Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' Add items to the ArrayList Dim i As Long For i = LBound(arr, 1) To UBound(arr, 1) coll.Add arr(i) Next i ' Return the new ArrayList Set ArrayToArrayList = coll End Function
You can use it like this:
' https://excelmacromastery.com/ Sub ReadFromArray1D() Dim arr(1 To 3) As Variant arr(1) = "PeterJ" arr(2) = "Jack" arr(3) = "Jill" ' Create the ArrayList Dim coll As Object Set coll = ArrayToArrayList(arr) PrintToImmediateWindow coll End Sub
Remove All Items from the ArrayList
We can remove all the items from an ArrayList by using the Clear function:
' https://excelmacromastery.com/ Sub ClearArrayList() ' Declare and Create ArrayList Dim coll As Object Set coll = CreateObject("System.Collections.ArrayList") ' Add items coll.Add "Apple" coll.Add "Watermelon" coll.Add "Pear" coll.Add "Banana" coll.Add "Plum" Debug.Print vbCrLf & "The number of items is: " & coll.Count ' Remove all item coll.Clear Debug.Print "The number of items is: " & coll.Count End Sub
You can download all the code examples at the top of this post.
What’s Next?
Free VBA Tutorial If you are new to VBA or you want to sharpen your existing VBA skills then why not try out the The Ultimate VBA Tutorial.
Related Training: Get full access to the Excel VBA training webinars and all the tutorials.
(NOTE: Planning to build or manage a VBA Application? Learn how to build 10 Excel VBA applications from scratch.)
Object Hierarchy | Collections | Properties and Methods
Learn more about the Workbook and Worksheet object in Excel VBA.
Object Hierarchy
In Excel VBA, an object can contain another object, and that object can contain another object, etc. In other words, Excel VBA programming involves working with an object hierarchy. This probably sounds quite confusing, but we will make it clear.
The mother of all objects is Excel itself. We call it the Application object. The application object contains other objects. For example, the Workbook object (Excel file). This can be any workbook you have created. The Workbook object contains other objects, such as the Worksheet object. The Worksheet object contains other objects, such as the Range object.
The Create a Macro chapter illustrates how to run code by clicking on a command button. We used the following code line:
Range(«A1»).Value = «Hello»
but what we really meant was:
Application.Workbooks(«create-a-macro»).Worksheets(1).Range(«A1»).Value = «Hello»
Note: the objects are connected with a dot. Fortunately, we do not have to add a code line this way. That is because we placed our command button in create-a-macro.xlsm, on the first worksheet. Be aware that if you want to change things on different worksheets, you have to include the Worksheet object. Read on.
Collections
You may have noticed that Workbooks and Worksheets are both plural. That is because they are collections. The Workbooks collection contains all the Workbook objects that are currently open. The Worksheets collection contains all the Worksheet objects in a workbook.
You can refer to a member of the collection, for example, a single Worksheet object, in three ways.
1. Using the worksheet name.
Worksheets(«Sales»).Range(«A1»).Value = «Hello»
2. Using the index number (1 is the first worksheet starting from the left).
Worksheets(1).Range(«A1»).Value = «Hello»
3. Using the CodeName.
Sheet1.Range(«A1»).Value = «Hello»
To see the CodeName of a worksheet, open the Visual Basic Editor. In the Project Explorer, the first name is the CodeName. The second name is the worksheet name (Sales).
Note: the CodeName remains the same if you change the worksheet name or the order of your worksheets so this is the safest way to reference a worksheet. Click View, Properties Window to change the CodeName of a worksheet. There is one disadvantage, you cannot use the CodeName if you reference a worksheet in a different workbook.
Properties and Methods
Now let’s take a look at some properties and methods of the Workbooks and Worksheets collection. Properties are something which an collection has (they describe the collection), while methods do something (they perform an action with an collection).
Place a command button on your worksheet and add the code lines:
1. The Add method of the Workbooks collection creates a new workbook.
Workbooks.Add
Note: the Add method of the Worksheets collection creates a new worksheet.
2. The Count property of the Worksheets collection counts the number of worksheets in a workbook.
MsgBox Worksheets.Count
Result when you click the command button on the sheet:
Note: the Count property of the Workbooks collection counts the number of active workbooks.