Analyzing Data with Microsoft Query and PivotTables in Microsoft Excel

Presented by Tim Lebel

Tim Lebel is the Group Product Planning Manager with the Microsoft® Excel group helping define the future of Excel. Tim came to Microsoft in October of 1991. Prior to joining Microsoft, he spent eight years at Ashton-Tate where he worked as product manager of dBASE. In his four years at Microsoft, Tim has contributed to the launch of Microsoft Excel 4.0, 5.0, and Microsoft Excel 95 and has been a key contributor to the data access features you see today in Microsoft Excel.

Introduction

Spreadsheets have grown from simple number-crunching tools into a more general purpose desktop tool for viewing as well as analyzing data. And Microsoft Excel is one of the big reasons for this. With sophisticated tools added to the spreadsheet over the years, users are now able to get at most data in an organization and utilize the spreadsheet as a tool to view and analyze that data. Microsoft Excel 5.0 contains some of the most sophisticated and powerful analysis tools available today on Personal Computers. While at Microsoft, I came across a paper written by Joel Spolsky (former design engineer for Excel) which summed it up well. It is called "A New Vision for Client/server Computing. Here is a slightly modified version of that. It can be summed up like this:

Think of all the printed reports in your company. Now think, wouldn't it be much more useful if those reports came out as Excel spreadsheets? Sure, you can print them out if you want, but you can do so much more! This is how you're going to be competitive in the next decade, and Microsoft can take you there.

A New Vision for Client/Server Computing

The state of client/server computing today is a fraud. Client/server computing hasn't brought about the major increase in competitiveness that was promised. Today's typical client/server applications are functionally identical to their mainframe predecessors, with the addition of some pretty screen fonts.

Microsoft Excel will lead a major revolution in client-server computing. We will introduce the world to a major shift in paradigm that combines the best of distributed systems with the best of personal productivity applications. This white paper introduces the philosophy that will bring about this revolution. It is a remarkable opportunity for Microsoft, if we can get it right. It means much more than Information At Your Fingertips. It is a revolutionary way that allows knowledge workers to go far beyond the traditional boundaries of how they look at data.

Today, when most people think of "client-server," they think of pretty GUI front-ends talking to server databases. However spiffy those front ends may be, the underlying metaphor still remains the same as it was in the days of 3270 terminals running CICS screens. This metaphor is as outdated as the computers it runs on. We need a new computing metaphor: one in which personal productivity applications, especially spreadsheets, serve as the clients in client-server systems.

A Concise History of the Universe

In the beginning, there was ibm. And ibm made huge computers that filled up large air-conditioned rooms and required special plumbing to keep them from going up in flames. A priestly class cared for these systems in white coats. If you weren't a priest, you couldn't use the computer.

One day, someone noticed that these big computers might do a good job of keeping track of airline reservations. Imagine if reservations agents could make reservations by typing them directly into the computer! They could also check seat availability, order special meals, and even automatically send your luggage on its merry way to Kalamazoo when you're on your way to Acapulco. American Airlines had hundreds of reservations agents in those days, so they attached hundreds of terminals to their mainframes. Mainframes were the dinosaurs that ruled the earth.

The microprocessor changed all that. Personal microcomputers evolved in a radically different way than mainframes. In the PC model, Personal Productivity was the keyword. Networks and connectivity were an afterthought. Word processors, spreadsheets, and single-user databases ruled the desktop. But there was a big problem with PCs. There were still some crucial computer applications that couldn't be accomplished with PCs, such as multiuser databases and email. ibm smugly convinced itself that there would always be a market for mainframes.

This problem was solved in the 1990s, when PCs starting getting networked. All the pundits started talking about client/server computing. Client/server computing meant the end of the mainframe, because now all kinds of applications, especially multiuser databases and email, could be accomplished on networks of PCs. Yay!

"OK," you ask. "How does this client/server stuff work?" I'll give you the classic example. Listen closely, because this is where it gets interesting. You have a multiuser application to build – maybe it's email, but more likely it's a multiuser database. Here's how you build it so that it works on a network of cheapo PCs. First, put a server on a really big PC and put that in the middle of the room. Now, write client applications that have glitzy easy-to-use user interfaces, with online help, lots o' fonts, and 256 color bitmaps of the company logo. Connect clients to server with some twisted pair. Great. The client deals with the hard work of dealing with the actual user, while the server only has to actually manage the data and make sure nobody tries to do anything nasty to it.

What do client applications look like? Well, basically, they are forms-based packages. You have a form, people fill it out, then they push a button and poof all their data goes up to the server. There are lots of pretty dialogs that you can use to search, filter, and maybe even sort the data.

Look at a classic example of this client/server model: Microsoft Access. Here's what Access gives you:

