Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
136
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

PROGRAMMING EXCEL 453

ListBox2.Items.Add(ListBox1.Items(wrd))

End If

Application.DoEvents()

Next

End Sub

Programming Excel

Excel is probably the most popular application among users and developers. Actually, there are countless programmers who earn their living by doing everything with Excel—they even write limited database applications using Excel as a data store. I’m not suggesting you start using Excel as a universal tool, but it’s very likely that, at some point, you’ll be called to import data from an Excel spreadsheet into your applications. In most situations, the tabular format of Excel isn’t what you really need, and you’ll have to write code to import the data into your applications.

Another good reason for using Excel’s object model is to format and print tabular data. An application that generates reports on a regular basis (every day, for example) can create XLS files that can be used for neat printouts, as well as for archiving purposes.

To use Excel’s object model in your code, you must add a reference to the Microsoft Excel 9.0 Object Library item to your project. Open the Project menu, select Add Reference, and double-click the name of the Excel library. Then click OK to add an instance of Excel’s object model to your application. To contact Excel from within your VB application, declare a variable of the Excel.Application type. The following declaration must appear outside the procedures that use it:

Dim EXL As New Excel.Application

EXL represents a new instance of Excel, which runs in the background.

To access Excel’s functionality, you can use a hierarchy of objects, which are described next. The objects that Excel exposes have different names from those of Word, but they form an equally sensible and structured hierarchy for accessing data stored in a tabular arrangement. Just as Word’s basic unit of information is the text segment (not characters or words), Excel’s basic unit of information is also called Range. A Range object can contain a single cell or an entire worksheet (and everything in between).

Two important methods of Excel’s Application object are the Calculate method, which recalculates all open worksheets, and the Evaluate method, which evaluates math expressions and returns the result. The following statement returns a numeric value that is the result of the math expression passed to the Evaluate method as argument:

Dim result As Double

result = EXL.Evaluate(“cos(3/1.091)*log(3.499)”)

You can also use variables in your expressions as long as you store their values in specific cells and use the addresses of these cells in the expression. You will see shortly how to assign formulas to specific cells. Doing so allows you to calculate complicated expressions that involve other cells as well.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

454 Chapter 10 AUTOMATING MICROSOFT OFFICE APPLICATIONS

The Worksheets Collection and the Worksheet Object

Each workbook in Excel contains one or more worksheets. The Worksheets collection, which is similar to Word’s Documents collection, contains a Worksheet object for each worksheet in the current workbook. To add a new worksheet, use the Add method, whose syntax is as follows:

Application.Worksheets.Add(before, after, count, type)

The before and after arguments let you specify the order of the new worksheet in the workbook. You can specify one of the two arguments; if you omit both, the new worksheet is inserted before the active worksheet (and also becomes active). The type argument specifies the new worksheet’s type and can have one of the values in Table 10.1.

Table 10.1: The XLSheetType Enumeration

Value

Description

xlWorksheet

The default value

xlExcel4MacroSheet

A worksheet with Excel 4 macros

xlExcel4IntlMacroSheet

A worksheet with Excel 4 international macros

xlChart

A worksheet with Excel charts

xlDialogSheet

A worksheet with Excel dialogs

 

 

To create a new worksheet, declare a variable of the Worksheet type and then add it to the Worksheets collection. Sheets belongs to Workbooks, so you must use a statement like the following one to create a new Workbook and then add a Worksheet to it:

Dim WSheet As New Excel.Worksheet()

WSheet = EXL.Workbooks.Add.Worksheets.Add

You can also open an existing workbook with the Open method of the Workbooks collection:

EXL.Workbooks.Open(“c:\Sample.xls”)

Then you can access the worksheets from within your code and populate them. By default, each new workbooks contains three worksheets, named “Sheet1,” “Sheet2,” and “Sheet3.” To place a value in the first cell of the second worksheet, use the following statement:

WSheet = EXL.Workbooks.Item(1).Worksheets(“Sheet2”)

WSheet.Cells(1, 1) = “TOP LEFT CELL”

You can also add worksheets to the current Workbook with the Add method of the Worksheets collection. The following statements add a new worksheet and place a value to the top-left cell:

WSheet = EXL.ActiveWorkbook.Worksheets.Add()

WSheet.Cells(1, 1) = “First Cell”

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

PROGRAMMING EXCEL 455

To access an individual worksheet, use the Worksheet collection’s Item method, passing the index or the worksheet’s name as an argument. If the second worksheet is named SalesData.xls, the two following expressions are equivalent:

