Вы находитесь на странице: 1из 28

Recording a macro in Excel

How to record a macro in Excel 2007 and Excel 2010

In Excel 2007 (and Excel 2010), the Record Marco menu option is under the
View ribbon. Click on the Macros button towards at the right end of the
ribbon and then click Record Macro. A pop-up box will ask you to enter the
details of the macro. If you are just starting to record your own macro, you
can simply click on the ok button. After this you can carry out the steps
that you want like entering numbers, formulas, formatting cells, inserting
charts etc etc. Once you are done you can stop recording the macro by
clicking the Stop Recording option under the Macro button.

Alternatively, you can begin and stop recording a macro in Excel 2010 (and
2007) by clicking on the icon located at the bottom-left of the application
window, right next to where it is labelled Ready.
You can now view the macro that you just recorded by clicking the View
Macros option under the Macros button. Alternatively you can press

Alt+F8 as the shortcut key. You can give a descriptive name to the macro or
assign a shortcut key so that by pressing that key combination, the macro
will begin execution.

How to record a macro in Excel 2003 (& earlier)


In Excel 2003 and earlier versions, you can record a macro by clicking on
Tools option in the menubar and then clicking on Macro and then
choosing the Record New Macro option. Click ok on the pop-up box that
appears and then carry out the steps that you wish the record in the macro.
Once you are done, you can click the Stop Recording option under Macro
from the menu.

You can view the macro you just recorded by clicking on Tools option in the
menubar and then clicking on Macro and then choosing the Macros
option. Alternatively you can press Alt+F8 as the shortcut key. You can record
a complete set of macros and then run them one after another to get a the
steps related to a task accomplished at one go.
How to edit a macro
Congratulations! You have now written your first macro. The logical next step
is to check out the code that was generated by the macro. The code
generated by the application is in a language called VBA (Visual Basic for
Applications). To view the code, we will need to open the VBA Editor (also
referred to as the VBA IDE or VBA Integrated Development Environment). You
can use the shortcut key Alt+F11 to open up the IDE or simply use the
following menu options.
Editing a macro in Excel 2010 and 2007
You can turn on the Developer tab by clicking on the Office button located
at the top left corner of the Excel workbook. Click on the Excel Options
button and then turn on Show developer tab in the Ribbon checkbox the
under the Popular menu option.

Having done that, you can now use the Developer tab to access the VBA
Editor by pressing the Visual Basic button.

Editing a macro in Excel 2003 and earlier versions


The visual basic editor can be accessed using he shortcut key Alt+F11, by
using the visual basic editor button in the visual basic toolbar or by choosing
the visual basic editor option from the menu as shown below.

You may want to keep just one workbook open to avoid confusion while
opening the VBA editor.

Once youve opened up the VBA IDE, heres how it would look like.

At this point, it is important to familiarize oneself with the various windows


and menu options. A few minutes spent in understanding these can
potentially save you a ton of effort later.
To view to code of the macro that you just recorded, click on the Module
under the project explorer window and then double click on Module1. It
would open up a window like the one shown below with a few lines of code.

This is the point now where you can begin to edit the code that the macro
generated while you were recording it in Excel. For example, you have to
automate a task where a certain column is populated with numbers starting
from 1 to 10. You recorded the first three steps so that you now have the
code that can enter the numbers 1, 2 and 3 in the first three cells of that
column. You would now like to write the next seven steps.
If you looked at the code given above, you would have guessed that there is
a structure to the code. The application first moves the cursor to the cell by
using an instruction like Range(A1).Select and then editing its contents by
something like ActiveCell.FormulaR1C1 = 1. So for the remaining steps, we
can simply repeat these steps by providing the address of the new cell and
then in the next step providing the value that we would like to enter. For
example if you wanted to enter 4 in cell A4, you would write:
1 Range("A4").Select
2 ActiveCell.FormulaR1C1 = "4"
and then repeat the step for the all the other values that you would like to
enter.