Guess what? It's a big fraud. Step back for a second and ask yourself, honestly, what do PC databases do that those big bad mainframe programs didn't do? Not much. There are some pretty fonts. Maybe things are easier. It's easier to create an Access (or VB) form than it was to create a cics screen. And defining a report is much easier. That's nice. But you know what? The model is exactly the same. We still assume that people like to create big fat printed reports which list all their data in black and white. We still assume that showing one record at a time, on a screen, is the way people like to look data. Face it: an Access form is fundamentally the same as a cics screen, plus the addition of pretty fonts. An Access report is fundamentally the same as a report created in 1963 using RPG II, plus the addition of pretty fonts.

Most client/server applications are really just mainframe applications with lots o' fonts.

In the meantime, nobody seems to be asking the existential questions. Why the heck do you need printed reports, anyway? And why can't client/server applications take advantage of the real benefits of PCs (spreadsheets, word processors)?

Reports Must Die

Talk to all the people you know who have created PC database applications. Ask them if they have defined any reports. You know what? They probably haven't. Printed detail reports are honestly pretty useless.

Before you get argumentative, there are still a couple of things printed reports may be good for. Paper is still a better display medium than the screen. It is much easier to read text printed on a laser printer than to read text on the screen. But remember, we're not talking about reading Dante's Inferno, here – we're talking about a detail report from a database. NOBODY reads detail reports from a database. If they do, they probably shouldn't be. So, if you really tried hard, you might convince me that printed reports are crucial for mailing labels. Whoopee. OK, so they're crucial for mailing labels. Other than that, throw them in the trash. Just build your Access application without any reports, roll it out to your users, and then decide if you really need printed reports. Betcha you don't.

In the mainframe days, people created big printed reports, but it wasn't because they wanted to read them. They printed them so that they could make big fat printouts which could be distributed to various information workers. These information workers either ignored the reports completely, or used them as a reference book, like a phone book. Sometimes they took them home so their kids could make confetti. On a very rare occasion, they would look something up. Nobody actually read the entire reports unless they were autistic like Dustin Hoffman in Rainman who read the entire phone book. So who cares if they are easier to read when they are laser printed. I'll just look up the data I need on the screen, thonk ye very much.

Which brings us to another really, really important idea. Read this twice because this idea is at the heart of where we should be going.

Online reports are infinitely more useful than printed reports.

Let's take an example of that, from real life. Last week I was looking for an apartment in Manhattan. The New York Times has about three pages, literally thousands of ads, for apartments in Manhattan. These classified ads are effectively a printed report. Let's look at how I used this report to help find an apartment.

I had some important constraints in looking for an apartment. I knew roughly the area I wanted: the West Side, somewhere between 70th and 100th street. I knew the size of apartment I could afford: about 27 square feet. And I knew a few things that I considered desirable ("vu", "drmn", "eik", "marble bath") and some things that were undesirable ("brkr", "walkup", "quaint").

Now, the New York Times apartment ads are printed in order of cross street. So I could ignore all the ads from the 1s until the 70s. But that's about all they are ordered by. So I had to read every single ad, effectively disqualifying ads as I went along. Since I was sure that I wanted to live on the West Side I skipped over all the ones that had an E next to the street number. Since I knew I couldn't afford more than about a thousand dollars, I ignored the ones that mentioned Donald Trump or Leona Helmsley. This little exercise took me a couple of hours.

Imagine that the New York Times apartment ads were delivered in Excel 5 format on a floppy disk. Wow! Now, I could narrow down my search in about five seconds using Autofilter or even just sorting by price. But I could do more interesting things, too:

Not only could I have done this, but I could have done it fairly quickly. But notice an amazing fact—typical client/server applications would not have allowed me to perform these analyses! Suppose the New York Times had hired Oracle to write an application to provide on-line classified ads. Oracle decided to do it using Visual Basic, ODBC, and Oracle 7. Sounds pretty normal. What does that VB app have? Well, I'll betcha it has two forms. The first form is a criteria screen where I'm supposed to fill in everything I'm looking for. There is a listbox to choose different neighborhoods. There are checkboxes for drmn and rvr vu. When I fill out this form, I click the OK button and I get to another screen which lists the apartments that meet the criteria I'm looking for. You know what? I'll betcha that custom $500,000 app doesn't allow me to do half of the neat things that I could do with Excel.

Anyway, hitting the pavement was getting fairly tiresome, so I finally called up a real estate broker. These are the folks who charge you literally thousands of dollars for "finding the perfect apartment." Actually, it's a big rip off. The broker I called was a company called Feathered Nest which was supposed to have hundreds of apartment listings. They were famous for having been one of the first brokers to computerize, so presumably, they could zero in on the right apartment quickly. Really? BALONEY. I told them what I wanted. They dutifully wrote it down on a piece of paper. "We'll get right back to you," they said. I was sure they would type this stuff into a computer, get back a listing of apartments that matched, and call me right back, so I sat near the phone all afternoon waiting for their call.

