Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (5.72 MB, 490 trang )
currently equal to Nothing, in which case the Union function will (unfortunately) return
Nothing. In other words:
Application.Union(Something, Nothing) = Nothing
Example 19-10. The SelectIfDifferent Procedure
Private Sub SelectIfDifferent()
Dim rngMatch As Range
Dim vCellValue As Variant
Dim vPreviousCellValue As Variant
Dim cMatches As Integer
Dim oCell As Object
Dim cRows As Integer, cColumns As Integer
Dim r As Integer, c As Integer
' Get row and column count (one of which is 1)
cColumns = rngSearch.Columns.Count
cRows = rngSearch.Rows.Count
' Start search
cMatches = 0
Set rngMatch = Nothing
AM
FL
Y
For r = 1 To cRows
For c = 1 To cColumns
Set oCell = rngSearch.Cells(r, c)
vCellValue = oCell.Value
vCellValue = CStr(vCellValue)
TE
If r = 1 And c = 1 Then
' Include first cell
If rngMatch Is Nothing Then
Set rngMatch = oCell
Else
Set rngMatch = Application.Union(rngMatch, oCell)
End If
cMatches = cMatches + 1
' Save value for next comparison
vPreviousCellValue = vCellValue
Else
' Do comparison with previous cell
vCellValue = rngSearch.Cells(r, c).Value
vCellValue = CStr(vCellValue)
If vCellValue <> vPreviousCellValue Then
If rngMatch Is Nothing Then
Set rngMatch = oCell
Else
Set rngMatch = Application.Union(rngMatch, oCell)
End If
cMatches = cMatches + 1
End If
' Save value for next comparion
vPreviousCellValue = vCellValue
End If
Next ' column
287 ®
Team-Fly
Next
' row
' Select the range
If cMatches > 0 Then
rngMatch.Select
cmdUndo.Enabled = False
Else
MsgBox "No matching cells. Selection will not be changed.",
vbInformation
cmdUndo.Enabled = False
End If
End Sub
The SelectIfSame procedure, which is shown in Example 19-11, is very similar to the
SelectIfDifferent procedure. One significant difference is that we do not include the first
cell.
Example 19-11. The SelectIfSame Procedure
Private Sub SelectIfSame()
Dim
Dim
Dim
Dim
Dim
Dim
Dim
rngMatch As Range
vCellValue As Variant
vPreviousCellValue As Variant
cMatches As Integer
oCell As Object
cRows As Integer, cColumns As Integer
r As Integer, c As Integer
' Get row and column count (one of which is 1)
cColumns = rngSearch.Columns.Count
cRows = rngSearch.Rows.Count
' Start search
cMatches = 0
Set rngMatch = Nothing
For r = 1 To cRows
For c = 1 To cColumns
Set oCell = rngSearch.Cells(r, c)
vCellValue = oCell.Value
vCellValue = CStr(vCellValue)
If r = 1 And c = 1 Then
' Save first value for next comparion
vPreviousCellValue = vCellValue
Else
' Do comparison with previous cell
vCellValue = rngSearch.Cells(r, c).Value
vCellValue = CStr(vCellValue)
If vCellValue = vPreviousCellValue Then
If rngMatch Is Nothing Then
Set rngMatch = oCell
Else
Set rngMatch = Application.Union(rngMatch, oCell)
End If
cMatches = cMatches + 1
End If
' Save value for next comparion
288
vPreviousCellValue = vCellValue
End If
Next ' column
Next ' row
' Select the range
If cMatches > 0 Then
rngMatch.Select
cmdUndo.Enabled = False
Else
MsgBox "No matching cells. Selection will not be changed.",
vbInformation
cmdUndo.Enabled = False
End If
End Sub
The SelectIfEmpty and SelectIfNotEmpty procedures are almost identical.
SelectIfEmpty is shown in Example 19-12.
Example 19-12. The SelectIfEmpty Procedure
Private Sub SelectIfEmpty()
Dim rngMatch As Range
Dim cMatches As Integer
Dim oCell As Object
Dim cRows As Integer, cColumns As Integer
Dim r As Integer, c As Integer
' Get row and column count (one of which is 1)
cColumns = rngSearch.Columns.Count
cRows = rngSearch.Rows.Count
' Start search
cMatches = 0
Set rngMatch = Nothing
For r = 1 To cRows
For c = 1 To cColumns
Set oCell = rngSearch.Cells(r, c)
If IsEmpty(oCell) Then
If rngMatch Is Nothing Then
Set rngMatch = oCell
Else
Set rngMatch = Application.Union(rngMatch, oCell)
End If
cMatches = cMatches + 1
End If
Next ' column
Next ' row
' Select the range
If cMatches > 0 Then
rngMatch.Select
cmdUndo.Enabled = False
Else
MsgBox "No matching cells. Selection will not be changed.",
vbInformation
cmdUndo.Enabled = False
289
End If
End Sub
To get the SelectIfNotEmpty procedure, just change the line:
If IsEmpty(oCell) Then
to:
If Not IsEmpty(oCell) Then
Finally, the CompleteColumns and CompleteRows procedures are called from the
corresponding command-button Click events and are very similar. CompleteColumns is shown
in Example 19-13.
Example 19-13. The cmdCompleteColumns_Click Procedure
Private Sub cmdCompleteColumns_Click()
' For each selected cell, select the entire column
Dim oCell As Object
Dim rngNew As Range
Set rngNew = Nothing
For Each oCell In Selection
If rngNew Is Nothing Then
Set rngNew = oCell.EntireColumn
Else
Set rngNew = Union(rngNew, oCell.EntireColumn)
End If
Next
rngNew.Select
cmdUndo.Enabled = True
End Sub
To get CompleteRows, just replace EntireColumn by EntireRow in two places.
290
Chapter 20. Pivot Tables
In this chapter, we take a look at pivot tables and how to create and format them using code.
20.1 Pivot Tables
While we are assuming that the reader is familiar with the basics of Excel, it probably would not
hurt to review the concept of a pivot table (or PivotTable) quickly.
PivotTables are one of the most powerful features in Excel. They are designed to accomplish three
main tasks:
•
•
•
Import external data
Aggregate data; for example, sum, count, or average the data
Display the data in interesting ways
PivotTables can use data from external sources, as well as from one or more Excel tables. For
instance, the data for a PivotTable can come from an Access database. However, setting up Excel
to import external data requires that the appropriate data source drivers be installed on the user's
computer. Moreover, there are significant limitations on Excel's ability to import data through
PivotTables. For instance, all strings are limited to a length of 255 characters, which makes using
SQL to define a data source much more difficult.
All in all, importing data using a PivotTable can be problematic. Furthermore, we always have the
option of importing the required data directly to an Excel worksheet (using a variety of more
sophisticated methods, such as DAO and the GetRows method) and then creating the PivotTable
from the worksheet. Accordingly, we will restrict our discussion to using Excel data as the
PivotTable source.
Table 20-1, which represents sales from a fictitious fast food company that has both company and
franchise stores, shows the first half of the data that we will use to build our pivot table. The actual
source table is an Excel worksheet that contains twice the number of rows as Table 20-1, the
additional rows being the analogous data for the year 1997. (Thus, the first column in the
remainder of the table contains the year 1997.)
Year
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
Table 20-1. Source Data for PivotTable (for 1998)
Period Store Code
Store City
Store Type Transactions
1
BO-1
BOSTON
Company
3881
1
BO-2
BOSTON
Company
3789
1
BO-3
BOSTON
Company
3877
1
BO-4
BOSTON
Company
3862
1
BO-5
BOSTON
Franchise
4013
1
BO-6
BOSTON
Franchise
3620
2
BO-1
BOSTON
Company
3948
2
BO-2
BOSTON
Company
3878
2
BO-3
BOSTON
Company
3911
2
BO-4
BOSTON
Company
3926
2
BO-5
BOSTON
Franchise
3990
291
Sales
$6,248.00
$5,722.00
$6,278.00
$6,123.00
$6,861.00
$5,039.00
$6,468.00
$6,301.00
$6,390.00
$6,438.00
$6,767.00
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
1998
2
3
3
3
3
3
3
4
4
4
4
4
4
1
1
1
1
1
1
2
2
2
2
2
2
3
3
3
3
3
3
4
4
4
4
4
4
1
1
1
1
1
1
2
2
2
BO-6
BO-1
BO-2
BO-3
BO-4
BO-5
BO-6
BO-1
BO-2
BO-3
BO-4
BO-5
BO-6
LA-1
LA-2
LA-3
LA-4
LA-5
LA-6
LA-1
LA-2
LA-3
LA-4
LA-5
LA-6
LA-1
LA-2
LA-3
LA-4
LA-5
LA-6
LA-1
LA-2
LA-3
LA-4
LA-5
LA-6
NY-1
NY-2
NY-3
NY-4
NY-5
NY-6
NY-1
NY-2
NY-3
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
BOSTON
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
LOS ANGELES
NEW YORK
NEW YORK
NEW YORK
NEW YORK
NEW YORK
NEW YORK
NEW YORK
NEW YORK
NEW YORK
292
Franchise
Company
Company
Company
Company
Franchise
Franchise
Company
Company
Company
Company
Franchise
Franchise
Franchise
Company
Company
Franchise
Franchise
Franchise
Franchise
Company
Company
Franchise
Franchise
Franchise
Franchise
Company
Company
Franchise
Franchise
Franchise
Franchise
Company
Company
Franchise
Franchise
Franchise
Company
Franchise
Franchise
Company
Franchise
Franchise
Company
Franchise
Franchise
3615
3936
3857
3898
3949
3617
3624
3853
3891
3892
3966
3595
3611
8259
9140
9727
9494
10644
10649
9066
9789
9814
9917
10617
10190
9531
9698
9771
10232
10561
10924
9310
9496
9596
10050
10440
10778
6390
7016
7293
7037
7815
6935
6954
7531
7486
$5,091.00
$6,307.00
$6,153.00
$6,319.00
$6,453.00
$5,052.00
$5,111.00
$6,021.00
$6,333.00
$6,289.00
$6,571.00
$4,945.00
$5,051.00
$29,267.00
$31,947.00
$35,405.00
$33,830.00
$39,971.00
$40,077.00
$32,595.00
$35,217.00
$35,455.00
$35,926.00
$39,424.00
$38,387.00
$33,966.00
$34,419.00
$34,494.00
$37,315.00
$39,141.00
$41,938.00
$33,202.00
$33,910.00
$34,500.00
$37,274.00
$38,304.00
$40,965.00
$19,890.00
$22,229.00
$24,077.00
$22,704.00
$26,962.00
$22,925.00
$22,389.00
$25,324.00
$24,753.00