Once you are done editing, save the workbook. You can play back this marco
either by pressing F5 while still within the main body of the macro or going
back to the excel workbook and using the Run button after selecting the
required macro from the Macro list window shown above.
Please take a few minutes to carefully read through the code that the macro
has generated. If you are a beginner, a few minutes invested in reading
through the code and yield tremendous results and will go a long way on
familiarizing you with commonly used objects in VBA. (Please bear in mind
that this example is only for illustration. There are better and faster ways of
achieving the same results, some of which we will cover in the sections
below.)
Improving speed to execution of an Excel Macro
So far so good. Lets move on to learning some tricks that can help you
speed up the performance of your macros VBA code. Lets take the example
of the code snippet shown above. On a high-end computer the above code
will probably run faster than you can click an eyelid but suppose we we had
to run the same code over and over again for 50,000 cells (or iterations).
That would take some time. If the macro that you wrote runs into hundreds
of lines of code, you can improve the speed of execution by cutting down on
all the other processes that are not required when the code is executing.
Using Application.ScreenUpdating command
The first trick is to stop Excel from updating the screen as the code executes.
That helps Excel save all the processing power executing the code and
update the screen with fresh value only after the code has ended executing.
To achieve this, we can write a statement at the beginning of the code to
turn off screen updation and turn it right back on at the end of the code.
1
2
3
4
5
6
7
8
9
10

Sub Macro1()
Application.ScreenUpdating = False
Range("A1").Select
ActiveCell.FormulaR1C1 = "1"
Range("A2").Select
ActiveCell.FormulaR1C1 = "2"
Range("A3").Select
ActiveCell.FormulaR1C1 = "3"
Application.ScreenUpdating = True
End Sub

The Application.ScreenUpdating command tells the application to forget


about updating the screen with real-time results from the code and to refresh
it only after the code has been fully executed.

Using Application.Calculation command


The second trick is to turn off automatic calculations. Let me explain.
Whenever a user or a process updates a cell, excel tends to recalculate all
the cells that depend upon that cell. So if say, 10,000 cells depend on the
cell that your code is going to update, excel will recalculate all of them
before the code completes executing. Now if there are a number of such
cells, the recalculation can severely slow down code execution. To prevent
this from happening, you can set the Application.Calculation parameter to
manual at the beginning of the code and then right back on towards the end
of the code.
1
2
3
4
5
6
7
8
9
10
11
12

Sub Macro1()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range("A1").Select
ActiveCell.FormulaR1C1 = "1"
Range("A2").Select
ActiveCell.FormulaR1C1 = "2"
Range("A3").Select
ActiveCell.FormulaR1C1 = "3"
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Be careful to turn on this option back on at the end otherwise it will remain
turned off even when the code has fully executed. If you let it turned off
withing the code, you can change it to automatic by using the Tools ->
Options -> Calculation tab from the menu as shown below:

Avoid Cell and Range Selection in VBA


When you record a macro, you will typically see lines of code like
Range(A1).Select. In our example above, we have used such statements
multiple times to select a particular cell and then changing its value. You can
avoid doing this by simply assigning a value to the cell without selecting it.
(The macro recorded your cursors movement from one cell to another and
hence inserted these steps, however they are not necessary when working
with VBA code). So in this case, a far more efficient code would be:
1
2
3
4
5
6
7
8
9
10
11

Sub Macro1()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Range("A1").Value = 1
Range("A2").Value = 2
Range("A3").Value = 3
Range("A4").Value = 4
Range("A5").Value = 5
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

What weve done here is to simply reference a cell and then provide a value
to it without selecting it at all. This is way faster than the previous one.

How to write loops in VBA


You can refer to some of the previous articles dealing with this. You can learn
more about VBA For Loop here. For the Do While Loop please refer to this
article.
How to fix runtime errors in VBA
Once you have learnt how to record and edit a macro and acquire the skills
to write basic VBA code, it is important that you learn about error handling.
Error handling prevents the application from crashing when an unexpected
event occurs. Please read more about fixing runtime errors in VBA here.
Excel macro Examples
Here are a few examples of VBA code that can help you automate some
frequently repeated tasks.
Excel Macro to insert a row
1 Sub Macro1()
2 Rows(2).EntireRow.Insert
3 End Sub