It took them two days to finally call me back and say, "sorry, we can't find anything that matches your requirements in the computer. You're going to have to relax your parameters." That's really what they said! "Relax your parameters." Now, this really pissed me off. "Relax This!" I said, in a close approximation of a Scottish soccer fan accent. First, they work on commission. Of COURSE they wanted me to pay more. But I knew for a fact that my parameters were not at all unreasonable; there were dozens of listings in the New York Times that matched.

But I was even more pissed off that it took them two days to plug things into the computer, and they didn't even get a very good answer back! A good answer would be, "Gee, we don't have anything that matches, but would you be willing to go as high as 96th street? There are a few apartments that match up there." Another good answer would have been "Gee, prices are so high these days on the West Side. Have you thought about living on the East Side? You could save a lot of money." A bad answer is "nothing matches, you lose." I asked them the following question: "OK, there's nothing for under $1000. So what are the lowest price apartments that are available?" They couldn't even answer this question. They kept saying "How high can you afford to go?" I don't think their computer even had an option to list the cheapest apartments. Honestly, I don't know if Feathered Nest is using a client/server computer or something a little bit more obsolete, but it sure as heck wasn't solving their customer's problems.

So, printed reports (the New York Times paper edition) suck, online client/server is hardly better, but detailed reports in Excel would be really, really nice.

Homework

Think of some database application you've worked with recently, and think about how Excel spreadsheets would be a better presentation medium than printed reports or typical client/server tools. What forms of analysis could you do that you couldn't do before? How would this provide tangible benefits?

I've illustrated that spreadsheets are the ideal medium for detailed databases for the case of apartment hunting, and in last night's homework, you came up with another example. There is a general principle involved here, and, at the risk of sounding academic, I'd like to bring it up:

Joel's Theorum: "Knowledge workers can contribute more to their organizations if they get their data as spreadsheets."

When knowledge workers get printed reports, they can't do any further analysis beyond what the designer of the report had in mind. If the New York Times doesn't have a section where it compares the average price of a 1 bedroom apartment on the East Side to the average price of a 1 bedroom apartment on the West Side, there is no way to automatically compute it. If the New York Times editors never thought it would be useful to show how much more (on average) you have to pay for a doorman building, there is no way to compute that either.

The same thing applies to business reports. If the report designer never thought it would be interesting to figure out how many pizza pies are damaged per manager, you can stare at that Damaged Pizza Report all day long and never realize that Bozo is wrecking about 3 times as many pizzas as all the other night managers put together. Knowledge workers who use printed reports will never be able to find connections, look for relationships, and track things in different ways. Thus, Joel's Theorum states quite forcefully that knowledge workers can contribute more if they get their data as spreadsheets. Companies who do this will be able to compete more effectively in a rapidly-changing world. And not just a little bit more effectively – a lot more effectively.

Here's a Drama In Real Life™ to illustrate that. In the late 1980s, a decade of overbuilding caused real estate prices to collapse all over the United States. Banks that had made a lot of real estate loans were suddenly in very serious trouble. Every banker wanted to know the answer to a simple question: how much exposure do I have to real estate? Seems like an easy question, right?

As it turns out, it was an incredibly difficult question to answer! Why? Because until then, it had never occurred to anyone to create a report that showed how much exposure the bank had to different sectors. It's not that the information wasn't in the computers – it was. But the report hadn't been created. For many banks, it took months to answer this simple question. One large bank in New England brought in a team of consultants for six months to figure out the answer.

Suppose the data had been easily accessible to Excel. Instead of printing a 7,000 page report listing every outstanding loan, the bank created a mongo spreadsheet listing every outstanding loan. Now, in minutes, a bank executive can figure out:

You can do this stuff easily, using AutoFilter, sorting, pivot tables, trendlines, and the usual Excel recalc stuff.

Now you can quickly start to do interesting things, like figure out if you have to tighten credit so as to prevent a cash crunch. This can all be done in minutes, in an interactive fashion. The bank executive can explore different possibilities; try what-if scenarios (what if the Yen drops? What if Dukakis is elected?) and so on and so forth. Clearly, an executive with these capabilities is going to be able to contribute more to the organization than an executive using printed reports and predefined EIS screens. Companies have to have this capability. Without it, they will not be able to compete against companies that do.

The good news is that Microsoft Excel can deliver this today. The power of Data Access and PivotTables in Excel make it easy to implement this vision.

Glossary

3270

A typical "smart" terminal for ibm mainframes. See CICS.

CICS

