
- •Using Your Sybex Electronic Book
- •Acknowledgments
- •Contents at a Glance
- •Introduction
- •Who Should Read This Book?
- •How About the Advanced Topics?
- •The Structure of the Book
- •How to Reach the Author
- •The Integrated Development Environment
- •The Start Page
- •Project Types
- •Your First VB Application
- •Making the Application More Robust
- •Making the Application More User-Friendly
- •The IDE Components
- •The IDE Menu
- •The Toolbox Window
- •The Solution Explorer
- •The Properties Window
- •The Output Window
- •The Command Window
- •The Task List Window
- •Environment Options
- •A Few Common Properties
- •A Few Common Events
- •A Few Common Methods
- •Building a Console Application
- •Summary
- •Building a Loan Calculator
- •How the Loan Application Works
- •Designing the User Interface
- •Programming the Loan Application
- •Validating the Data
- •Building a Math Calculator
- •Designing the User Interface
- •Programming the MathCalculator App
- •Adding More Features
- •Exception Handling
- •Taking the LoanCalculator to the Web
- •Working with Multiple Forms
- •Working with Multiple Projects
- •Executable Files
- •Distributing an Application
- •VB.NET at Work: Creating a Windows Installer
- •Finishing the Windows Installer
- •Running the Windows Installer
- •Verifying the Installation
- •Summary
- •Variables
- •Declaring Variables
- •Types of Variables
- •Converting Variable Types
- •User-Defined Data Types
- •Examining Variable Types
- •Why Declare Variables?
- •A Variable’s Scope
- •The Lifetime of a Variable
- •Constants
- •Arrays
- •Declaring Arrays
- •Initializing Arrays
- •Array Limits
- •Multidimensional Arrays
- •Dynamic Arrays
- •Arrays of Arrays
- •Variables as Objects
- •So, What’s an Object?
- •Formatting Numbers
- •Formatting Dates
- •Flow-Control Statements
- •Test Structures
- •Loop Structures
- •Nested Control Structures
- •The Exit Statement
- •Summary
- •Modular Coding
- •Subroutines
- •Functions
- •Arguments
- •Argument-Passing Mechanisms
- •Event-Handler Arguments
- •Passing an Unknown Number of Arguments
- •Named Arguments
- •More Types of Function Return Values
- •Overloading Functions
- •Summary
- •The Appearance of Forms
- •Properties of the Form Control
- •Placing Controls on Forms
- •Setting the TabOrder
- •VB.NET at Work: The Contacts Project
- •Anchoring and Docking
- •Loading and Showing Forms
- •The Startup Form
- •Controlling One Form from within Another
- •Forms vs. Dialog Boxes
- •VB.NET at Work: The MultipleForms Project
- •Designing Menus
- •The Menu Editor
- •Manipulating Menus at Runtime
- •Building Dynamic Forms at Runtime
- •The Form.Controls Collection
- •VB.NET at Work: The DynamicForm Project
- •Creating Event Handlers at Runtime
- •Summary
- •The TextBox Control
- •Basic Properties
- •Text-Manipulation Properties
- •Text-Selection Properties
- •Text-Selection Methods
- •Undoing Edits
- •VB.NET at Work: The TextPad Project
- •Capturing Keystrokes
- •The ListBox, CheckedListBox, and ComboBox Controls
- •Basic Properties
- •The Items Collection
- •VB.NET at Work: The ListDemo Project
- •Searching
- •The ComboBox Control
- •The ScrollBar and TrackBar Controls
- •The ScrollBar Control
- •The TrackBar Control
- •Summary
- •The Common Dialog Controls
- •Using the Common Dialog Controls
- •The Color Dialog Box
- •The Font Dialog Box
- •The Open and Save As Dialog Boxes
- •The Print Dialog Box
- •The RichTextBox Control
- •The RTF Language
- •Methods
- •Advanced Editing Features
- •Cutting and Pasting
- •Searching in a RichTextBox Control
- •Formatting URLs
- •VB.NET at Work: The RTFPad Project
- •Summary
- •What Is a Class?
- •Building the Minimal Class
- •Adding Code to the Minimal Class
- •Property Procedures
- •Customizing Default Members
- •Custom Enumerations
- •Using the SimpleClass in Other Projects
- •Firing Events
- •Shared Properties
- •Parsing a Filename String
- •Reusing the StringTools Class
- •Encapsulation and Abstraction
- •Inheritance
- •Inheriting Existing Classes
- •Polymorphism
- •The Shape Class
- •Object Constructors and Destructors
- •Instance and Shared Methods
- •Who Can Inherit What?
- •Parent Class Keywords
- •Derived Class Keyword
- •Parent Class Member Keywords
- •Derived Class Member Keyword
- •MyBase and MyClass
- •Summary
- •On Designing Windows Controls
- •Enhancing Existing Controls
- •Building the FocusedTextBox Control
- •Building Compound Controls
- •VB.NET at Work: The ColorEdit Control
- •VB.NET at Work: The Label3D Control
- •Raising Events
- •Using the Custom Control in Other Projects
- •VB.NET at Work: The Alarm Control
- •Designing Irregularly Shaped Controls
- •Designing Owner-Drawn Menus
- •Designing Owner-Drawn ListBox Controls
- •Using ActiveX Controls
- •Summary
- •Programming Word
- •Objects That Represent Text
- •The Documents Collection and the Document Object
- •Spell-Checking Documents
- •Programming Excel
- •The Worksheets Collection and the Worksheet Object
- •The Range Object
- •Using Excel as a Math Parser
- •Programming Outlook
- •Retrieving Information
- •Recursive Scanning of the Contacts Folder
- •Summary
- •Advanced Array Topics
- •Sorting Arrays
- •Searching Arrays
- •Other Array Operations
- •Array Limitations
- •The ArrayList Collection
- •Creating an ArrayList
- •Adding and Removing Items
- •The HashTable Collection
- •VB.NET at Work: The WordFrequencies Project
- •The SortedList Class
- •The IEnumerator and IComparer Interfaces
- •Enumerating Collections
- •Custom Sorting
- •Custom Sorting of a SortedList
- •The Serialization Class
- •Serializing Individual Objects
- •Serializing a Collection
- •Deserializing Objects
- •Summary
- •Handling Strings and Characters
- •The Char Class
- •The String Class
- •The StringBuilder Class
- •VB.NET at Work: The StringReversal Project
- •VB.NET at Work: The CountWords Project
- •Handling Dates
- •The DateTime Class
- •The TimeSpan Class
- •VB.NET at Work: Timing Operations
- •Summary
- •Accessing Folders and Files
- •The Directory Class
- •The File Class
- •The DirectoryInfo Class
- •The FileInfo Class
- •The Path Class
- •VB.NET at Work: The CustomExplorer Project
- •Accessing Files
- •The FileStream Object
- •The StreamWriter Object
- •The StreamReader Object
- •Sending Data to a File
- •The BinaryWriter Object
- •The BinaryReader Object
- •VB.NET at Work: The RecordSave Project
- •The FileSystemWatcher Component
- •Properties
- •Events
- •VB.NET at Work: The FileSystemWatcher Project
- •Summary
- •Displaying Images
- •The Image Object
- •Exchanging Images through the Clipboard
- •Drawing with GDI+
- •The Basic Drawing Objects
- •Drawing Shapes
- •Drawing Methods
- •Gradients
- •Coordinate Transformations
- •Specifying Transformations
- •VB.NET at Work: Plotting Functions
- •Bitmaps
- •Specifying Colors
- •Defining Colors
- •Processing Bitmaps
- •Summary
- •The Printing Objects
- •PrintDocument
- •PrintDialog
- •PageSetupDialog
- •PrintPreviewDialog
- •PrintPreviewControl
- •Printer and Page Properties
- •Page Geometry
- •Printing Examples
- •Printing Tabular Data
- •Printing Plain Text
- •Printing Bitmaps
- •Using the PrintPreviewControl
- •Summary
- •Examining the Advanced Controls
- •How Tree Structures Work
- •The ImageList Control
- •The TreeView Control
- •Adding New Items at Design Time
- •Adding New Items at Runtime
- •Assigning Images to Nodes
- •Scanning the TreeView Control
- •The ListView Control
- •The Columns Collection
- •The ListItem Object
- •The Items Collection
- •The SubItems Collection
- •Summary
- •Types of Errors
- •Design-Time Errors
- •Runtime Errors
- •Logic Errors
- •Exceptions and Structured Exception Handling
- •Studying an Exception
- •Getting a Handle on this Exception
- •Finally (!)
- •Customizing Exception Handling
- •Throwing Your Own Exceptions
- •Debugging
- •Breakpoints
- •Stepping Through
- •The Local and Watch Windows
- •Summary
- •Basic Concepts
- •Recursion in Real Life
- •A Simple Example
- •Recursion by Mistake
- •Scanning Folders Recursively
- •Describing a Recursive Procedure
- •Translating the Description to Code
- •The Stack Mechanism
- •Stack Defined
- •Recursive Programming and the Stack
- •Passing Arguments through the Stack
- •Special Issues in Recursive Programming
- •Knowing When to Use Recursive Programming
- •Summary
- •MDI Applications: The Basics
- •Building an MDI Application
- •Built-In Capabilities of MDI Applications
- •Accessing Child Forms
- •Ending an MDI Application
- •A Scrollable PictureBox
- •Summary
- •What Is a Database?
- •Relational Databases
- •Exploring the Northwind Database
- •Exploring the Pubs Database
- •Understanding Relations
- •The Server Explorer
- •Working with Tables
- •Relationships, Indices, and Constraints
- •Structured Query Language
- •Executing SQL Statements
- •Selection Queries
- •Calculated Fields
- •SQL Joins
- •Action Queries
- •The Query Builder
- •The Query Builder Interface
- •SQL at Work: Calculating Sums
- •SQL at Work: Counting Rows
- •Limiting the Selection
- •Parameterized Queries
- •Calculated Columns
- •Specifying Left, Right, and Inner Joins
- •Stored Procedures
- •Summary
- •How About XML?
- •Creating a DataSet
- •The DataGrid Control
- •Data Binding
- •VB.NET at Work: The ViewEditCustomers Project
- •Binding Complex Controls
- •Programming the DataAdapter Object
- •The Command Objects
- •The Command and DataReader Objects
- •VB.NET at Work: The DataReader Project
- •VB.NET at Work: The StoredProcedure Project
- •Summary
- •The Structure of a DataSet
- •Navigating the Tables of a DataSet
- •Updating DataSets
- •The DataForm Wizard
- •Handling Identity Fields
- •Transactions
- •Performing Update Operations
- •Updating Tables Manually
- •Building and Using Custom DataSets
- •Summary
- •An HTML Primer
- •HTML Code Elements
- •Server-Client Interaction
- •The Structure of HTML Documents
- •URLs and Hyperlinks
- •The Basic HTML Tags
- •Inserting Graphics
- •Tables
- •Forms and Controls
- •Processing Requests on the Server
- •Building a Web Application
- •Interacting with a Web Application
- •Maintaining State
- •The Web Controls
- •The ASP.NET Objects
- •The Page Object
- •The Response Object
- •The Request Object
- •The Server Object
- •Using Cookies
- •Handling Multiple Forms in Web Applications
- •Summary
- •The Data-Bound Web Controls
- •Simple Data Binding
- •Binding to DataSets
- •Is It a Grid, or a Table?
- •Getting Orders on the Web
- •The Forms of the ProductSearch Application
- •Paging Large DataSets
- •Customizing the Appearance of the DataGrid Control
- •Programming the Select Button
- •Summary
- •How to Serve the Web
- •Building a Web Service
- •Consuming the Web Service
- •Maintaining State in Web Services
- •A Data-Driven Web Service
- •Consuming the Products Web Service in VB
- •Summary

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 |