'Insert a new row above the second row

Excel Macro to insert a column


1
Sub Macro1()
Columns(3).EntireColumn.Insert
2
3rd colmun
End Sub
3

'Insert a new column to the left of the

Excel Macro to insert a column


1 Sub Macro1()
2 'Change the formatting of the cell D2 to bold, underlined and itallic
3 Cells(2, 4).Font.Bold = True
4 Cells(2, 4).Font.Underline = xlUnderlineStyleSingle
5 Cells(2, 4).Font.Italic = True
6 End Sub
Excel Macro to traverse a range
1 Sub Macro1()
2 For Each cel In Range(Cells(1, 1), Cells(10, 5))
3 counter = counter + 1

4 cel.Value = counter
5 Next cel
6 End Sub

VBA For Next Loop


The For Next loop has the following syntax:
1 For a_counter = start_counter To end_counter
2
'Do something here
3 Next a_counter
What we are doing here essentially is create a loop that uses a variable
a_counter as the time keeper of the loop. We set it to a value equal to
start_counter at the beginning of the loop and then increment (or reduce) it
by 1 during each loop till. The loop will execute till the time the value of the
a_counter becomes equal to end_counter. The loop executes for the last time
when both the above values match and then stop.
Example of a for loop
1 Sub my_for_loop1()
2 For a_counter = 1 to 10
3 j = a_counter
4 Next a_counter
5
6 msgbox "The value of the counter in the last loop was " & a_counter
7 End Sub
The final value of the of the a_counter in the above loop is 11.
VBA For Loop in Reverse with STEP Instruction
It is not necessary that counter in the for loop only move from a lower value
to a higher value you can have the for loop backwards too. Here is an
example of for loop in reverse:
1 Sub my_for_loop2()
2 For a_counter = 10 to 1 Step -1
3 j = a_counter
4 Next a_counter
5
6 msgbox "The value of the counter in the last loop was " & a_counter

7End Sub
The final value of the a_counter in this loop is 1.
As you can see, we can use the Step n instruction to ensure that the for loop
works either forward or in reverse. By default the Step value is forward 1,
however it can be set to a number more than 1 to skip forward loops or
negative for the for loop to work in reverse.
VBA For Each In Next Loop
The For Each In Next loop has the following syntax:
1 For Each item_in_group In group_of_items
2
Do something here
3 Next item_in_group
The item_in_group here belongs to a group_of_items (smart aint I). What I
mean is that the object used as a group_of_items has to be a collection of
objects. You cant run a for each item loop on individual objects (lest
Microsoft throw the friendly run-time error 438 at you !)

The above loop moves one item at a time starting with the first item in the
collection of objects. You can use this particular for loop syntax to iterate
along sheets in a workbook, shapes in a sheet, pivot tables in a sheet or any
collection of objects in general.
Lets take the example of how you can use the for loop to iterate through all
worksheets in a workbook:
1
2
3
4
5

Sub my_for_loop3()
For Each sht In ActiveWorkbook.Worksheets
MsgBox sht.Name
Next sht
End Sub

Now lets see how we can loop through all the pivot tables in a sheet:

1
2
3
4
5

Sub my_for_loop4()
For Each pvt In ActiveSheet.PivotTables
MsgBox pvt.Name
Next pvt
End Sub

End For Loop before End Condition


If you need to end the For loop before the end condition is reached or met,
simply use the END FOR in conjunction with the IF statement. In the example
given below, we exit the for loop prematurely and before the end condition is
met. The for example given below, the loop exits when a_counter reaches a
value of 3.
1
2
3
4
5
6

Sub my_for_loop5()
For a_counter = 0 To 5
MsgBox a_counter
If (a_counter = 3) Then Exit For
Next a_counter
End Sub

Move out of or Skip a particular loop in a For Loop