(Pronounced "kicks".) An IBM software environment popular on mainframe systems. Under CICS, the programmer designs complete 80 x 24 screens with labels and input fields. The terminal (usually a 3270 or related terminal) is responsible for displaying the screen, filling the fields with initial values, and accepting the users input and edits. When the user presses a Send key, the entire screen of data is sent to the mainframe in a batch. This is supposed to be more efficient than UNIX™-type systems where the main CPU has to handle individual keystrokes itself. The idea is that under CICS the terminal device is smart enough to handle all the editing operations so that the mainframe only has to worry about the actual transaction processing.

Legacy Systems

Polite word for mainframes. These systems are often extremely complex and mission critical. Big companies with legacy systems would usually rather build a pretty GUI type environment around the legacy system rather than starting from scratch. See also screen scraping.

Screen Scraping

One way of putting a pretty face on legacy cics systems. The idea is that you have a fancy gui front end which acts like a virtual 3270 terminal to the back end. The front end knows exactly where the fields are on the cics forms and stuffs characters into those fields or reads it out. Theoretically, this sounds like a nice way to put some lipstick on a legacy system. In reality these projects never work very well and it is impossible to add any flexibility beyond what the underlying cics application already has.

Acknowledgments

Many thanks to Joel Spolsky (author), and he thanks Eric Michelman, Corey Salka, Adam Bosworth, Andrew Layman, Craig Unger, Andrew Kwatinetz, and Don Koscheka, without whose ideas and listening Joel's ideas would never have come this far. Special thanks to Andy Short who helped Joel reframe the question by being a great active listener.

Bonus Section

As an added Bonus I am including a section on how to automate PivotTables in Excel 5.0. You should be sufficiently convinced by now that PivotTables in Excel and dynamic, online reports are infinitely more useful than printed reports. Here is an introduction (written last year by Eric Wells) to using VBA with PivotTables.

I. Programmatic Creation of Pivot Tables

    Open file Lesson1.xls (select File-Open and then select Lesson1.xls).
  1. Click on the Control Screen tab. Right-click on the Control Screen tab, select Insert, and then select Worksheet.
  2. Right-click on the tab of the new sheet, select Rename, and enter "Pivot Sheet." With Pivot Sheet displayed, select Tools-Options—then select the View tab and turn off gridlines.
  3. Right-click on the Pivot Sheet tab and select Insert-Module to insert Module1. Select the top line of the module and select Tools-Record Macro-Mark Position for Recording.
  4. Click the Datasheet tab. Select Tools-Record Macro-Record New Macro—select OK to the dialog displayed.
  5. Select Data-Pivot Table.
  6. Select Microsoft Excel List or Database in the 1st dialog and then select Next.
  7. Make sure the database range has been properly selected in the 2nd dialog and then select Next.
  8. In the 3rd dialog, put Region and Prod_cat in the Page field, Country in the Row field, Product in the column field and Revenue in the data field. Double-click on the Sum of Revenue button in the Data field, select Number, then select the first Currency format. Select OK-OK-Next.
  9. In the fourth dialog select cell B10 on the Pivot Sheet for the for the Pivot Table Starting Cell. Deselect the Autoformat option—Leave all other options as they are. Select Finish.
  10. Select Tools-Record Macro-Stop Recording.
  11. On the Pivot Sheet: adjust the width of Column A to 3, column B to 17, column C to 15 and columns D-Z to 12.
  12. Click on the Module1 tab. The recorded Macro should appear as follows:
    Sub Macro2()
    ActiveSheet.PivotTableWizard SourceType:=xlDatabase, SourceData:= _
    "Datasheet!$A$1:$K$226", TableDestination:= _
    "'[Book2]Pivot Sheet'!R13C2", TableName:="Pivottable1", _
    HasAutoFormat:=False
    ActiveSheet.PivotTables("Pivottable1").AddFields RowFields:="COUNTRY", _
    ColumnFields:="PRODUCT", PageFields:=Array("PROD_CAT", "REGION")
    With ActiveSheet.PivotTables("Pivottable1").PivotFields("REVENUE")
    .Orientation = xlDataField
    .NumberFormat = "$#,##0_);($#,##0)"
    End With
    End Sub
  13. Change the name of the recorded macro to Create_pivot_table. Delete the reference to Book2 (or any other file name) on the 4th line of the macro. Add an autoformat command to the end of the macro (changes marked in bold):
    Sub Create_pivot_table()
    ActiveSheet.PivotTableWizard SourceType:=xlDatabase, SourceData:= _
    "Datasheet!$A$1:$K$226", TableDestination:= _
    "'Pivot Sheet'!R13C2", TableName:="Pivottable1", _
    HasAutoFormat:=False
    ActiveSheet.PivotTables("Pivottable1").AddFields RowFields:="COUNTRY", _
    ColumnFields:="PRODUCT", PageFields:=Array("PROD_CAT", "REGION")
    With ActiveSheet.PivotTables("Pivottable1").PivotFields("REVENUE")
    .Orientation = xlDataField
    .NumberFormat = "$#,##0_);($#,##0)"
    End With
    range("b13").autoformat format:=xlclassic3, width:=false
    End Sub
  14. Click on the Pivot Sheet tab. Select range A8:Z200 - in the range name box in the upper left, enter Pivot_range.
  15. Click on the Module1 tab and make the following changes to the Create_pivot_table macro:
    Sub Create_pivot_table()
    range("pivot_range").clear
    ActiveSheet.PivotTableWizard SourceType:=xlDatabase, SourceData:= _
    "Datasheet!$A$1:$K$226", TableDestination:= _
    "'Pivot Sheet'!R13C2", TableName:="Pivottable1", _
    HasAutoFormat:=False
    ActiveSheet.PivotTables("Pivottable1").AddFields RowFields:="COUNTRY", _
    ColumnFields:="PRODUCT", PageFields:=Array("PROD_CAT", "REGION")
    With ActiveSheet.PivotTables("Pivottable1").PivotFields("REVENUE")
    .Orientation = xlDataField
    .NumberFormat = "$#,##0_);($#,##0)"
    End With
    range("b13").autoformat format:=xlclassic3, width:=false
    dim piv as object
    set piv = worksheets("pivot sheet").pivottables("pivottable1")
    with piv
    .pivotfields("region").currentpage = "Africa"
    .pivotfields("prod_cat").currentpage = "Strings"
    end with
    range("a1").select
    End Sub
  16. Click the Pivot Sheet Tab. Test the macro by selecting Tools-Macro-Create_pivot_table.
  17. Click on the Module1 tab. Enter the following macro after the Create_pivot_table macro:
    sub go_to_pivot_sheet
    application.screenupdating = false
    worksheets("pivot sheet").select
    create_pivot_table
    with activewindow
    .displayhorizontalscrollbar = true
    .displayverticalscrollbar = true
    end with
    end sub
  18. Click on the Control Screen tab. Right-click on the 1993 Sales button and select Assign Macro. Assign macro Go_to_pivot_table to the button. Click the 1993 Sales button to test.
  19. Click the Module1 tab. Enter the following macro:
    sub go_to_control_screen
    application.screenupdating = false
    worksheets("control screen").select
    with activewindow
    .displayhorizontalscrollbar = false
    .displayverticalscrollbar = false
    end with
    end sub
  20. Click the Pivot Sheet tab. Click the Create Button tool on the drawing toolbar and draw a button at cell E3 on the Pivot Sheet. Assign macro Go_to_control_screen to the button and change the caption of the button to "Control." Click the Control button to test.

