OfficeTalk: Working with Lists and Tables: VBA Samples (Part 2 of 2)
This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.
Summary: Tables and lists are an integral part of Microsoft Excel. Microsoft Excel MVP Ron de Bruin explains some handy VBA subroutines that can make you more productive when using tables or lists. (8 printed pages)
Ron de Bruin, Excel MVP
Frank Rice, Microsoft Corporation
May 2009
Applies to: Microsoft Office Excel 2003, Microsoft Office Excel 2007
Contents
Copying Tables or Lists to New Workbooks
Filtering Tables or Lists
Clearing Filters
Conclusion
Additional Resources
To download a Microsoft Excel workbook containing the procedures discussed in these column and more, see VBA Code Examples for Tables in Excel 2007 or a List in Excel 2003.
Copying Tables or Lists to New Workbooks
The following code is similar to the subroutine in the previous column except that instead of copying the table or list to a new worksheet in the same workbook, the procedure copies the visible data to a new workbook.
Sub CopyListOrTableData2NewWorkbook()
'Works in Excel 2003 and Excel 2007. Only copies visible data.
Dim New_Ws As Worksheet
Dim ACell As Range
Dim CCount As Long
Dim ActiveCellInTable As Boolean
Dim CopyFormats As Variant
'Check to see if the worksheet is protected.
If ActiveSheet.ProtectContents = True Then
MsgBox "This macro will not work when the worksheet is write-protected."
Exit Sub
End If
'Set a reference to the ActiveCell named ACell. You can always use
'ACell now to point to this cell, no matter where you are in the workbook.
Set ACell = ActiveCell
'Test to see if ACell is in a table or list. Note that by using ACell.ListObject, you
'don't need to know the name of the table to work with it.
On Error Resume Next
ActiveCellInTable = (ACell.ListObject.Name <> "")
On Error GoTo 0
'If the cell is in a list or table, run the code.
If ActiveCellInTable = True Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
On Error Resume Next
With ACell.ListObject.ListColumns(1).Range
CCount = .SpecialCells(xlCellTypeVisible).Areas(1).Cells.Count
End With
On Error GoTo 0
'Test if there are more than 8192 separate areas. Excel only supports
'a maximum of 8,192 non-contiguous areas through VBA macros and manual.
If CCount = 0 Then
MsgBox "There are more than 8192 areas, so it is not possible to " & _
"copy the visible data to a new workbook. Tip: Sort your " & _
"data before you apply the filter and try this macro again.", _
vbOKOnly, "Copy to new workbook"
Else
'Copy the visible cells to the new workbook.
ACell.ListObject.Range.Copy
'Add a new workbook with one worksheet.
Set New_Ws = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
'Paste the data in the worksheet into the new workbook.
On Error Resume Next
With New_Ws.Range("A1")
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteValuesAndNumberFormats
.Select
Application.CutCopyMode = False
End With
On Error GoTo 0
'Call the Create List or Table dialog
Application.ScreenUpdating = True
Application.CommandBars.FindControl(ID:=7193).Execute
New_Ws.Range("A1").Select
ActiveCellInTable = False
On Error Resume Next
ActiveCellInTable = (New_Ws.Range("A1").ListObject.Name <> "")
On Error GoTo 0
Application.ScreenUpdating = False
'If you do not create a table, you have an option to copy the formats.
If ActiveCellInTable = False Then
Application.GoTo ACell
CopyFormats = MsgBox("Do you also want to copy the Formats?", _
vbOKCancel + vbExclamation, "Copy to new workbook")
If CopyFormats = vbOK Then
ACell.ListObject.Range.Copy
With New_Ws.Range("A1")
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
End If
End If
'Select the new workbook if it is not active.
Application.GoTo New_Ws.Range("A1")
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
Else
MsgBox "Select a cell in your list or table before you run the macro.", _
vbOKOnly, "Copy to new workbook"
End If
End Sub
Filtering Tables or Lists
The following code filters a table or list. To test the procedure, I used a table similar to Figure 1. Just type in the data and then use the procedure described at the beginning of this column to encapsulate it into a table.
Figure 1. A sample table for testing the filter macro
Sub FilterListOrTableData()
'Works in Excel 2003 and Excel 2007.
Dim ACell As Range
Dim ActiveCellInTable As Boolean
Dim FilterCriteria As String
'Check to see if the worksheet is protected.
If ActiveSheet.ProtectContents = True Then
MsgBox "This macro will not work when the worksheet is write-protected.", _
vbOKOnly, "Filter example"
Exit Sub
End If
'Set a reference to the ActiveCell named ACell. You can always use
'ACell now to point to this cell, no matter where you are in the workbook.
Set ACell = ActiveCell
'Test to see if ACell is in a table or list. Note that by using ACell.ListObject, you
'don't need to know the name of the table to work with it.
On Error Resume Next
ActiveCellInTable = (ACell.ListObject.Name <> "")
On Error GoTo 0
'If the cell is in a list or table, run the code.
If ActiveCellInTable = True Then
'Show all data in the table or list.
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
'This example filters on the first column in the List/Table
'(change the field if needed). In this case the Table starts
'in A so Field:=1 is column A, field 2 = column B, ......
'Use "<>" & filtercriteria if you want to exclude the criteria from the filter.
FilterCriteria = InputBox("What text do you want to filter on?", _
"Type in the filter item.")
ACell.ListObject.Range.AutoFilter _
Field:=1, _
Criteria1:="=" & FilterCriteria
Else
MsgBox "Select a cell in your list or table before you run the macro.", _
vbOKOnly, "Filter example"
End If
End Sub
If you want to filter on the active cell instead, change the following lines:
FilterCriteria = InputBox("What text do you want to filter on?", _
"Type in the filter item.")
ACell.ListObject.Range.AutoFilter _
Field:=1, _
Criteria1:="=" & FilterCriteria
To the following:
'This example filters on the ActiveCell value.
ACell.ListObject.Range.AutoFilter _
Field:=ACell.Column - ACell.ListObject.Range.Cells(1).Column + 1, _
Criteria1:="=" & ACell.Text
Likewise, if you want to use the text in cell C1 as the filter criteria, replace the following lines:
FilterCriteria = InputBox("What text do you want to filter on?", _
"Type in the filter item.")
ACell.ListObject.Range.AutoFilter _
Field:=1, _
Criteria1:="=" & FilterCriteria
To the following:
'This example filters on the first column in the List/Table.
'(change the field if needed). In this case the Table starts
'in column A so Field:=1 is column A, field 2 = column B,
'It will use a cell text of Range("C1")for the Criteria.
ACell.ListObject.Range.AutoFilter _
Field:=1, _
Criteria1:="=" & Range("C1").Text
If you want to add your criteria in the code, replace the following lines:
FilterCriteria = InputBox("What text do you want to filter on?", _
"Type in the filter item.")
ACell.ListObject.Range.AutoFilter _
Field:=1, _
Criteria1:="=" & FilterCriteria
To the following:
'This example filters on the first column in the List/Table
'(change the field if needed). In this case the Table starts
'in A so Field:=1 is column A, 2 = column B, ......
'Use "<>Netherlands" if you want to exclude the criteria from the filter
ACell.ListObject.Range.AutoFilter Field:=1, Criteria1:="=Netherlands"
You can also use this to filter for all Sales Representatives born between 23 Feb 1947 and 7 May 1988 from the Netherlands and the USA (column A, C and D in the sample table). Use two criteria in field 1 and 4 (2 items are the maximum number of criteria for AutoFilter).
ACell.ListObject.Range.AutoFilter Field:=1, Criteria1:="=Netherlands", Operator:=xlOr, Criteria2:="=USA"
ACell.ListObject.Range.AutoFilter Field:=3, Criteria1:="=Sales Representative"
ACell.ListObject.Range.AutoFilter Field:=4, Criteria1:=">=02/23/1947" , _
Operator:=xlAnd, Criteria2:="<=05/07/1988"
Important
When using VBA code, you must use the United States’s date format mm/dd/yyyy to filter dates. In the user interface, you can use any date format. For more information, see International Issues.
Tip
If you want to filter every record that has a value in the first column that starts with Netherlands, you can use Criteria1:="=Netherlands*". If Netherlands is a part of the string, you can use Criteria1:="=Netherlands". You can also use the ? as a wildcard for one character . If the is part of the name you are filtering on as in USA, you can use USA~ where the ~ is a substitute for the single character . You can also use ~? or~ ~ if ? or ~ are part of the string.
Clearing Filters
The following macro clears a filter on a table or list.
Sub ClearFilterListOrTable()
'Works in Excel 2003 and Excel 2007.
Dim ACell As Range
Dim ActiveCellInTable As Boolean
'Check to see if the worksheet is protected.
If ActiveSheet.ProtectContents = True Then
MsgBox "This macro will not work when the worksheet is write-protected.", _
vbOKOnly, "Clear filter example"
Exit Sub
End If
'Set a reference to the ActiveCell named ACell. You can always use
'ACell now to point to this cell, no matter where you are in the workbook.
Set ACell = ActiveCell
'Test to see if ACell is in a table or list. Note that by using ACell.ListObject, you
'don't need to know the name of the table to work with it.
On Error Resume Next
ActiveCellInTable = (ACell.ListObject.Name <> "")
On Error GoTo 0
'If the cell is in a list or table, run the code.
If ActiveCellInTable = True Then
'Show all data in the table or list.
On Error Resume Next
ActiveSheet.ShowAllData
On Error GoTo 0
Else
MsgBox "Select a cell in your list or table before you run the macro.", _
vbOKOnly, "Clear filter example"
End If
End Sub
Conclusion
The methods showcased in this column and in OfficeTalk: Working with Lists and Tables: VBA Samples (Part 1 of 2) provide a starting place for you to explore the other VBA objects and methods available to help you work with lists and tables.
Additional Resources
More information on the subjects described in this column can be found at the following locations.
Working with Tables in Excel 2007 (Jan Karel Pieterse - Excel MVP)
Working with Tables in Excel 2007 with VBA (Jan Karel Pieterse - Excel MVP)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 1 of 6)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 2 of 6)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 3 of 6)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 4 of 6)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 5 of 6)
OfficeTalk: Bringing Improvements to Tables in Excel 2007 (Part 6 of 6)
OfficeTalk: Filtering by the Active Cell's Value, Font Color, or Fill Color in Excel 2007