It is not advisable to move out a for loop and then move back again. Lets
take a very convoluted example:
1
2
3
4
5
6
7
8
9
10
11
12
13

Sub my_for_loop6()
Dim j As Integer
For i = 0 To 5
b:
If (j = 3) Then GoTo a:
j=i
Next i
a:
j=4
GoTo b:
MsgBox ("Final value of j = " & j)
End Sub

What weve tried to do here is a move out of the for loop in one particular
iteration (when j = 3). What do you think is the final value of j in the above
example. 3 ? 5? Well none of them really. The loop executes endlessly and
would soon lead to overflow.

However it is possible to skip a loop in the For Loop. You can increment the
counter by 1 (or any other number) and that can cause the for loop to skip all
the loops in between. Heres an example.
1
2
3
4
5
6

Sub my_for_loop7()
For i = 0 To 5
i=i+1
MsgBox i
Next i
End Sub

However again, this is not a good coding practice and can lead to headaches
for the folks maintaining the VBA code later. Instead check if the particular
condition is to be skipped in a FOR loop, try using an IF function or even a
SELECT CASE statement.
Using a simple IF function in VBA
Heres an example of the IF function. This piece of VBA code is simply
checking whether the condition specified (i.e. 1 > 4) evaluates to TRUE or
FALSE. In this case, we have only specified the steps to be completed when
the condition evaluates to TRUE. In this case, the result will be a message
box being displayed on the screen. If the function were to evaluate to FALSE,
the VBA code will do nothing.
1
2
3
4
5

Sub IF_FUNCTION()
If 7 > 1 Then
MsgBox "7 is greater than 1"
End If
End Sub

The THEN statement is essentially a directive indicating that the steps


immediately following it are to be executed if the condition just before if
evaluate to TRUE.
The IF function typically ends with an END IF declaration which lets the
application know that it is the last line of the IF function. Given below is a
slightly shorter form of the IF function. Note that the END IF statement has
been eliminated in this and thus three lines of code has been merged into
one.
1 Sub IF_FUNCTION_SHORT()
2 If 7 > 1 Then MsgBox "7 is greater than 1"
3 End Sub

However this form should be used only when there are no ELSE or ELSE IF
statements are needed. Lets look at what they are and how they help
enhance the IF function.
Using a IF function with ELSE in VBA

In the example given above, we saw that the IF


function would be able to carry out steps only if the condition evaluated to
TRUE. But what if we wanted to specify the steps to be carried out when
either of the conditions were met. One way to achieve branching out of an IF
function is to use the ELSE statement. Simply put, the ELSE statement
causes the application to execute the steps mentioned in the ELSE block
when the condition specified in the IF clause evaluates to FALSE.
In the VBA code example below, the condition in the IF function evaluates to
false, the steps mentioned in the ELSE block are executed with the result
that the message 1 is less than 4 gets displayed on the screen. Multiple
steps can be added to the block to have them all execute one after another.
1
2
3
4
5
6
7

Sub IF_ELSEIF_FUNCTION()
If 1 > 4 Then
MsgBox "1 is greater than 4"
Else:
MsgBox "1 is less than 4"
End If
End Sub

Using a IF function with ELSEIF and ELSE: in VBA


The ELSE statement may be supported by ELSEIF statements. They are
typically used to check for specific conditions and if all of them evaluate to
FALSE, the steps specified in the ELSE condition will finally get executed. The
IF statement will check for a given condition. If that condition turns out to be
FALSE, the condition specified in the first ELSEIF statement will be checked. If
that also turns out to be FALSE, the condition specified in the second ELSEIF
statement will be checked, and so on and so forth. If all conditions specified

in the IF and ELSEIF statements turn out to be FALSE, by default the steps
mentioned under the final ELSE: block will get executed. Please remember
that if there are multiple ELSEIF statements, the first one that evaluates to
TRUE will get executed and once completed, the code execution will move to
the END IF statement. Even if there are multiple ELSEIF conditions that
evaluate to TRUE, only the first one that evaluates to TRUE will be executed.
1
2
3
4
5
6
7
8
9
10
11