II. Using On-sheet Controls to Control Pivot Tables

    Click the Pivot Sheet tab to go to the Pivot Sheet. Display the Forms toolbar by selecting View-Toolbars-Forms. Click the Drop-Down tool and draw a Drop-Down list box starting at cell E10.
  1. In cell H2, enter "Data_output"; in cell H3, enter "Data_input; in cell I3, enter "Revenue"; in cell I4, enter "Profit."
  2. Select cell I2. In the range name box in the upper left, enter "data_output."
  3. Select cells I3:I4. In the range name box in the upper left, enter "data_input."
  4. Right-click the Drop-Down list box in cell E10. Select Format Object and then select the Control tab—enter Data_input for Input Range and Data_output for Cell Link. Select OK. Scroll to the left so that column A is displayed.
  5. Right-click the Module1 tab and select Insert-Module. Enter the following macro in Module2:
    Sub change_pivot()
    Application.ScreenUpdating = False
    Dim piv As Object
    Set piv = Worksheets("pivot sheet").PivotTables("pivottable1")
    Dim data_output As Object
    Set data_output = Worksheets("pivot sheet").Range("data_output")
    piv.DataBodyRange.PivotField.Orientation = xlHidden
    Select Case data_output.Value
    Case 1
    piv.PivotFields("revenue").Orientation = xlDataField
    Case 2
    piv.PivotFields("profit").Orientation = xlDataField
    End Select
    piv.DataBodyRange.PivotField.NumberFormat = "$#,##0_);($#,##0)"
    End Sub
  6. Click the Pivot Sheet Tab. Right-click the Drop-Down list box in cell E10. Select Assign Macro and then select Change_pivot. Select OK.
  7. Test the Drop-Down list box by alternately selecting Revenue and Profit.