Application.Worksheets.Item(2)

Application.Worksheets.Item(“SalesData”)

The Range Object

Excel is an application for manipulating units of information stored in cells, but the basic object for accessing the contents of a worksheet is the Range object, which is a property of the Worksheet object. There are several ways to identify a Range, but here’s the basic syntax of the Range method:

Worksheet.Range(cell1:cell2)

Here, cell1 and cell2 are the addresses of the two cells that delimit a rectangular area on the work- sheet—the top-left and bottom-right corners of the selection. In this section, we are going to use the standard Excel notation, which is a number for the row and a letter for the column—for example, C3 or A103. To select the 10×10 top-left section of the active Worksheet, use the expression:

Worksheet.Range(“A1:J10”)

To retrieve a single cell as a Range object, use the Cells method, whose syntax is:

Worksheet.Cells(row, col)

The Range property is an object, and among the properties it exposes is the Range property. The Range.Range property is a relative reference to another cell. In the following code segment, the first line returns the cell D8. The second line returns a cell that is three columns to the right and five rows down from the previous cell—that is, G13:

range1 = Worksheet.Range(4, 8) range2 = range1.Range(3, 5)

The second line can also be written as:

range2 = range1.Range(“C5”)

Finally, the Rows and Columns methods return an entire row or column by number. The following expressions return the third row and the fourth column as Row and Column objects, respectively:

Worksheet.Rows(3)

Worksheet.Columns(“D”)

The Row object contains a single row, and you can access this row’s cells with the Cells property, which accepts as argument a single coordinate—the cell’s order in the row. The same is true for columns. The following statement retrieves the third cell in the second row:

Console.WriteLine(WSheet.Rows(2).Cells(3).Text)

The Range object is not a collection, but you can access individual cells in a Range object through its Cells method. The Cells method accepts as arguments the row and column coordinates

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

456 Chapter 10 AUTOMATING MICROSOFT OFFICE APPLICATIONS

of a cell and returns its value. The indices are 1-based. The Cells(i, j).Text property returns the cell’s contents as a string, and the Cells(i, j).Value property returns the cell’s contents as a string (if it’s text) or as a numeric value (if it’s numeric).

Another way to work with cells is to make a selection and access the properties and methods of the Selection object. To create a Selection object (which represents the cells that are highlighted with the mouse when Excel’s window is visible), use the Range object’s Select method:

Range(“A2:D2”).Select

This statement creates a new Selection object. You can also assign names to the ranges and access them later in your code by their names. The following statement selects the same range as the preceding one and names it:

myRange = Range(“A2:D2”).Select

Because a worksheet has only one selection, you don’t have to specify any arguments. To change the appearance of the selection, for instance, use the Font property:

Selection.Font.Bold = True

Selection.Font.Size = 13

Notice that the selection is always rectangular; you can’t select nonadjoining cells on a worksheet. However, you can specify an area consisting of multiple ranges. The following statements combine two different ranges with the Union method and assign them to a new Range object:

Set Titles = Worksheet.Range (“A1:A10”)

Set Totals = Worksheet.Range (“A100:A110”)

Set CommonRange = Union(Titles, Totals)

CommonRange.Font.Bold = True

The Union method returns a Range object, which you can use to manipulate all the cells in the Titles and Totals ranges together. For example, you can apply common formatting to all the cells in the CommonRange object, as shown above.

The Members of the Range Object

The Range object provides a large number of properties and methods, which can’t be discussed in the context of this chapter. One basic property is the Cells property, which is a collection of the cells that make up the current range. The first cell in the Range is Range.Cells(1, 1), and the last is

Range.Cells(Range.Cells.Rows, Range.Cells.Columns)

All of Excel’s collections are 1-based, rather than 0-based.

You can also access an entire row or column in the selection with the EntireRow and EntireColumn properties. These properties are also objects, and they expose a Cells property, similar to the Row and Column objects. To access an individual cell in either collection, use a single index. The HorizontalAlignment and VerticalAlignment properties let you specify how the cells’ contents will be aligned in available space. Look up the corresponding enumerations in the Object Browser to find out the possible settings for these properties.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

PROGRAMMING EXCEL 457

The Clear method resets all the cells of the Range object, and the Copy method creates a copy of the Range object. If you want to fill a Range with identical values, use the methods FillDown, FillLeft, FillRight, and FillUp.

You can also sort the cells in a Range object by calling its Sort method, which rearranges the rows in the Range object according to the sorting criteria. Its syntax is:

Sort(key1, order1, key2, type, order2, key3, order3, header, orderCustom, _ matchCase, orientation, sortMethod)

The arguments of the Sort method allow you to specify the same settings you would normally specify through Excel’s Sort dialog box, shown in Figure 10.3. To bring up this dialog box in Excel, select a range of cells, and choose the Data Sort command.

Figure 10.3

The Sort method’s arguments specify the same settings as this dialog box.

key1, key2, and key3 are the columns according to which the range will be sorted. If you specify more than one column, the range will be sorted according to the key1 column. Rows with

identical values in this column will then be sorted according to the key2 column. The order1, order2, and order3 arguments determine the sort order of the three key columns. Their values are members of the XLSortOrder enumeration and can be set to xlAscending (the default) or xlDescending.

The type argument specifies which cells will be sorted and is used only when sorting PivotTables. Its value can be one of the following members of the XLSortType enumeration: xlSortLabels or xlSortValues. The header determines whether the first row should be treated as a header row or not; header rows are not sorted. This argument is one of the following members of the XLYesNoGuess enumeration: xlGuess, xlNo, or xlYes. The orientation argument, finally, lets you determine whether you want to sort rows (xlSortRows, which is the default value) or columns (xlSortColumns).

To sort the first 20 columns and 2 rows of the first worksheet, use the following statements:

Worksheets.(“Sheet1”).Range(“A1:C20”).Sort _

Key1:=Worksheets(“Sheet1”).Range(“A1”), _

Key2:=Worksheets(“Sheet1”).Range(“B1”)

In the section “The ExcelDemo Project,” later in this chapter, you’ll find a demonstration of the Sort method.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

458 Chapter 10 AUTOMATING MICROSOFT OFFICE APPLICATIONS

The UsedRange Object

Another useful member of the Excel object model is the UsedRange object, which represents a rectangular section of the active worksheet containing all the non-empty cells. The UsedRange object is a Range object and exposes all the members of the Range object. The Rows and Columns properties are collections that contain the UsedRange object’s rows and columns, respectively. The number of

columns and rows are given by the properties UsedRange.Columns.Count and UsedRange.Rows.Count,

and the total number of used cells is given by UsedRange.Cells.Count. To access these cells, use the expression UsedRange.Cells(row, col); you can’t use the A1 notation with the Cells collection.

To iterate through all the non-empty cells on the current worksheet, use the following loop. This loop scans the cells of myRange row by row and prints the indices and value of each cell in the Output window:

Dim myRange As Excel.Range = Wsheet.UsedRange Dim row, col As Integer

For row = 1 To myRange.Rows.count

For col = 1 To myRange.Columns.count Console.WriteLine(“[“ & row & “, “ & col & “ : “ & _

myRange.cells(row, col).value & “]”)

Next Next

Of course, not all the cells in the UsedRange are non-empty; some of them may be empty. All cells outside the UsedRange, however, are empty.

In the following section, we are going to create a new spreadsheet from within a Visual Basic application, insert data and formulas, and then print the document.

VB.NET at Work: The ExcelDemo Project

The ExcelDemo application’s Create Spreadsheet button demonstrates how to access a worksheet, populate it with data, and then format the data (see Figure 10.4). The program starts by setting the AppExcel object variable, which references the Excel application.

Figure 10.4

Contacting Excel’s object model from within a VB application

The new spreadsheet is populated and formatted with the statements shown in Listing 10.9. The code uses the Cells collection to access individual cells and assign their values. To format a group of cells, it creates a Range object that contains all the cells to be formatted alike, selects the range, and then manipulates the cells through the Selection object. Finally, it uses the UsedRange object to print the values of all non-empty cells in the Output window.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

PROGRAMMING EXCEL 459

Listing 10.9: Preparing a New Spreadsheet

Dim EXL As New Excel.Application()

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click If EXL Is Nothing Then

MsgBox(“Couldn’t start Excel”) Exit Sub

End If

Dim WSheet As New excel.Worksheet() WSheet = EXL.Workbooks.Add.Worksheets.Add With WSheet

.Cells(2, 1).Value = “1st Quarter”

.Cells(2, 2).Value = “2nd Quarter”

.Cells(2, 3).Value = “3rd Quarter”

.Cells(2, 4).Value = “4th Quarter”

.Cells(2, 5).Value = “Year Total”

.Cells(3, 1).Value = 123.45

.Cells(3, 2).Value = 435.56