Sub IF_ELSEIF_ELSE_FUNCTION()
If < <condition_1>> Then
MsgBox "1 is greater than 4"
ElseIf < <condition_2 if condition_1 = FALSE >> Then
MsgBox "2 is greater than 4"
ElseIf < <condition_3 if condition_2 = FALSE >> Then
MsgBox "3 is greater than 4"
Else < <If_Everything_Fails>>:
MsgBox "1, 2 or 3 are lesser than 4"
End If
End Sub

In the example shown below, the IF condition is checked first. Since it


evaluates to FALSE, the first ELSEIF condition is evaluated, followed by the
second. Since none of them evaluate to TRUE, the steps mentioned in the
ELSE: condition are executed.
1
2
3
4
5
6
7
8
9
10
11

Sub IF_ELSEIF_ELSE_FUNCTION()
If 1 > 4 Then
MsgBox "1 is greater than 4"
ElseIf 2 > 4 Then
MsgBox "2 is greater than 4"
ElseIf 3 > 4 Then
MsgBox "3 is greater than 4"
Else:
MsgBox "1, 2 or 3 are lesser than 4"
End If
End Sub

Quick Tip How to make IF statements work faster


Both the pieces of code appear similar. The two ELSEIF conditions in the
second function have been swapped. Which one of the following pieces of
VBA code do you think executes faster?
1
2
3
4

Sub IF_NEED_FOR_SPEED_1()
t = Timer
For i = 1 To 100000000
If 1 > 4 Then

5
6
7
8
9
10
11

ElseIf 3 > 4 Then


ElseIf 5 > 4 Then
Else:
End If
Next i
MsgBox Timer - t
End Sub

OR
1
2
3
4
5
6
7
8
9
10
11

Sub IF_NEED_FOR_SPEED_2()
t = Timer
For i = 1 To 100000000
If 1 > 4 Then
ElseIf 5 > 4 Then
ElseIf 3 > 4 Then
Else:
End If
Next i
MsgBox Timer - t
End Sub

The answer is that the second one executes much faster than the first. Why?
Because the second one needs to application to go through lesser lines of
code before it finds a condition that evaluates to TRUE. Remember that the
first ELSEIF condition that if found TRUE gets executed and none of the other
conditions are evaluated, even if they were to also evaluate to TRUE. In the
first piece of the VBA code, the ELSEIF function on line 6 evaluates to TRUE
while in the second, line 5 meets the criteria. In essence, the more likely the
condition is to get evaluated to TRUE, the earlier it should be placed in the
VBA code, all else being the same

VBA Code Multiple Column Text to Column Conversion

Heres a bit of VBA code to convert Text to Column which will work across
multiple columns selected together at one go.

Heres the code:


Sub Multi_Column_Text_To_Column()
Dim selected_range, selected_range_individual_column() As Range
Dim one_to_how_many_columns, col_count As Long
Set selected_range = Selection
On Error GoTo err_occured:
'------------------------------------------------------------------------------------'one_to_how_many_columns value = Number of colums that a single column
should be split into
'Provide a sufficiently large value so as to prevent overlaps and overwriting
'------------------------------------------------------------------------------------one_to_how_many_columns = 10

Application.DisplayAlerts = False
If Not (TypeName(selected_range) = "Range") Then End
ReDim selected_range_individual_column(selected_range.Columns.Count - 1)
As Range
For col_count = LBound(selected_range_individual_column) To
UBound(selected_range_individual_column)
Set selected_range_individual_column(col_count) =
selected_range.Columns(col_count + 1)
'MsgBox "Value = " &
selected_range_individual_column(col_count).Cells(1, 1).Value
Next col_count
'Begin Text to Column conversion process by starting from Right and
proceeding left
For col_count = UBound(selected_range_individual_column) To
LBound(selected_range_individual_column) Step -1