III. Using On-sheet Controls with Charts

    Right-click the Pivot Sheet tab and select Insert-Worksheet.
  1. Right-click the tab of the new sheet and select Rename. Enter "Chart Sheet".
  2. Click the Pivot Sheet tab. Select the range B14:E19. Display the Standard toolbar by selecting View-Toolbars-Standard. Click the ChartWizard tool on the Standard toolbar. Click the Chart Sheet tab. Draw a large box on the Chart Sheet - filling the entire area of the displayed portion of the sheet. Select Next. Select 3D Column, select Next. Select Format 6, select Finish.
  3. Turn off all displayed toolbars. Select Tools-Options-View tab and turn off:
    • Gridlines
    • Row/column headers
    • Outline symbols
    • Horizontal scroll bar
    • Vertical scroll bar
    • Sheet tabs
    • Formula bar
    • Status bar
  4. Size the chart so that is takes up the entire portion of the displayed area of the sheet.
  5. Double-click on the chart to edit the chart. Delete the legend.
  6. Select Format-Chart Type-Options. Select the Options Tab. Enter 400 for Gap Depth; 200 for Chart Depth; 200 for Gap Width. Select OK.
  7. Select Format-3D View. Enter 2 for Elevation; 38 for Rotation; 30 for Perspective.
  8. Select the Plot area and drag it all of the way over to the right-hand side. Drag the top border of the Plot area down .5 inches.
  9. Select the X axis on the chart and click the right mouse button. Select Format Axis. Select the Font tab and select 8 Point, Bold, Times New Roman. Repeat the same font formatting on the Y and Z axes.
  10. Select the Chart Walls, click the right mouse button and select Format Walls. On the Patterns tab, select the light gray box (2nd from right on 2nd row). Apply the same formatting to the floor of the chart.
  11. Select the Chart area. Click the right mouse button and select Format Chart Area. Select the Patterns tab and under Fill, select the dark gray box (furthest right on the second row).
  12. Close the chart window. Right click the on-sheet chart object and select Format Object. Select the Patterns tab and select the dark gray box for Fill (furthest on the right on the second row).
  13. Select the chart. Select Edit Copy. Select Edit Paste. There are now 2 charts, one on top of the other.
  14. Double-click the top chart. Select Format-Chart Type. Select 3D Surface, then OK. Close the chart window. Enter a new name for the top chart in the range name box in the upper left - enter "sur_chart" (if the range name box is not displayed, select View-Formula Bar). Right-click the top chart and select Send To Back.
  15. The column chart should now be displayed. Click on the top chart and enter a new name in the range name box in the upper left - enter "col_chart". Right-click the column chart and select Send To Back.
  16. Display the Forms toolbar by selecting View-Toolbars-Forms. Draw two option buttons in the upper left portion of the screen - label the top button "Column" and the bottom button "Surface". Select both option buttons (by holding down the control key and the shift key), and click the right mouse button. Select Format Object and then select the Patterns tab. For Border, select Automatic, and for Fill, select the light gray box (2nd from the right on the 2nd row). Select OK.
  17. Select Tools-Options and turn on the following:
    • Row/column headings
    • Horizontal scroll bar
    • Vertical scroll bar
    • Sheet tabs
    • Formula bar
    • Status bar
  18. Enter "chart_selection" in cell M2. Select cell M3. In the range name box in the upper left, enter "chart_selection". Scroll to the left so that column A is displayed.
  19. Right-click on one of the option buttons. Select Format Object and then select the Control tab. Enter Chart_selection for the Cell Link. Select OK.
  20. Right-click the Module2 tab and select Insert-Module. Enter the following macro on Module3:
    Sub select_chart()
            Application.ScreenUpdating = False
            Dim col_chart As Object
            Set col_chart = Worksheets("chart sheet").DrawingObjects("col_chart")
            Dim sur_chart As Object
            Set sur_chart = Worksheets("chart sheet").DrawingObjects("sur_chart")
            Dim chart_selection As Object
            Set chart_selection = Worksheets("chart sheet").Range("chart_selection")
            Select Case chart_selection.Value
                    Case 1
                        col_chart.Top = 0
                        sur_chart.Top = 500
                    Case 2
                        col_chart.Top = 500
                        sur_chart.Top = 0
            End Select
            Range("a1").Select
    End Sub
  21. Click the Chart Sheet tab. Select both the Column and Surface option buttons (by using control-shift) and then click the right mouse button, select Assign Macro and then select Select_Chart - select OK. Test the macro by alternately clicking on the Column and Surface option buttons.
  22. Click on the Module3 tab and enter the following macro:
    Sub go_to_chart_sheet()
            Application.ScreenUpdating = False
            Worksheets("chart sheet").Select
            With ActiveWindow
                    .DisplayHorizontalScrollBar = False
                    .DisplayVerticalScrollBar = False
            End With
    End Sub
  23. Click the Pivot Sheet tab. Click the Create Button tool on the Forms toolbar and draw a button below the Control button on the Pivot Sheet. Assign the Go_to_chart_sheet macro to the button and change the caption to "Chart". Click the button to test the macro.
  24. Click the Module3 tab. Enter the following macro:
    Sub go_back_to_pivot_sheet()
            Application.ScreenUpdating = False
            Worksheets("pivot sheet").Select
            With ActiveWindow
                    .DisplayHorizontalScrollBar = True
                    .DisplayVerticalScrollBar = True
            End With
    End Sub    
  25. Click the Chart Sheet tab. Click the Create Button tool on the Forms toolbar and draw a button in the lower left hand portion of the screen. Assign the Go_back_to_pivot_sheet macro to the button and change the caption to "Back". Click the button to test the macro.