.Cells(3, 3).Value = 376.25

.Cells(3, 4).Value = 425.75

.Range(“A2:E2”).Select() With EXL.Selection.Font

.Name = “Verdana”

.FontStyle = “Bold”

.Size = 12 End With

End With WSheet.Range(“A2:E2”).Select() EXL.Selection.Columns.AutoFit() WSheet.Range(“A2:E2”).Select() With EXL.Selection

.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter End With

Format numbers WSheet.Range(“A3:E3”).Select() With EXL.Selection.Font

.Name = “Verdana”

.FontStyle = “Regular”

.Size = 11 End With

WSheet.Cells(3, 5).Value = “=Sum(A3:D3)” Dim R As Excel.Range

R = WSheet.UsedRange Dim row, col As Integer

For col = 1 To R.Columns.count For row = 1 To R.Rows.count

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

460 Chapter 10 AUTOMATING MICROSOFT OFFICE APPLICATIONS

TextBox1.AppendText (R.cells(row, col).value & vbTab)

Next

TextBox1.AppendText(vbCrLf)

Next

End Sub

While the worksheet is being populated and formatted, Excel is running in the background. Users can’t see Excel, although they will notice activity (the disk is spinning, and the pointer assumes an hourglass shape for several seconds).

After the grid is populated, we can read the values from the spreadsheet and displays them in two columns on the TextBox control of the ExcelDemo form. To read the data, you can use different technique. The code in Listing 10.10 creates a selection on the spreadsheet and then brings it into the Visual Basic application in a single move. The selected cells are read into the CData object with the following statements:

AppExcel.Range(“A2:E3”).Select

Set CData = AppExcel.Selection

CData is a Range object that holds the selected cells. Then you can use straight VB code to iterate through the elements of the CData object and create the two columns of text, shown in Figure 10.5.

Listing 10.10: Importing Data from Excel

Private Sub Button2_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button2.Click

TextBox1.Clear()

Dim WSheet As New Excel.Worksheet()

WSheet = EXL.Workbooks.Open(“C:\TEST.XLS”).Worksheets.Item(1)

EXL.Range(“A2:E3”).Select()

Dim CData As Excel.Range

CData = EXL.Selection

Dim iCol, iRow As Integer

For iCol = 1 To 5

For iRow = 0 To 1

TextBox1.AppendText(CData(iRow, iCol).value & vbTab

Next

TextBox1.AppendText(vbCrLf)

Next

EXL.Workbooks.Close()

End Sub

The ExcelDemo project also demonstrates how to use the Sort method (Listing 10.11), even though the range is too small. We’ll treat the 10 cells on the worksheet as a range and sort them according to the values in the first column.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

PROGRAMMING EXCEL 461

Figure 10.5

This spreadsheet was created by the ExcelDemo application, using Excel’s objects.

Listing 10.11: The Sort and Import Data Button

Private Sub Button3_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button3.Click Dim WSheet As New Excel.Worksheet()

WSheet = EXL.Workbooks.Open(“C:\TEST.XLS”).Worksheets.Item(1) EXL.Range(“A2:E3”).Select()

Dim CData As Excel.Range CData = EXL.Selection

CData.Sort(Key1:=CData.Range(“A2”), order1:=Excel.XLSortOrder.xlAscending) TextBox1.Clear()

Dim iCol, iRow As Integer For iCol = 1 To 5

For iRow = 0 To 1

TextBox1.AppendText(CData(iRow, iCol).value & vbTab) Next

TextBox1.AppendText(vbCrLf) Next

EXL.Workbooks.Close() End Sub

If you change the order1 argument’s value to Excel.XLSortOrder.xlDescending, the rows won’t be rearranged, because they happen to already be in descending order. You can add more rows to the worksheet and sort a larger range. You should also set the header argument to Excel.XLYesNoGuess.xlYes, so that the first row will be treated as header and won’t be sorted along with the other rows.

To sort the same range by column, specify the orientation argument to the Sort method. To experiment with the various sort options, change the call to the Sort method in the previous listing to the following:

CData.Sort(Key1:=CData.Range(“A2”), order1:=Excel.XlSortOrder.xlAscending, _ orientation:=Excel.XlSortOrientation.xlSortRows)

If you print the values of the UsedRange without sorting, they will appear on the TextBox in the following order:

1st Quarter

2nd Quarter

3rd Quarter

4th Quarter

Year Total

123.45

435.56

376.25

425.75

1361.01

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com