If
Application.WorksheetFunction.CountIf(selected_range_individual_column(col
_count), "<>") = 0 Then GoTo next_loop:
'------------------------------------------------------------------------------------'DataType = xlDelimited or xlFixedWidth
'------------------------------------------------------------------------------------'If Data Type = xlDelimited then one has to specify the delimiting
characters
'
Change the boolean values for various delimiting characters such
as :
'
ConsecutiveDelimiter, Tab, Semicolon, Comma, Space and Other
tokens as per requirement
'If Data Type = xlFixedWidth then one has to specify the widths of the fields
using the FieldInfo Array.
'
This example specifies three widths for splitting into five columns
with each array
'
bit containing the cumulative sum of chars till the beginning of
each word
'
You will have to edit and modify (add more or delete) these values
as per need
'------------------------------------------------------------------------------------selected_range_individual_column(col_count).TextToColumns _
Destination:=selected_range.Cells(selected_range.Row,
one_to_how_many_columns * col_count + 1), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=True, _
Tab:=False, _
Semicolon:=False, _
Comma:=False, _
Space:=True, _
Other:=False, _
FieldInfo:=Array( _
Array(0, 1), _
Array(3, 1), _
Array(6, 1), _
Array(12, 1), _
Array(17, 1) _
), _
TrailingMinusNumbers:=True
next_loop:
Next col_count
err_occured:

Application.DisplayAlerts = True
End Sub

Microsoft Office Excel can convert only one column at a time. The range can
be many rows tall but no more than one column wide. Tray again by selecting
cells in one column only.
In the code above you can change:
one_to_how_many_columns = Determines how many columns should be
used as a gap to place the (split/converted) data when two consecutive
columns are converted.
DataType = xlDelimited or xlFixedWidth (The text to column feature has two
modes Character Delimited and Fixed Width.)
TextQualifier = xlDoubleQuote or xlSingleQuote or xlNone
Tab = True or False
Semicolon = True or False
Comma = True or False
Space = True or False
TrailingMinusNumbers = True or False
ConsecutiveDelimiter = True or False
You can download a sample worksheet with a example of multiple column
text to column here or click on the button below:

Heres the source data for all the examples:

Create a pivot table using a VBA Macro


The sample vba code shown below helps create a pivot table.
1Sub create_pivot()
2ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _
3SourceData:="Sheet3!data").CreatePivotTable _
4TableDestination:=ActiveSheet.Cells(10, 10), _
5TableName:="PivotTable1", _
6DefaultVersion:=xlPivotTableVersion10
7ActiveSheet.PivotTables(1).AddFields RowFields:="Name"
8ActiveSheet.PivotTables(1).PivotFields("Name").Orientation = xlDataField
9End sub
Parts of this VBA macro that you may want to change:
SourceData = Provide a range that contains the underlying data for the
pivot table. In its present form, the code simply create a pivot table by
picking up all the used cells present near the active cell.
TableName = Give the Pivot Table a name that you like
TableDestination = The cell where youd like to place the pivot table.
Format to use= [filename.xls]Sheet1!R1C1
Delete all Pivot Tables Using a VBA Macro
1
2
3
4
5
6

Sub Delete_All_Pivot_Tables_In_Sheet()
For Each pvt In ActiveSheet.PivotTables
pvt.PivotSelect "", xlDataAndLabel, True
Selection.ClearContents
Next pvt
End Sub

Refer to a Pivot Table directly within a VBA Macro