IV. Using On-Sheet Controls with Pivot Tables and Charts

    Click the Chart Sheet tab. Display the Forms toolbar by selecting View-Toolbars-Forms. Click the Drop-Down tool and draw a Drop-Down list box above the chart.
  1. Turn on the Horizontal and Vertical Scroll Bars by selecting Tools-Options, then select the View tab and click Horizontal Scroll Bar and Vertical Scroll Bar.
  2. Enter "Region_output" in cell M4. Enter "Region_input" in cell M5. In cell N5, enter Africa; in cell N6, enter Asia; in cell N7, enter Europe; in cell N8, enter Latin America; in cell N9, enter North America.
  3. Select cells N5:N9. Enter "Region_input" in the name range box. Select cell N4. Enter "Region_output" in the name range box. Scroll to the left so that column A is displayed.
  4. Select the Drop-Down list box. Click the Right Mouse button and select Format Object. Select the Control tab and enter Region_input for Input Range and Region_output for Cell Link. Select OK.
  5. Right-click the Module3 tab and select Insert-Module. Enter the following macro in Module4:
    Sub change_region()
            Application.ScreenUpdating = False
            Dim piv As Object
            Set piv = Worksheets("pivot sheet") _
            .PivotTables("pivottable1").PivotFields("region")
            Dim region_output As Object
            Set region_output = Worksheets("chart sheet").Range("region_output")
            Select Case region_output.Value
                    Case 1
                        piv.CurrentPage = "Africa"
                    Case 2
                        piv.CurrentPage = "Asia"
                    Case 3
                        piv.CurrentPage = "Europe"
                    Case 4
                        piv.CurrentPage = "Latin America"
                    Case 5
                        piv.CurrentPage = "North America"
            End Select
    End Sub
  6. Right-click the Drop-Down list box. Select Assign Macro and select Change_region. Test the macro by selecting different values from the Drop-Down.

V. Controlling Microsoft Word through OLE Automation

    Click the Pivot Sheet tab. Select cells B14:F20 on the Pivot Sheet. Enter "Data_Table" in the range name box.
  1. Right-click the Module4 tab and select Insert-Module. Enter the following macro on Module5:
    Dim ms_word As Object
    Sub create_report()
    Set ms_word = CreateObject("word.basic")
    Dim piv As Object
    Set piv = Worksheets("pivot sheet").PivotTables("pivottable1")
    Dim col_chart As Object
    Set col_chart = Worksheets("chart sheet").DrawingObjects("col_chart")
    Dim data_table As Object
    Set data_table = Worksheets("pivot sheet").Range("data_table")
    With ms_word
    .appmaximize
    .filenewDefault
    .insertpara
    .insertpara
    .Insert "Encore Musical Instruments"
    .insertpara
    .lineup 1
    .startofline
    .endofline 1
    .Bold
    .fontsize 18
    .centerpara
    .linedown 1
    .insertpara
    .insertpara
    End With
    For Each x In Worksheets("chart sheet").Range("region_input")
    piv.PivotFields("region").CurrentPage = x
    region_name = x.text
    data_table.Copy
    With ms_word
    .insertpara
    .insertpara
    .insert (region_name)
    .insertpara
    .lineup 1
    .startofline
    .endofline 1
    .bold
    .fontsize 16
    .linedown 1
    .insertpara
    .insertpara
    .editpastespecial 0, 0, 0, "excel.sheet.5", "pict"
    .insertpara
    .insertpara
    End With
    col_chart.Copy
    With ms_word
    .editpastespecial 0, 0, 0, "excel.chart.5", "pict"
    .insertbreak 0
    End With
    Next x
    End Sub
  2. Click the Control Screen tab. Right-click the Create Report button and select Assign Macro. Assign macro create_report to the button. Then click the Create Report button to test the macro.

VI. Auto_Open, Auto_Close, and Environment settings

    Click the Chart Sheet tab. Right Click the tab and select Insert-Worksheet. Right-click the tab of the new sheet, select Rename, and enter "Variables".
  1. Enter "Formula_bar" in cell A1. Enter "Status_bar" in cell A2. Enter "Tool_bars" in cell A3. Select cells A1:B3. Select Insert-Name-Create-Left Column. Select OK.
  2. Right-click the Module5 tab and select Insert-Module. Enter the following macro on Module6:
    Sub auto_open()
            Application.ScreenUpdating = False
            Application.Caption = "Encore Musical Instruments"
            ActiveWindow.Caption = ""
            If Application.DisplayFormulaBar = True Then
                    Worksheets("variables").Range("formula_bar") = 1
            Else
                    Worksheets("variables").Range("formula_bar") = 0
            End If
            If Application.DisplayStatusBar = True Then
                    Worksheets("variables").Range("status_bar") = 1
            Else
                    Worksheets("variables").Range("status_bar") = 0
            End If
            Application.DisplayFormulaBar = False
            Application.DisplayStatusBar = False
            toolbar_num = 1
            Dim toolbar_range As Object
            Set toolbar_range = Worksheets("variables").Range("tool_bars")
            For Each tool_bar In Application.Toolbars
                    If tool_bar.Visible = True Then
                        toolbar_range.Offset(toolbar_num, 0) = 1
                    Else
                        toolbar_range.Offset(toolbar_num, 0) = 0
                    End If
                    If (toolbar_num <> 14 And toolbar_num <> 15 _
                And toolbar_num <> 16 _
                And toolbar_num <> 17 And toolbar_num <> 18) Then
                        tool_bar.Visible = False
                    Else 
                toolbar_range.Offset(toolbar_num, 0) = 0
                    End If
                    toolbar_num = toolbar_num + 1
            Next tool_bar
            Worksheets("control screen").Range("a1").Select
            Application.ScreenUpdating = True
    End Sub    
  3. Enter the following macro onto module6:
    Sub Auto_Close()
            Application.DisplayAlerts = False
            If Worksheets("variables").Range("formula_bar") = 1 Then
                    Application.DisplayFormulaBar = True
            End If
            If Worksheets("variables").Range("status_bar") = 1 Then
                    Application.DisplayStatusBar = True
            End If
            toolbar_num = 1
            Dim toolbar_range As Object
            Set toolbar_range = Worksheets("variables").Range("tool_bars")
            For Each tool_bar In Application.Toolbars
                    If toolbar_range.Offset(toolbar_num, 0) = 1 Then
                        tool_bar.Visible = True
                    End If
                    toolbar_range.Offset(toolbar_num, 0) = 0
                    toolbar_num = toolbar_num + 1
            Next tool_bar
            Application.Caption = "Microsoft Excel"
    End Sub
  4. Enter the following macro on Module6:
    Sub quit_application()
        Application.DisplayAlerts = False
        Application.Quit
    End Sub
  5. Click the Control Screen tab. Right-click the Quit button and select Assign Macro. Assign the Quit_application macro to the button.
  6. Click the Chart Sheet Tab. Turn off all toolbars. Select Tools-Options-View and turn off the following:
    • Gridlines
    • Row/column headings
    • Outline symbols
    • Horizontal scroll bar
    • Vertical scroll bar
    • Sheet tabs
    • Formula bar
    • Status bar
  7. Click the Back button on the Chart Sheet. Repeat the steps in number 5 above on the Pivot Sheet.
  8. Click the Control Button to go to the Control Screen. Repeat the steps in number 5 above on the Control Screen. Save the File.

© 1995 Microsoft Corporation.

THESE MATERIALS ARE PROVIDED "AS-IS," FOR INFORMATIONAL PURPOSES ONLY.

NEITHER MICROSOFT NOR ITS SUPPLIERS MAKES ANY WARRANTY, EXPRESS OR IMPLIED WITH RESPECT TO THE CONTENT OF THESE MATERIALS OR THE ACCURACY OF ANY INFORMATION CONTAINED HEREIN, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW EXCLUSIONS OF IMPLIED WARRANTIES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.

NEITHER MICROSOFT NOR ITS SUPPLIERS SHALL HAVE ANY LIABILITY FOR ANY DAMAGES WHATSOEVER INCLUDING CONSEQUENTIAL INCIDENTAL, DIRECT, INDIRECT, SPECIAL, AND LOSS PROFITS. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES THE ABOVE LIMITATION MAY NOT APPLY TO YOU. IN ANY EVENT, MICROSOFT'S AND ITS SUPPLIERS' ENTIRE LIABILITY IN ANY MANNER ARISING OUT OF THESE MATERIALS, WHETHER BY TORT, CONTRACT, OR OTHERWISE SHALL NOT EXCEED THE SUGGESTED RETAIL PRICE OF THESE MATERIALS.