1
2
Sub Refer_Table()
3Dim pvt As PivotTable
Set pvt = ActiveSheet.PivotTables(1) 'Referring to Pivot Table with Index 1
4Set pvt = ActiveSheet.PivotTables("PivotTable1") 'Referring to pivot table
with Pivot Table Name
5MsgBox pvt.Name
MsgBox ActiveSheet.PivotTables(1).Name
6MsgBox ActiveSheet.PivotTables("PivotTable1").Name
End Sub
7
8
You can either set the pivot table to an object or refer it directly using the
index or the pivot table name.
Refer to a Pivot Table Field directly within a VBA Macro
1Sub Refer_Pivot_Table_Field()
2Dim pvt_fld As PivotField
3Set pvt_fld = ActiveSheet.PivotTables(1).PivotFields(1)
4Set pvt_fld = ActiveSheet.PivotTables("PivotTable1").PivotFields("Sales")
5MsgBox pvt_fld.Name
6MsgBox ActiveSheet.PivotTables(1).PivotFields(2).Name
7MsgBox ActiveSheet.PivotTables("PivotTable1").PivotFields("Sales").Name
8End Sub
Again, you can either set the pivot field to an object or refer it directly using
the index or the name of the pivot field in the macro.
Refer to a Pivot Item of a Pivot Field present in a Pivot Table directly
using a VBA Macro
1Sub Refer_Pivot_Table_Item()
Dim pvt_itm As PivotItem
2Set pvt_itm = ActiveSheet.PivotTables(1).PivotFields(1).PivotItems(1)
Set pvt_itm =
3ActiveSheet.PivotTables("PivotTable1").PivotFields("Name").PivotItems("Adri
an")
4MsgBox pvt_itm.Name
MsgBox ActiveSheet.PivotTables(1).PivotFields(1).PivotItems(1).Name

5
MsgBox
6
ActiveSheet.PivotTables("PivotTable1").PivotFields("Name").PivotItems("Adri
an")
7
End Sub
8
Remove Old (ghost) Items from a Pivot Table using VBA Macro
Often times you will items show up in the list drop down of a particular field
in pivot table even though those values do not exist in the pivot table. More
likely than not, these are old items left over from the earlier data in the pivot
tables cache and still continue to appear in the table. As a good practice, if
you have large amounts of data in a pivot table and that table gets updated
with fresh data frequently, you may want to call this procedure to clean up
the pivot table.
1 Sub Remove_Old_Items()
2 For Each pvt In ActiveSheet.PivotTables
3 pvt.PivotCache.MissingItemsLimit = xlMissingItemsNone
4 pvt.PivotCache.Refresh
5 Next pvt
6 End Sub
Refresh All Pivot Tables in a Workbook using VBA Macro
The classic case of refreshing all pivot tables in a workbook in one go. A must
when you have more than a handful of pivot tables in the workbook
1
2
3
4
5

Sub Refresh_All_Pivots_1()
For Each pvt In ActiveWorkbook.PivotCaches
pvt.Refresh
Next pvt
End sub

OR
1
2
3
4
5
6
7

Sub Refresh_All_Pivots_2()
For Each sht In ActiveWorkbook.Worksheets
For Each pt In sht.PivotTables
pt.RefreshTable
Next pt
Next sht
End Sub

Refresh All Pivot Tables in an Excel Sheet using VBA Macro


1
2
3
4
5

Sub Refresh_All_Pivots_In_Sheet()
For Each pvt In ActiveSheet.PivotTables
pvt.PivotCache.Refresh
Next pvt
End Sub

This is the simple method of expanding a pivot table so that the underlying
data is revealed. This requires that the pivot table store a copy of the
underlying data set with it for it to work well.
Extract Data (Expand) from a Pivot Table using a VBA Macro
1 Sub Extract_Data_From_Pivot()
2 For Each pvt In ActiveSheet.PivotTables
3 With pvt
4
.ColumnGrand = True
5
.RowGrand = True
6 End With
7 Set rng = pvt.DataBodyRange
8 rng.Cells(rng.Rows.Count, rng.Columns.Count).ShowDetail = True
9 Next pvt
10 End Sub
Remove or Include a Pivot Field in a Pivot Table using a VBA Macro
Often times we need to remove a particular field from the pivot table. The
following code will help you achieve it.
1
2
3
4
5
6
7

Sub Hide_Fields()
For Each pvt In ActiveSheet.PivotTables
For Each pvtfld In pvt.PivotFields
pvtfld.Orientation = xlHidden
Next pvtfld
Next pvt
End Sub

In the above code, we have tried to hide all pivot fields in a pivot table. You
may want to selectively remove fields by referring to them either by their
index values or by their names. Example:
ActiveSheet.PivotTables(PivotTable1).PivotFields(Name).Orientation =
xlHidden

To include the fields again and have them display in the pivot table, use this
code:
1
2
3
4
5
6
7
8
9
10
11

Sub Show_Fields()
For Each pvt In ActiveSheet.PivotTables
For Each pvtfld In pvt.PivotFields
'Use any of the four options listed here
'pvtfld.Orientation = xlRowField
'pvtfld.Orientation = xlColumnField
'pvtfld.Orientation = xlPageField
pvtfld.Orientation = xlDataField
Next pvtfld
Next pvt
End Sub

Hide Pivot Items of Pivot Field located in a Pivot Table using a VBA
Macro
The following code will help you turn off a field from the drop-down of a
particular field in a pivot table
1
2
3
4
5
6
7
8
9
10

Sub Hide_Items()
On Error Resume Next
For Each pvt In ActiveSheet.PivotTables
For Each pf In pvt.PivotFields
For Each pit In pf.PivotItems
pit.Visible = False
Next pit
Next pf
Next pvt
End Sub

By default, atleast one pivot item needs to be left turned if you decide to
hide items in the drop down of a field in a pivot table. Other wise you will
have excel throwing an error which says : Run-time error 1004: Unable to
set the Visible property of the PivotItem class. To ensure that we do not have
the error blocking the code during runtime, we insert the On Error Resume
Next in our code. (You may want to read more about error handling in VBA
here). To make the fields show again, simply turn them on by replacing the
pit.Visible = False statement with pit.Visible = true.
Moving and change orientation of Pivot Fields in a Pivot Table using
VBA Macro
1
2

Sub Move_Fields_Of_Pivot_Table()
For Each pvt In ActiveSheet.PivotTables

3
4
5
6
7
8
9
10
11
12
13

For Each pvtfld In pvt.PivotFields


pvtfld.Orientation = xlHidden
Next pvtfld
Next pvt
For Each pvt In ActiveSheet.PivotTables
pvt.PivotFields("Target").Orientation = xlDataField
pvt.PivotFields("Product").Orientation = xlRowField
pvt.PivotFields("Month").Orientation = xlColumnField
pvt.PivotFields("Manager").Orientation = xlPageField
Next pvt
End Sub

Reduce time taken to update a pivot table when using a VBA macro
Pivot tables can be notoriously slow when you work with large data sets in
VBA. Moving, updating and hiding items can a long time to happen. To
reduce update and response time when working with Pivot Tables in VBA, try
setting the update option to manual. Manual update can reduce the time
taken to update and work with a pivot table by around 10% for very small
tables (say 10 rows in source data) to as much as 75% in large tables (with
more than 50,000 rows in source data).
1Sub Set_Manual_Update_On
2ActiveSheet.PivotTables(1).ManualUpdate = True 'At the beginning of code
3'YOUR CODE HERE
4ActiveSheet.PivotTables(1).ManualUpdate = False 'At the end of code
5End Sub
You can test the improvement in speed by say comparing both the pieces of
VBA code shown below. The first piece of the code will run much slower than
the later.
1
2
3
4
5
6
7
8
9
10
11
12

Sub Manual_Update_Off()
t = Timer
For i = 1 To 20
On Error Resume Next
For Each pf In ActiveSheet.PivotTables(1).PivotFields
For Each pit In pf.PivotItems
pit.Visible = False
Next pit
Next pf
Next i
MsgBox Timer - t
End Sub

This one will work much faster.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Sub Manual_Update_On()
t = Timer
ActiveSheet.PivotTables(1).ManualUpdate = True
For i = 1 To 20
On Error Resume Next
For Each pf In ActiveSheet.PivotTables(1).PivotFields
For Each pit In pf.PivotItems
pit.Visible = False
Next pit
Next pf
Next i
ActiveSheet.PivotTables(1).ManualUpdate = False
MsgBox Timer - t
End Sub

You can download an example of the pivot table and vba macro code
here or click on the button below:

Вам также может понравиться