ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
• •
Table of C ontents Index
Database Programming with Visual Basic® .NET and ADO.NET: Tips, Tutorials, and Code
By F. Scott Barker Publisher Pub Date ISBN Pages : Sams Publishing : September 12, 2002 : 0-672-32247-1 : 544
The topic combination of VB .NET and ADO.NET is unbeatable. VB .NET is the most popular language in which to code. And, every developer needs to understand ADO.NET to allow data to be accessed from a Web site. In this book Developers will be shown numerouse code examples that will illustr4ate how to program database driven applications within the .NET Framework. The book is aimed at both established and new VB Developers. Important topics covered include: Visual Studio development environment, ASP.NET applications, Windows Forms application, using VB .NET with ADO.NET, complex queries, security, COM interop., and application deployment.
[ Team LiB ]
Page 1
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
• •
Table of C ontents Index
Database Programming with Visual Basic® .NET and ADO.NET: Tips, Tutorials, and Code
By F. Scott Barker Publisher Pub Date ISBN Pages : Sams Publishing : September 12, 2002 : 0-672-32247-1 : 544
C opyright About the Author Acknowledgments Tell Us What You Think! Introduction Who Is This Book For? What's C overed in Database Programming with Visual Basic .NET and ADO.NET: Tips, Tutorials, and Code? C hapter 1. Section Section Section Section Section Section Section Section Section Developing Windows Forms Using Bound C ontrols 1.1. C reate a Bound List Box 1.2. Limit the Data Displayed in a Bound List Box 1.3. Bind and View Individual Text Boxes Based Off a Selected List Box Item 1.4. Edit and Update Data Using Bound C ontrols 1.5. Add and Delete Records Using Bound C ontrols 1.6. Take C are of Error Handling with Bound C ontrols 1.7. Put the Finishing Touches on a Data Bound Form 1.8. Bind Data to C omboBox and DataGrid C ontrols 1.9. Drill Down to Data in the DataGrid C ontrol
C hapter 2. C reating SQL Server Database Objects From Visual Studio .NET Working with Tables, C olumns, and Rows Utilizing Properties for Tables and C olumns Section 2.1. C reate a New SQL Server Database from Within Visual Studio .NET Section 2.2. Define Tables and Fields Section 2.3. Define a Primary Key and Other Indexes Section 2.4. Define Relations Between Tables Section 2.5. Define Defaults and C onstraints Section 2.6. C reate Views Section 2.7. C reate Stored Procedures
Page 2
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
C hapter 3. Viewing Data With ADO.NET Differences Between ADO and ADO.NET Objects That Are Found in ADO.NET Section 3.1. Retrieve Data by Using the DataReader Object Section 3.2. Retrieve Results from SQL Server by Using the DataTable Object Section 3.3. Locate Records with the DataTable Object Section 3.4. Filter and Sort Records Using the DataView Object C hapter 4. Section Section Section Section Manipulating Data With ADO.NET 4.1. Edit Data and Update C hanges That Are Made to an ADO.NET DataSet Object 4.2. Add and Delete Rows in a Dataset with ADO.NET 4.3. Execute Parameterized Stored Procedures in ADO.NET 4.4. C reate and Execute On-the-Fly Batch Updates by Using ADO.NET
C hapter 5. Working With Data In Web Forms Dealing with Stateless Programming Section 5.1. Use Bound C ontrols with Web Forms Section 5.2. Validate Data Using Validation C ontrols Section 5.3. Populate DropDown and ListBox C ontrols Section 5.4. Display Data Using the Table C ontrol Section 5.5. Display Data Using the Repeater C ontrol C omments Section 5.6. Display, Sort, and Page Data in the DataGrid C ontrol Section 5.7. Add, Edit, and Delete Data Using the DataGrid C ontrol Section 5.8. Hyperlink from a Row in the Data Grid to a Detail Page C hapter 6. Section Section Section Section Section Section Section Section C reating Transact-SQL C ommands 6.1. Retrieve Unique Records Using Only a Select Query 6.2. Use Variables and Functions in T-SQL 6.3. Use Wildcards and Ranges of Values in a SQL Query 6.4. Find Records in a Table Without C orresponding Entries in a Related Table 6.5. Take Advantage of Using Subqueries 6.6. C reate, Modify, and Delete Tables 6.7. C reate a New Table with Data from Existing Tables 6.8. C reate and C all SQL Server 2000 User-Defined Functions
C hapter 7. Performing C ommon Database Tasks Using SQL-DMO Looking at the SQL Server DMF APIs Setting References in .NET for the SQL APIs Section 7.1. C reate a Dialog Box to C onnect to a New Database, Including Listing Available SQL Servers Section 7.2. Section 7.3. Section 7.4. Section 7.5. C hapter 8. Section Section Section Form Section Section Section Section Section C hapter 9. Section Section Section Section and Databases Back Up and Verify a SQL Server Database Restore a SQL Server Database Transfer Tables Between SQL Server Databases C reate a Detach/Attach SQL Server Database Dialog Box
Taking Advantage of Data-Driven Techniques 8.1. Work with Data-Bound Multi-Select List Boxes Using Windows Forms 8.2. Use a Single Windows Form to Update Multiple Lookup Tables 8.3. C reate a Point-and-C lick SQL Server Query Tool for Users Using a Windows 8.4. 8.5. 8.6. 8.7. 8.8. Make a Generic Search Form in a Visual Basic .NET Desktop Application Work with Data-Bound Multi-Select List Boxes Using Web Forms Use a Single Web Form to Update Multiple Lookup Tables C reate a Point-and-C lick Query Tool for Users Using a Web Form Make a Generic Search Form in an ASP.NET Web Application
Using C lasses With Databases to Make Life Easier 9.1. Define a C lass in Visual Basic .NET 9.2. C reate a C lass That Implements the Interface You Defined 9.3. Use Visual Studio .NET Tools to Speed Up Writing ADO.NET C ode 9.4. C ontrol the C reation and Behavior of C lasses
Page 3
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Section 9.5. Implement the Methods That Update the Database Section 9.6. Validate Data Passed to Properties and C ommunicate Errors to Developers Section 9.7. Write Data Validation C ode That C an Be Reused in Other C lasses C hapter 10. C reating Reports Using C rystal Reports Section 10.1. C reate a Report Using C rystal Reports Report Expert Section 10.2. Display a Report That Was C reated Section 10.3. Add C alculated Fields to the C rystal Reports Report Section 10.4. Select Whether the Report Will Be Displayed, Printed, or Exported Using Visual Basic .NET C ode Section 10.5. Determine Which Records Will Be Printed at Runtime Section 10.6. Print Labels and C ontrol the Order in Which Records Will Be Printed Section 10.7. C reate an Onscreen Report That C ontains Hyperlinks C hapter 11. Managing SQL Server Security Section 11.1. C reate Windows NT/2000 Users Section 11.2. C reate Windows NT/2000 Groups Section 11.3. Establish a Windows NT/2000 Authentication Mode Section 11.4. Establish Mixed-Mode Authentication Section 11.5. C reate a Standard Login Section 11.6. C reate a Windows NT/2000 Login Section 11.7. Use a Fixed Server Role Section 11.8. C reate a Database User Account Section 11.9. Use Statement Permissions Section 11.10. Use Object Permissions Section 11.11. Use Fixed Database Roles Section 11.12. C reate C ustom Database Roles Section 11.13. C reate Application Roles C hapter 12. Utilizing XML Data In Your Visual Basic .NET Applications Ways of Utilizing XML in .NET XML Namespaces in .NET Section 12.1. Use XMLWriter to C reate an XML Document Section 12.2. Use XMLReader to Read an XML Document Section 12.3. Work with the XML Document Object Model Section 12.4. Retrieve XML from SQL Server 2000 Section 12.5. Work with Datasets and XML C hapter 13. C reating XML Web Services Overview of the XML Web Services Infrastructure Section 13.1. Get Started with XML Web Services Section 13.2. C reate a Simple XML Web Service Using Parameters Section 13.3. C onsume XML Web Services Section 13.4. Pass a Dataset Back from an XML Web Service Appendix A. Desktop Development With ADO When to Use ADO (Local Database/Single Tier Applications) Looking At the ADO Object Models Referencing the Type Libraries Using the Connection Object Working with the ADO Recordset Object Executing a SQL Server Stored Procedure By Using ActiveX Data Objects Executing Batch Updates with ADO and SQL Server C reating SQL Server Objects with ActiveX Data Objects C onclusion Index
[ Tea m LiB ]
Page 4
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Page 5
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Copyright Copyright © 2003 by Sams Publishing
All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher. No patent liability is assumed with respect to the use of the information contained herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions. Nor is any liability assumed for damages resulting from the use of the information contained herein. Library of Congress Catalog Card Number: 2001094459 Printed in the United States of America First Printing: September 2002 05 04 03 02 4 3 2 1
Trademarks
All terms mentioned in this book that are known to be trademarks or service marks have been appropriately capitalized. Sams Publishing cannot attest to the accuracy of this information. Use of a term in this book should not be regarded as affecting the validity of any trademark or service mark.
Warning and Disclaimer
Every effort has been made to make this book as complete and as accurate as possible, but no warranty or fitness is implied. The information provided is on an "as is" basis. The author and the publisher shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the information contained in this book.
Credits
ASSOCIATE PUBLISHER Michael Stephens ACQUISITIONS EDITOR Neil Rowe DEVELOPMENT EDITOR Kevin Howard MANAGING EDITOR Charlotte Clapp PROJECT EDITORS Matt Purcell Tony Reitz
Page 6
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
COPY EDITOR Karen A. Gill INDEXER Sandy Henselmeier PROOFREADER Linda Seifert TECHNICAL EDITOR Shawn Nanto TEAM COORDINATOR Lynne Williams INTERIOR DESIGNER Gary Adair COVER DESIGNER Alan Clements PAGE LAYOUT Stacey Richwine-DeRome
Dedication
I would like to dedicate this book to the innocent men, women, and children who died in the September 11, 2001 attack in New York, at the Pentagon, and those in the airplanes as well. God bless you, and God bless America!
[ Team LiB ]
Page 7
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] About the Author
F. Scott Barker holds a bachelor of science in computer science and has worked as a developer in the database field for more than 16 years, first with Clipper, and then with Visual Basic, SQL Server, and Microsoft Access for the past 10 years. Scott has already created and deployed a number of ASP.NET Web sites for his clients. Working at Microsoft for two years, Scott was a member of the Microsoft Access and FoxPro teams. Since leaving, he has been a contractor with Microsoft developing in-house tools used throughout Microsoft. With his company, Applications Plus, Scott has also been doing contract development for many Fortune 500 companies, developing in ASP.NET, Visual Basic .NET, C#, Visual Basic/Access/Office, and SQL Server. Scott has trained for Application Developers Training Company and others all around the U.S. and is a frequent speaker at Microsoft conferences throughout the U.S., Canada, South Asia, and Europe. Through his classes and conferences, Scott has trained thousands of developers. Scott is a writer for a number of development magazines and is the author of F. Scott Barker's Microsoft Access 2002 Power Programming, published by Sams, and Access 97 Power Programming, published by Que. Scott can be reached at his Web site at www.appsplus.com, or via e-mail at FSBarker@AppsPlus.com.
[ Team LiB ]
Page 8
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Acknowledgments
To start off, I want to acknowledge Neil Rowe, my acquisitions editor, for putting up with me for another book. Thanks also to Kevin Howard, my development editor. Bud, you had me scared at first. A big thanks goes to my longtime friends Paul Sheriff, Ken Getz, Mike Groh, and Tom Howe, for putting up with me that week at Paul's class, helping me hammer out the outline, and being around for me to bounce ideas off of. A really special thanks goes to Michael O'Neil for his work on the Classes chapter. He is a man who has a lot of class. Good luck with NYU! Another thanks to Mike Groh for his work on the Security chapter, you are a great friend Mike, and know your stuff! Thanks to the students who attended my .NET classes and helped to shape the contents of this book as I was writing it. No, you don't get any of my royalties, but you have my thanks. As usual, I want to thank some people from Microsoft for putting up with my questions, listening to my beefs, and not telling me where to go when I got on their nerves. Ari Bixhorn, you are one of the most enthusiastic guys I know. My thanks to you and Ed Robinson for being so patient with me and letting your excitement for .NET show through so honestly. My thanks to Woodinville #2 Starbucks for putting up with me rearranging their furniture so I could work by both the plug-in and the fireplace while I cranked on this book and for keeping those lattes and cappuccinos coming. Finally, I need to acknowledge those people who put up with me the most: my wife Diana, and my kids Christopher, Kari Anne, Nichole, David, and Joseph. Let's go skiing!
[ Team LiB ]
Page 9
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Tell Us What You Think!
As the reader of this book, you are our most important critic and commentator. We value your opinion and want to know what we're doing right, what we could do better, what areas you'd like to see us publish in, and any other words of wisdom you're willing to pass our way. As an associate publisher for Sams, I welcome your comments. You can fax, e-mail, or write me directly to let me know what you did or didn't like about this book as well as what we can do to make our books stronger. Please note that I cannot help you with technical problems related to the topic of this book, and that due to the high volume of mail I receive, I might not be able to reply to every message. When you write, please be sure to include this book's title and author as well as your name and phone or fax number. I will carefully review your comments and share them with the author and editors who worked on the book. Fax: E-mail: Mail: 317-581-4770 feedback@samspublishing.com Michael Stephens Sams Publishing 201 West 103rd Street Indianapolis, IN 46290 USA
[ Team LiB ]
Page 10
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Introduction
Dear Reader, Here we are on the brink of what feels like another revolution of computing: .NET. Now I know what some people are saying: .NET is merely evolutionary, not revolutionary. I disagree. Here I sit at the San Francisco airport, waiting for my return flight home to Seattle, sipping on my ice quad venti vanilla latte (yes, that is a coffee drink) pondering all wonderful technology I witnessed this week. You see, I spent the past five days sitting in on Paul Sheriff's "Jumpstart Introduction to VB.NET Week." Along with around 20 regular students, Paul had asked a few of his friends who were also interested in presenting the training down for what is called "Train the Trainer." By the time you read this, I will have presented the training myself a few times. I have to admit I have not been as excited about a product like this since my early days of working on the Access team. (No snide remarks about Access, please.) I have been working primarily in Access/Visual Basic/SQL Server for the past 10 years and making a good living at it. The Web daunted me with all that there was to develop for it using products such as ASP and HTML. That has all changed. Now the line between developing for the Web and desktop has become almost invisible. Developing with Visual Basic .NET and databases is more powerful than ever, and you can easily blend creating Windows Forms (Visual Basic .NET) and Web Forms (ASP.NET) into the same solution. One of the most exciting things is that when you know how to work with ADO.NET using Windows Forms, you can use similar techniques and the same objects in Web Forms. I hope that, with this book, you will become as excited as I am about creating database applications using Visual Basic .NET! Sincerely, F. Scott Barker Author, Database Programming with Visual Basic .NET and ADO.NET: Tips, Tutorials, and Code
[ Team LiB ]
Page 11
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Who Is This Book For?
This book is for the serious developer, whether corporate or independent, who wants to create database applications using Visual Basic .NET. If you are looking for a primer on .NET or even a beginner book for Visual Basic .NET, then you would be wise to pick up another book to give you the basics on those topics. This book focuses on the topic I love best: database development. Current Visual Basic developers will get quite a bit out of this book. Although you will find that much of Visual Basic .NET looks familiar, the language has grown up quite a bit and even gets more of the respect it deserves since we can now use the Visual Basic we know and love in Web Forms as well as Windows Forms. Those who are familiar with ADO will appreciate the samples that show how to use ADO.NET. Hopefully, even hard-core Visual Basic developers will appreciate the chapter on wrapping up some of the ADO.NET data access into classes for simplified coding. Those Access developers who are attempting to take the plunge and expand their horizons hopefully will be placed at ease with how similar developing databases between Access and Visual Basic is. If you have already worked with SQL Server and ADO, then you are ahead of the game. Even if you haven't developed in Visual Basic previously, this book will give you some great sample code to get started. Corporate management will find this book useful for getting an idea of what their developers can do with Visual Basic .NET, both on the desktop and Web sides.
[ Team LiB ]
Page 12
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] What's Covered in Database Programming with Visual Basic .NET and ADO.NET: Tips, Tutorials, and Code?
I have laid out this book to logically follow the course of learning how to use the database features of Visual Basic .NET and be as productive as possible, as quickly as possible. Hopefully, you can see this even with the way I have laid out and labeled the chapters:
Chapter 1, "Developing Windows Forms Using Bound Controls," gets you started being productive from the get-go. You will get a great start on creating Windows Forms in Visual Basic .NET that you can use not only to view data, but also to add, edit, and delete data. You will accomplish this quickly by using bound controls that are more robust than what is found in previous versions of Visual Basic.
Chapter 2, "Creating SQL Server Database Objects from Visual Studio .NET," shows you how to use some of the design tools found inside Visual Studio .NET to create and maintain SQL Server databases.
Chapter 3, "Viewing Data with ADO.NET," takes you into using the objects found in ADO.NET, such as the OleDbDataReader and OleDbDataSet. These objects and more are used to view data and load it into various controls such as list boxes and combo boxes.
Chapter 4, "Manipulating Data with ADO.NET," takes you further into using the objects found in ADO.NET. You will see how to use the various objects in ADO.NET to add, edit, and delete records and manipulate data.
Chapter 5, "Working with Data in Web Forms," takes what you learned in the previous chapters and shows you how to create useful Web Forms using ASP.NET, including taking advantage of the DataGrid control.
Chapter 6, "Creating Transact-SQL Commands," brings you deeper into the language that makes SQL Server such a powerful database. It teaches you how to take advantage of the Transact-SQL commands to update and manipulate your SQL Server database from Visual Basic .NET.
Chapter 7, "Performing Common Database Tasks Using SQL-DMO," explains how to perform day-to-day tasks in your Visual Basic .NET application that an administrator would normally have to do. This includes common tasks such as importing/exporting data and backing up/restoring databases.
Chapter 8, "Taking Advantage of Data-Driven Techniques," takes what you have learned in the book so far and puts it to even more practical use. This chapter shows you how to create utilities that perform more tasks with less code. This chapter demonstrates how to create a point-and-click interface for a query tool for your users.
Chapter 9, "Using Classes with Databases to Make Life Easier," shows that even though it can take quite a bit of code to perform data access tasks, you can use classes to wrap that code for accessing data. By taking table definitions up into properties and methods, you can make accessing data in tables more intuitive and simpler to access throughout your applications.
Chapter 10, "Creating Reports Using Crystal Reports," gets into using crystal reports with Visual Basic .NET. Besides learning how to generate standard reports, you will see how to create some of the more advanced features that really take advantage of the engine.
Page 13
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Chapter 11, "Managing SQL Server Security," discusses the SQL Server security scheme and explains the options available to you as a Visual Basic developer. Authentication modes are discussed, as are the various permissions you might set on SQL Server objects.
Chapter 12, "Utilizing XML Data in Your Visual Basic .NET Applications," shows you just how much you can use XML from within your applications. You are shown how to load and manipulate XML document objects, as well as retrieve XML from SQL Server 2000.
Chapter 13, "Creating XML Web Services," show you how to take advantage of the one of the coolest new features in .NET. You can create a XML Web Service that both Internet and Desktop applications can take advantage of, and even pass ADO datasets.
Appendix A, "Desktop Development with ADO," discusses the use of ADO in your .NET applications. Although .NET uses ADO.NET, you might have a lot invested in ADO development. This Appendix shows how you can create a reference in your .NET application and what objects there are.
[ Team LiB ]
Page 14
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 1. Developing Windows Forms Using Bound Controls
In this chapter you will
Create a bound list box Limit the data displayed in a bound list box Bind and view individual text boxes based off a selected list box item Edit and update data using bound controls Add records using bound controls Take care of error handling with bound controls Put the finishing touches on an add/edit/delete form Bind data to ComboBox and DataGrid controls Drill down to data in the DataGrid control
Visual Basic .NET, one of the languages that ships with Visual Studio .NET, is a far more robust language than what was found in Visual Basic 6.0. Now, before you VB 6 developers go off and start cussing me for saying this, read on. As in previous versions of Visual Basic, you can use code to bind controls manually, which takes more work than using bound controls. The other method is to use data bound controls, which in the past were avoided because of not having total control over the way data is handled. In VB .NET, Microsoft has done a better job of not only creating the data bound controls, but because everything is class-based in the .NET languages, you also can see the code that is generated when you place data bound controls onto a form. In the prior versions of Visual Basic, the Microsoft Jet Database Engine was the database flavor of choice for small- to medium-sized databases, as well as books such as this one. Now, Visual Basic ships with the Microsoft SQL Server 2000 Desktop Edition (MSDE). This is a scaled-down version of SQL Server 2000, allowing you to create databases on your local machine and then distribute them for use on a user's individual local version of the MSDE or a larger SQL Server 2000 installation. If this sounds intimidating, don't worry. You will learn how to use SQL Server from within Visual Studio and your application. This includes creating utilities for connecting to new databases, as well as backing up and restoring databases. Although this book uses the MSDE for the database, you only have to adjust the ConnectionString property of the OleDbConnection object on forms and the
ConnectionString property of the OleDbConnection object discussed in Chapter 4,
"Manipulating Data with ADO.NET." In the code in Chapter 4, you will see a commented line of code that provides an example of using a Jet database version of Northwind.
[ Team LiB ]
Page 15
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.1 Create a Bound List Box
It used to be that when you wanted to create a data entry form, you just assigned a recordset to the data control and allowed the users to scroll through the data, making changes as needed. When you're dealing with Client Server or Web applications, this just doesn't cut it. One of the first things you need to do is provide a method to limit the amount of data so that users can pick which record they want to edit/view, without pulling all the fields of a table over the Net either LAN or Internet. List boxes and combo boxes help with that. In this How-To, you will learn how to set up two data controls: OleDbDataAdapter and DataSet. These controls enable you to populate a list box with one line of code. You want to see a list of customers on your Windows form in a ListBox control. You don't want to write code at this point. You only want to prototype a form, so you just want to use bound data controls. How do you create a list box and bind it using the data controls?
Technique
To get started with learning about any of the objects used for data in .NET, it's important to talk about what .NET Namespaces are and how to use them.
Using .NET Namespaces
The .NET Framework contains a big class library. This class library consists of a number of Namespaces. These Namespaces are made up of various classes that allow us to create our objects. All of the objects and classes that make up the .NET objects, such as forms, controls, and the various data objects, can be found in Namespaces. Namespaces also can be made up of other Namespaces. For example, there is a Namespace called System.Data. Although this Namespace has classes in it, such as DataSet and DataTable, it also has Namespaces within it called System.Data.OleDb and System.Data.SQLClient, as well as others. To check out the .NET Namespaces, choose Object Browser from the View menu. You can then expand the System.Data Namespace to see the other Namespaces contained within. If you are positive that the database you are going to be working with is SQL Server, then you would be far better served performance-wise to use the classes found in the System.Data.SQLClient Namespace. However, if you are not sure what database you will be working against, you should use the classes found in System.Data.OleDb. For this book, I am using objects created from the classes in the System.Data.OleDb Namespace. That way, you can use the routines against other databases with less modifications. Tip If you know that the back end that you will be accessing is SQL Server, then use the SQL Server type data controls because they are optimized for it.
Eight data controls are available for Windows forms. Table 1.1 lists these controls and their uses. You can find these controls by clicking on the Data group in the toolbox.
Page 16
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 1.1. Data Controls Used in Windows Forms Control Name Purpose This control is used in conjunction with the other data controls, storing the results that are returned by commands and the DataAdapters. Unlike the recordset from ADO and DAO, the DataSet actually brings back a hierarchical view of the data. Using properties and collections in the DataSet object, you can get all the way down to individual tables, rows, and columns.
DataSet
OleDbDataAdapter This control stores and manages the commands you want to use against an
OleDb provider such as Jet, Oracle, or SQL Server. The commands for selecting, updating, inserting, and deleting records can be used. The Connection against which to use the commands is also tracked.
OleDbConnection
This control maintains connection information for an OleDb provider. This control is used with the OleDbDataAdapter. Similar to the ADO command object, this control allows you to execute SQL statements or stored procedures to either run bulk operations or return data. This control is the same as the OleDbDataAdapter except that it is for use only against SQL Server stores.
OleDbCommand
SqlDataAdapter
SqlConnection
This control is the same as the OleDbConnection except that it is for use only against SQL Server stores.
SqlCommand
This control is the same as the OleDbCommand except that it is for use only against SQL Server stores.
DataView
This control creates multiple views of the same table. This includes looking at data in various states such as deleted, changed, or sorted differently.
Creating two types of the data controls just mentioned, OleDbDataAdapter and DataSet, bind them to a list box to display a list of customers. Note that an OleDbConnection control is also created, but Visual Studio .NET creates it. You then add a line of code to fill the dataset.
Steps
To preview this How-To, open the solution called VB.Net Chapter1 found in the chapter folder. When you run the project, the first form that comes up is the main switchboard with each of the How-Tos listed for this chapter. Click on How-To 1.1 to open the form for How-To 1.1 (see Figure 1.1 ). Figure 1.1. Main form and How-To form 1.1 from the first chapter's solution.
Page 17
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Note You can find the source code for all the chapters in the book at www.samspublishing.com. After you are there, just type the book ISBN (0672322471).
1.
Create a new Visual Studio .NET project using the Windows Application project template. This creates the initial form called Form1 that you will use.
2.
Drag the OleDbDataAdapter control from the Data Controls group located in the toolbox and drop it onto the form. The Data Adapter Configuration Wizard appears. Read the introductory screen, and then click Next to choose your data connection. At this point, if you don't see a data connection to Northwind database in the drop-down list of data connections to use, click the New Connection button. You then see the Data Link Properties dialog box with which you are familiar if you have used other Microsoft products such as Visual Studio 6.0. Type (local) for the server name, select Use Windows NT Integrated Security, and select Northwind for the database (see Figure 1.2.) Click OK. Figure 1.2. From now on, this data connection will show up in Visual Studio .NET's Server Explorer on this machine.
Page 18
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3.
Now you will be back on the Choose Your Data Connection page of the Data Adapter Configuration Wizard, with the Northwind database in the Data Connection drop-down list. Click Next. This brings you to the page to select the query type on which the data adapter will be based. Leave the default of Use SQL Statements, and click Next. In the text box that asks What Data Should the Data Adapter Load into the Dataset?, type the following:
4. 5. Select CustomerID, CompanyName From Customers Note
By default, the Data Adapter Configuration Wizard creates select statements not only for selecting (viewing) data, but also for inserting, updating, and deleting. If you don't need these other options, click the Advanced Options button at the bottom-left corner of the dialog box. Deselect the check box that reads Generate Insert, Update, and Delete statements. You don't need this because we are just using the data to fill a ListBox control. Click OK to close the Advanced Options dialog box.
6. Click Next to see results of your select statement, as shown in Figure 1.3. If you see something different from Figure 1.3, you either have entered your select statement incorrectly, or you have forgotten to deselect the advanced options.
Page 19
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 1.3. Success in creating the data adapter.
7.
Click Finished to create a data adapter and connection object. You then see a new data adapter control called OleDbDataAdapter1 and a Connection control called
OleDbConnection1. Both controls are in the Components tray below the Form designer.
8. After you have created the first two controls, it is time to create the Dataset object. Right-click on the Data Adapter and choose Generate Dataset from the pop-up menu. This opens the Generate Dataset dialog box. You can keep all the defaults and simply click OK to create a dataset control called DataSet
. (The sequential number might vary if you have generated other dataset controls.) 9. Now you are ready to create the ListBox control. Drag the ListBox control from the Windows Forms group in the toolbox and drop it on your form. Stretch the control to the size of your form, and then set the following properties in Table 1.2 on the ListBox control.
Table 1.2. ListBox Control Property Settings Needed to Bind a DataSet Control Property Setting
DataSource DisplayMember ValueMember
DataSet Customers.CompanyName Customers.CustomerID
Page 20
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
10. Although you have bound the dataset to the correct properties in the ListBox control, if you run the form at this point, you will still see a blank ListBox control on the form. 11. Now it is time for the one line of code in this sample, in the Load event of the form. Click on the View Code button in the Solution Explorer, or choose Code from the View menu. In the Code Editor, select (Base Class Objects) from the Class Name drop-down list, and then select Load from the Methods drop-down list. Next, type the line of code as displayed here, which tells the data adapter to fill the dataset with data: 12. 13. OleDbDataAdapter1.Fill(DataSet1) Be sure to use the names of the controls you created. Listing 1.1 presents the Load event code for the form called frmHowTo1_1 in the samples. Listing 1.1 frmHowTo1_1.vb: Filling the Data Set on Which ListBox1 Is Based
Private Sub frmHowTo1_1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.OleDbDataAdapter1.Fill(Me.DataSet1) End Sub
How It Works
When the form called frmHowTo1_1 loads, the Fill method of the OleDbDataAdapter1 is called, with the DataSet1 being passed. Because the DataSource property of ListBox1 was specified as being DataSet1 and the ValueMember and DisplayMember properties are both set appropriately,
ListBox1 is populated with the CustomerID and CompanyName from the Customers table in
Northwind. Figure 1.4 shows what the final form looks like in Design view, and Figure 1.5 shows what it looks like when running. Figure 1.4. The final design view for your first database how-to.
Page 21
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 1.5. This list is based on the Customers table in the Northwind SQL Server database.
Comments
In the .NET version of Visual Basic, Microsoft went to considerable effort to make the data controls more robust than ever. One cool thing is that most of the tasks that are done for you in Visual Basic .NET are discoverable. Even though you are using the data controls on your form, Visual Studio creates the code under the covers. You can see this code by clicking on the #Region statement that reads like this:
#Region " Windows Form Designer generated code "
Beware: There is much code here, and you don't want to change it. You can learn a lot from reading it though. As you continue to use the Data Controls shown here, you will become comfortable with changing various properties and getting more power and use out of them.
Page 22
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
[ Team LiB ]
Page 23
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.2 Limit the Data Displayed in a Bound List Box
Even populating a list box with a couple of columns from a table full of data can be a big performance hit. This How-To shows you how to create a parameterized SQL statement to limit the items that are displayed in the list box, thus giving you better performance on your forms. You have hundreds of thousands of customers in your database, and you don't want the list box loaded up with the whole customer table. How can you limit the data that is displayed in your list box?
Technique
You are going to make a copy of the form that you created in How-To 1.1. You will then add a Label and TextBox control that the Select statement contained within the OleDbDataAdapter control will query against to limit the data displayed in the list box. A command button will be added to allow you to call the Fill method of the OleDbDataAdapter control whenever you update the text box, and then you can click the command button (see Figure 1.6). Figure 1.6. You can now limit the amount of data loaded into the list box.
Steps
To get started with this How-To, right-click the form you created in How-To 1.1, which should be listed in the Solutions Explorer. Choose Copy from the pop-up menu. Next, right-click the project in the Solution Explorer, and choose Paste from the pop-up menu. You will now have a new Class object in the Solutions Explorer called Copy Of whatever the previous name of the form was. Rename the new form that you have created to the name you desire. Then, with that form highlighted, click on the Code button above the Solutions Explorer. Change the first line of code to say this:
Public Class
You see, VS does not change the line of code automatically for you. It thinks you have a duplicate Class definition. Now you can see that the icon of the form is correct. You can continue with the steps of the How-To. 1. Select the Data Adapter that you created. In the Properties pane, you will see the
Page 24
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html CommandText property when you click on the SelectCommand property plus sign. Replace the CommandText property with the following command:
2. 3. SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%') You will learn more about the Select statement in Chapter 3. However, the WHERE clause used here compares CompanyName to a parameter that will be supplied, as indicated by the ?. This will be performed using code in the final step of this How-To. The % is a wildcard that tells the server to make it a fuzzy search. 4. Resize the ListBox control, and leave room at the top of the form for the Label, TextBox, and Command button. Create these three controls, setting the properties described in Table 1.3.
Table 1.3. Label, TextBox, and Command Button Control Property Settings Object Property Setting
Label TextBox
Text Name Text
Customer txtCustLimit A btnLoadList Load List
Command Button
Name Text
5.
Double-click the new command button you just created called btnLoadList. Enter the code in Listing 1.2 in the Click event of the btnLoadList button. This code loads the data entered from txtCustLimit into the parameter of the OleDBDataAdapter1, which was created by using the ? in the Select statement of the data adapter. Then Dataset1 is cleared of its data with the Clear method. Finally, DataSet1 is refilled with data based off the value in txtCustLimit, using the data adapter. Listing 1.2 frmHowTo1_2.vb: Submitting a Parameter to a DataAdapter and Filling the
Dataset
Private Sub btnLoadList_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadList.Click Me.OleDbDataAdapter1.SelectCommand.Parameters(0).Value = _ Me.txtCustLimit.Text Me.DataSet1.Clear() Me.OleDbDataAdapter1.Fill(Me.DataSet1) End Sub
Page 25
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Note
There is one big difference here between an OleDbDataAdapter and a SqlDataAdapter. Whereas the OleDbDataAdapter takes a ? to specify a parameter within the Select statement, the
SqlDataAdapter requires a named parameter such as @parCustLimit. Therefore, instead of the select
statement in step 1 being this: SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%') It would be this: SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE @parCustLimit + '%') The naming of the actual parameter is up to you.
6. Highlight and delete the Load event for the form because you don't want to just fill the event when the form loads. You want the user to click btnLoadList.
How It Works
When the form you created for this How-To loads, or when you're using the form called frmHowTo1_2, you will see a blank ListBox control with a text box on top with the letter A in it. If you click the command button called btnLoadList, the list box becomes filled with values based on the letter (or letters) in txtCustLimit and on the code described in step 3.
Comments
Try entering a few other letters, and then try entering no letters. What happens? You limit the list more by the number of letters you enter, and you get all entries when you don't enter any letters. The method displayed here, although simple, is powerful, and it can be used in a variety of ways. You can continue building on this form for the next few How-Tos. If you want to copy your form and start a new one as described at the beginning of the steps for this one, you have the instructions there. Otherwise, by the time you reach How-To 1.8, you will have a data entry form that you can use. Each step, however, is available in the sample solution for this chapter.
[ Team LiB ]
Page 26
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.3 Bind and View Individual Text Boxes Based Off a Selected List Box Item
Using a list box similar to the one in the previous How-To, in this How-To, you will learn how to create additional OleDbDataAdapters and DataSets and bind them to individual text boxes for viewing data. Although the list box is nice for displaying a couple of fields in my form and limiting the rows displayed, how do you list the detail in individual text boxes by clicking on an item in the list box?
Technique
You are going to enhance the form that you created in How-To 1.2 to use additional data controls, specifically another data adapter and dataset. You will set up the select statement in the new data adapter to take the selected list box item as a parameter. The dataset will then be filled with data, and some text boxes with the dataset set as the data source will display the current record. You can see an example of this in Figure 1.7. Figure 1.7. You can bind text boxes to datasets as well as list boxes.
Steps
To go further with the form with which you have been working, you will want to rename the data adapter, dataset, and list box currently on the form to something more meaningful. You can see this in Table 1.4. Table 1.4. Changes to Current Objects on the Form Object Property Old Setting New Setting
ListBox OleDbDataAdapter DataSet
Tip
Name Name Name
ListBox1 OleDbDataAdapter1 DataSet1
lstCustomers odaCustomerList dsCustomerList
Page 27
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Name your objects at the time you first create them. This is true of your solutions, projects, and forms, as well as controls used on forms. With the .NET languages being so class and code driven, some items take multiple steps to rename. Visual Studio doesn't seem to catch all the places in code that need to be changed. Renaming a form is a good example. Remember that you had to change the Public Class statement in the code to have it match the new name of the form.
1.
Drop another Data Adapter control on the form from the Data group of the toolbox. Use the existing data connection, specify that you will use SQL statements, and assign the following select statement that will use a parameter supplied at runtime by using the selected list box item.
2. 3. 4. 5. PostalCode, Country, Phone, Fax FROM Customers WHERE (CustomerID = ?) You can click the Advanced Options button on the select statement page and deselect creating the Insert, Update, and Delete commands. Finish the Data Adapter Wizard and rename the control odaCustomerIndividual. 6. Right-click odaCustomerIndividual and choose Generate Dataset from the pop-up menu. Create a new dataset called dsCustomerIndividual. Click OK. As of this writing, VS places a 1 at the end of name of the dataset you specified. Clean up the name by removing the 1. Now you should have two data adapters: odaCustomerList and SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region,
odaCustomerIndividual, and two datasets: dsCustomerList and dsCustomerIndividual.
7. Now it's time to add the text boxes. Resize the form so that it allows you to add a column of text boxes with labels beside them. You will then add the labels and text boxes, setting the Text property of the text boxes to the column names in the Customers table as supplied by dsCustomerIndividual. The Text property of text boxes falls under the Data Binding category in the property sheet. Table 1.5 describes the controls and their property settings. Refer to Figure 1.8 for an example of where to place them. Figure 1.8. Letting users know when they can edit data is helpful.
Page 28
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 1.5. New Label and TextBox Control Property Settings for the Form frmHowTo1_3 Object Label Property Setting Text Customer ID
Label Label Label Label Label Label Label Label Label
Text Text Text Text Text Text Text Text Text
Company Name Contact Contact Title Address City Region Country Phone Fax txtCustomerID dsCustomerIndividual Customers.CustomerID txtCompanyName dsCustomerIndividual Customers.CompanyName
TextBox Name Text
TextBox Name Text
Page 29
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
TextBox Name Text
txtContact dsCustomerIndividual Customers.Contact txtContactTitle dsCustomerIndividual Customers.ContactTitle txtAddress dsCustomerIndividual Customers.Address txtCity dsCustomerIndividual - Customers.City txtRegion dsCustomerIndividual Customers.Region txtPostalCode dsCustomerIndividual Customers.PostalCode txtCountry dsCustomerIndividual Customers.Country txtPhone dsCustomerIndividual - Customers.Phone txtFax dsCustomerIndividual - Customers.Fax
TextBox Name Text
TextBox Name Text
TextBox Name Text TextBox Name Text
TextBox Name Text
TextBox Name Text
TextBox Name Text TextBox Name Text
8.
Now it's time for the code. To start off, you will change the Click event code for the button called btnLoadList. The first three lines of code are basically the same as in the last How-To, except that the name was changed as needed, and some lines were added to comment the code. Listing 1.3 frmHowTo1_3.vb: Adding the Call to the RefreshIndividual Subroutine
Private Sub btnLoadList_Click(ByVal sender As System.Object, _
Page 30
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal e As System.EventArgs) Handles btnLoadList.Click ' ' Store the text entered to limit the list box to the data adapter's parameter Me.txtCustLimit.Text ' Clear the current data in the dataset Me.dsCustomerList.Clear() ' Fill the customer list dataset
Me.odaCustomerList.SelectCommand.Parameters(0).Value = _
Me.odaCustomerList.Fill(Me.dsCustomerList) ' Fill the initial entry's individual dataset
RefreshIndividual() End Sub The only new line of code is the one just before the End Sub, which calls the subroutine
RefreshIndividual for the first item in the newly populated list box. This subroutine first handles clearing the dataset called dsCustomerIndividual. It ensures that a customer is
chosen in the list box and then places the selected item into the parameter value for odaCustomerIndividual. The dataset called dsCustomerIndividual is then filled, displaying the data in the text boxes bound to the dataset. Listing 1.4 frmHowTo1_3.vb: Refreshing the Dataset on Which the Text Boxes Are Based
Private Sub RefreshIndividual() ' Clear individual customer dataset
Me.dsCustomerIndividual.Clear() ' Check to see if an item was selected
If lstCustomers.SelectedIndex <> -1 Then ' ' Store the selected customer ID into the
parameter of the SQL data adapter Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = _
Me.lstCustomers.SelectedItem(0) ' Fill the dataset
Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual) End If End Sub The only other code is required when a new item is selected in the list box. You want to refresh the text boxes with the new data. This code is on the SelectedIndexChanged event for the lstCustomers list box. Listing 1.5 frmHowTo1_3.vb: Call the RefreshIndividual Routine
Page 31
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstCustomers.SelectedIndexChanged ' Fill the current list item's individual dataset RefreshIndividual() End Sub
How It Works
After the user types a letter into the txtCustLimit text box and clicks btnLoadList, the list box is populated with the items that match the text in the text box. After lstCustomers is populated, the user sees the details for the first item in the list box that is displayed in the text boxes. This occurs within the routine called RefreshIndividual. The selected item is used for the parameter for the data adapter called odaCustomerIndividual, then filling the dataset called
dsCustomerIndividual. As the user selects new items in the list box, the data that corresponds
to the selected item is displayed. Tip Always try to break your code into specific routines such as the subroutine RefreshIndividual. That way when someone tries to read the code, the code is easy to read, you don't make mistakes by typing the same code two or more times, and you only have to change the code in one place if necessary.
Comments
Binding text boxes to datasets saves work when switching from one record to another because you don't have to specifically load each text box with data each time. It also gets easier every time you use a data adapter and dataset in combination when manipulating data on your forms. Bound datasets are particularly useful as you edit, add, and delete data on your forms, as you will see in the following How-Tos.
[ Team LiB ]
Page 32
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.4 Edit and Update Data Using Bound Controls
Although viewing data is fine in some situations, the real power comes in being able to edit the data in the text box and update the data in the server. In this How-To, you learn just that, using some new methods and properties from the various data controls, including autogenerated commands that create update, insert, and delete SQL statements for you. This How-To also introduces you to the BinderContext class, which is used to perform updates with bound controls. The form as created in How-To 1.4 is great if you just want to view data for various records. But what if you want to let users edit and update the data?
Technique
Continuing with the form you used in the previous How-Tos, you are going to add a few command buttons with code that will perform the following:
Edit. Toggle the look of the text boxes to let the user know that he can edit the data in the controls by giving the controls a sunken look.
Save. Save the changes made to the data back to the server. Then toggle the look of the text boxes back to flat so that the user knows he can't edit them.
Cancel. Toggle the text boxes back to flat so that the user knows he can't edit them anymore, but don't save the data.
It is important to let users know when they can edit and when they can't. By toggling the style of the text boxes between flat and sunken and the color between gray and white, users have a definite clue that they can edit the data at certain times (see Figure 1.8). Another useful item to note about this How-To is the introduction of the BindingContext class. This class helps you work with data bound controls. Each control on a Windows form has a BindingContext object as well as BindingContext objects for any controls that are contained within that control. Each form also has a BindingContext object. BindingContext objects manage BindingManagerBase class object(s) for each control. Through the BindingContext object, you can manage editing and updating data back to the server. BindingManagerBase objects help with synchronization of datasets with controls. You are going to use the BindingContext class throughout the rest of this chapter, but only a couple of methods.
Steps
Open the solution for the chapter called "VB .NET How-To Chapter 1," and run the application. From the main form, click the command button with the caption "How-To 1.4." Click the Load List button. Along with the list being filled with customers whose names start with A, you will see the detail How-To fill in on the right side of the form with the first customer in the list. Click Edit. You will now be able to change the data in the text boxes. After you have changed a couple of fields, click Save. If you select another customer from the list box, select the one you changed. You will see that your changes have in fact been saved. If you click Cancel instead of Save, your changes will not be saved. Note that if you change the name of the customer, you must load the list again to see the changes in the list box. 1. Add the three command buttons to your form as described in Table 1.6 and as displayed in Figure 1.8.
Page 33
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 1.6. Command Buttons to Edit, Save, and Cancel Changes to Data Object Property Setting
Command Button
Name Caption
btnEdit &Edit btnSave &Save btnCancel &Cancel
Command Button
Name Caption
Command Button
Name Caption
2.
Add the code shown in Listing 1.6 to the btnEdit Click event. Listing 1.6 frmHowTo1_4.vb: Calling the ActiveEditing Subroutine from the btnEdit Command Button
Private Sub btnEdit_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnEdit.Click ' Enable the editing of the form
ActivateEditing(True) End Sub This calls the routine called ActivateEditing, listed here. This code iterates through all the controls on the form and uses the TypeOf condition to check whether the current control is a text box. It also ensures that the control is not the txtCustLimit text box. If the control is a text box and the parameter called bEnable has been passed in as True, then the sunken look is given to the text box using the BorderStyle and the BackColor property is set to white. Otherwise, the BorderStyle is set to FixedSingle, which is flat, and the BackColor is set to the backcolor of the form. The Enabled property of the text box is set to whatever bEnabled is: True or False. Listing 1.7 frmHowTo1_4.vb: Toggling the Enabled Property and Look of Text Boxes
Private Sub ActivateEditing(ByVal bEnable As Boolean) Dim oCurr As Object ' Loop through each of the controls on the form
For Each oCurr In Me.Controls() ' Check to see if the control is a text box
If TypeOf oCurr Is TextBox And oCurr.Name <> "txtCustLimit" Then
Page 34
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
' If so, toggle the properties
If bEnable Then oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.Fixed3D oCurr.BackColor() = System.Drawing.Color.White Else oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.FixedSingle oCurr.BackColor() = Me.BackColor
End If oCurr.Enabled = bEnable End If Next End Sub 3. Add the code to the Click event of the btnSave command button. This code calls a new routine called SaveRecord, which performs the actual save. The ActivateEditing is then called, passing False to disable the controls because you are finished editing. Listing 1.8 frmHowTo1_4.vb: Calling the SaveRecord Routine and Disabling the Text Boxes by Calling ActivateEditing
Private Sub btnSave_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSave.Click ' Save the information
SaveRecord() ' Disable the text boxes
ActivateEditing(False) End Sub Following is the code for the subroutine called SaveRecord. This routine calls the
EndCurrentEdit method of the BindingContext class, passing in the dataset called dsCustomerIndividual, and specifying the Customers table. Then the Update method is called off the data adapter called odaCustomerIndividual, passing the same parameters.
This updates the changes back to the dataset. Finally, the dataset changes are sent backto the server. Listing 1.9 frmHowTo1_4.vb: Saving the Data Back to the Server
Page 35
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub SaveRecord() ' ' Use the BindingContext class to end current editing so that we can update the server.
Me.BindingContext(Me.dsCustomerIndividual, "Customers").EndCurrentEdit() ' ' Perform the requested task at the dataset level using the data adapter
Me.odaCustomerIndividual.Update(Me.dsCustomerIndividual, "Customers") ' By accepting the changes, the data gets sent back to the server
Me.dsCustomerIndividual.AcceptChanges() End Sub Note
If you haven't read about ADO.NET yet, then you might be confused about doing an update to the dataset, accepting changes, and sending the changes back to the server. ADO.NET works using disconnected data. When you create a dataset by using a data adapter, the data is actually created using XML. To see proof of this, take a look at dsCustomerIndividual.xsd, found in the Solutions Explorer. This is all performed under the covers, so the good news is that you don't have to know XML to work with datasets and ADO. More information on this can be found in Chapter 3.
4. The last task is to give you the capibility to cancel the edits. You do this by placing the following code in the Click event on btnCancel. Calling the CancelCurrentEdit method of the BindingContext object for the form, the current edits are cancelled. Next, the text boxes are disabled using the routine ActivateEditing. Listing 1.10 frmHowTo1_4.vb: Canceling Changes to Data and Disabling the Text Boxes Again
Private Sub btnCancel_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCancel.Click ' Use the BindingContext class to cancel the current editing. "Customers").CancelCurrentEdit() ActivateEditing(False)
Me.BindingContext(Me.dsCustomerIndividual, _
Page 37
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub
How It Works
When the user clicks the btnEdit button, the ActiveEditing routine alerts the user that he can edit the data in the text boxes. The text boxes are enabled. If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server. If the user clicks the btnCancel button, the edits are canceled. In both cases, the
ActivateEditing routine is called to disable the text boxes and let the user know that the text
boxes cannot be edited.
Comments
This How-To showed the bare bones for editing and updating data. It presented a basic technique to get started. As you continue, you will learn methods to add and delete records, as well as handle errors. Using ADO.NET, which you use for bound controls, takes some getting used to if you have worked with other data accessing methods such as ADO and DAO. The BindingContext and
BindingManagerBase objects make working with bound objects in code much more manageable.
[ Tea m LiB ]
Page 38
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.5 Add and Delete Records Using Bound Controls
Besides editing data, adding new records and deleting records in a table are obviously important features. This How-To shows you just that, taking advantage of the BinderContext class. Besides being able to edit current records that already exist, users need to be able to add and delete records as well. How do you add and delete records using bound controls?
Technique
To create the Add New Record feature, you will add a button called btnAddNew that has code behind it. You will use the BindingContext object again to add a new record by using the AddNew method. A module variable will be added to the form to keep track of whether a record is being added or edited. If a new record is being added, then when the update is performed, the application needs to reload the data in the list box in case the new record's CompanyName data falls into the chosen list limit that is specified in the txtCustLimit text box. To create the Delete Record feature, you will add a button called btnDelete. This button will have code behind it that will use the RemoveAt method of the ContextBinding object to remove the record from the dataset. The data will then be posted back to the server.
Steps
Open the solution for the chapter called "VB .NET How-To Chapter 1," and run the application. From the main form, click on the command button labeled How-To 1.5. Click the Load List button. Click the button labeled New. Enter the text ALF for Customer ID and Alfred's Fried Foods in the Company Name. Then click the button labeled Save, and see the record you just entered added to the list. After the record has been entered, you can test the delete feature by clicking on the button named Delete. The record goes away, and the list is rebuilt. 1. Add a new command button under btnEdit, and then set the Name property to btnNew and the Caption property to &Save. 2. Add a new module-level variable called mbAddNew, which is a Boolean variable to keep track of whether you are adding a new record. This variable will be placed outside of your routines, just under the forms code. You can see this in Figure 1.9. Figure 1.9. By placing this variable just underneath Windows Form Designer Generated Code and declaring it Private, routines inside the Class can see it, but those outside cannot.
Page 39
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Tip
You can collapse and expand routines that you are working on within modules. This makes it handy when you are working on new routines (which can be expanded) and don't want to mess with old routines (which can be collapsed).
3. Add the following code to the Click event of the new command button btnNew. This code first sets the Boolean variable called mbAddNew to True. It then uses the AddNew method of the form's BindingContext object to add a new record to the dsCustomerIndividual dataset. Finally, the code calls the ActiveEditing routine to enable the text boxes. Listing 1.11 frmHowTo1_5.vb: Adding a New Record to the dsCustomerIndividual Dataset and Toggling Text Boxes
Private Sub btnNew_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnNew.Click mbAddNew = True ' Using the BindingContext class add a new record
Me.BindingContext(Me.dsCustomerIndividual, "Customers").AddNew() ActivateEditing(True) End Sub 4. Modify the Click event of the btnSave to test whether the mbAddNew flag has been set to
Page 40
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html True, meaning that a new record is being added. If True, then after saving the record by calling the SaveRecord and ActivateEditing routines, the LoadList and RefreshIndividual are called to load the new record's data. Note that the SaveRecord, ActiveEditing, and RefreshIndividual routines have not changed from How-To 1.4. The mbAddNew variable is then set to False.
Listing 1.12 frmHowTo1_5.vb: Saving the Changed Data, Toggling Text Boxes, and Reloading the List Box and First Record in the List
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click ' Save the information
SaveRecord() ' Disable the text boxes
ActivateEditing(False) If mbAddNew Then LoadList() RefreshIndividual() mbAddNew = False End If End Sub 5. Modify the Click event for the btnCancel button to reset the mbAddNew variable to False, as seen in Listing 1.13. Listing 1.13 frmHowTo1_5.vb: Canceling the Edit and Resetting the mbAddNew Variable
Private Sub btnCancel_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCancel.Click ' Use the BindingContext class to cancel the current editing.
Me.BindingContext(Me.dsCustomerIndividual, "Customers").CancelCurrentEdit() ActivateEditing(False) mbAddNew = False End Sub 6. Now it is time to add the delete functionality. To do this, add the following code to the
Click event of the new button called btnDelete. The first line of the code you added begins by introducing a new method called RemoveAt and a new property called Position, both used with the BindingContext object. You will work from the inside out. The Position property tracks the current position in the dataset, in this case dsCustomerIndividual. The RemoveAt method marks the record that is at the position
passed to it for deletion. Next, the Update method of the odaCustomerIndividual adapter is used to call the
Page 41
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html DELETE SQL statement command against the dataset, deleting the actual rows in the data set. The AcceptChanges method is called to send the changes to the dataset, a delete in this case, back to the server. Finally, the LoadList, RefreshIndividual, and ActivateEditing subroutines are called to refresh the list, refresh the first record in the
list for the text boxes, and toggle the text boxes so that the user knows he can't edit them. Listing 1.14 frmHowTo1_5.vb: Deleting the Selected Record and Reloading the List Box
Private Sub btnDelete_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDelete.Click ' Mark the row for deletion using the RemoveAt method of the BindingContext "Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual, "Customers").Position) ' ' Perform the requested task at the dataset level using the data adapter
Me.BindingContext(Me.dsCustomerIndividual, _
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") ' By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges() ' Reload the list
LoadList() ' Display the first record
RefreshIndividual() ' Disable the text boxes
ActivateEditing(False) End Sub
How It Works
When the user clicks the btnNew button, a flag (mbAddNew) is set to True, the dataset is set for adding a record with the AddNew method of the BindingContext, and the text boxes are enabled for editing. If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server. If the user clicks the btnCancel button, the edits are canceled. In both cases, the mbAddNew variable is set to False and the ActivateEditing routine is called to disable the text boxes and let the user know that the text boxes are not available for editing. Finally, if the btnSave button was clicked and the mbAddNew was set to True, the LoadList and RefreshIndividual routines are called. When the user clicks the btnDelete button, the record is deleted from the recordset and then from the server. The list box is reloaded and the first record in the list is displayed in the text boxes. The text boxes are then disabled.
Page 42
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Comments
Here you have the basic commands needed to create a full-fledged data entry form. You can add, edit, and delete information from the form. This actually takes less code than if you use Visual Basic 6.0. The BindingContext object really goes a long way to helping you work with bound data.
[ Team LiB ]
Page 43
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.6 Take Care of Error Handling with Bound Controls
When dealing with database tasks, you are going to get runtime errors. In .NET, we call the various types of errors you can get exceptions. This How-To shows examples of what exceptions could occur and how to handle them using the Try, Catch, and Finally statements. Adding and deleting records is fine, but what happens if an error occurs? You tried to delete an existing company, and got the screen that appears in Figure 1.10. Figure 1.10. This is an unhandled error, called an exception in .NET.
How do you make it so errors are handled gracefully within the application using bound controls?
Technique
Error handling is one of the most important aspects of working with data, between when a user is entering data and updating the server. If you don't have proper error handling, your system will, in the best situation, give an ugly error message, and in the worst, blow up and put bad data in your system. In Visual Studio .NET, errors are classes called exceptions. Many different (inherited) types of exceptions exist. Run-time exceptions can occur in just about any part of your application. They can be handled by using Try...Catch...Finally or they can be unhandled, where you will see the error in Figure 1.11. Figure 1.11. This error was thrown up from one subroutine to the one that called it.
Take a look at a common way to trap exceptions shown in Listing 1.15. Listing 1.15 Standard Code for Handling Exceptions
Private Sub MySub() Try ' Code to be handled here
Page 44
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Catch dataException as Exception MessageBox.Show(dataException.Message) Finally ' Code that will occur regardless of if an error occurs. End Try End Sub
Following are some basic points to help you when working with exceptions and Try...Catch...Finally blocks:
The name of the exception object can be whatever you want it to be. dataException was just used as an example.
Specific types of exceptions inherit from the base class of System.Exception.
OleDbException is one of those classes, and you will see an example of using this class in
the following steps.
You can use the Throw statement within a Catch statement to throw the exception back up to a calling subroutine.
You can use the When clause on the Catch statement to trap for specific exceptions. When multiple Catch statements are used, each one is executed unless an End Try or End
Sub is placed within a Catch block, as in this How-To.
You can use multiple Catch statements to handle various possible exceptions that can occur. You will see an example of these bullets in the following steps.
Steps
Taking the form with which you have been working, you are going to modify it to trap exceptions when the record is being saved (either for additions or editing) and when the record is deleted. You will also add some code in the event when closing the form. 1. Modify the code in the Click event of the command button called btnSave. You will surround the SaveRecord routine call with a Try...Catch...End Try block. If an exception occurs, the Show method of the MessageBox class is called, passing the Message property of the Exception object called saveException. Next, the subroutine is exited. If no errors occur, then life goes on, and so does the subroutine. Listing 1.16 frmHowTo1_6.vb: Code Added to btnSave Click Event to Trap Save Exceptions
Private Sub btnSave_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSave.Click Try
Page 45
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
' Save the information
SaveRecord() Catch saveException As Exception MessageBox.Show("The following error has occurred: " & _ saveException.Message, "Error Saving Record") Exit Sub End Try ' Disable the text boxes
ActivateEditing(False) If mbAddNew Then LoadList() RefreshIndividual() mbAddNew = False End If End Sub 2. Modify the SaveRecord routine to "throw" the exception up to the btnSave_Click subroutine, or whatever happens to have called the SaveRecord routine. Following is the
SaveRecord subroutine with the new Try...Catch...End Try block added, along with the Throw statement.
Listing 1.17 frmHowTo1_6.vb: Pass the Exception Back Up to the Calling Routine
Private Sub SaveRecord() Try ' ' Use the BindingContext class to end the current editing so that we can update the server. "Customers").EndCurrentEdit() ' ' Perform the requested task at the dataset level using the data adapter
Me.BindingContext(Me.dsCustomerIndividual, _
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") ' By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges() Catch saveException As Exception Throw saveException End Try
Page 46
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 3. Now it's time to deal with adding exception handling to the btnDelete Click event, as seen next. The Try statement is used to wrap the code that performs deletion of the data. The code then uses a Catch statement to check whether the exception that occurs is a specific OleDbException, 3621, which is an error having to do with trying to delete a record when related records exist in another table. Note that you could and in fact should assign this to a constant value. Because delException has been caught as an
OleDbException, you can look at the NativeError property of the first error in the Errors collection to get the actual OleDb error number. If the error is not 3621, then the exception is trapped with the next Catch statement, and a messagebox is displayed. If errors occur,
then the subroutine is exited before the final lines of code are executed. Listing 1.18 frmHowTo1_6.vb: Catching Exceptions When You're Deleting a Record
Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click Try ' Mark the row for deletion using the RemoveAt ' method of the BindingContext Me.BindingContext(Me.dsCustomerIndividual, "Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual, "Customers").Position) ' ' Perform the requested task at the dataset level using the data adapter
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") ' By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges() Catch delException As System.Data.OleDb.OleDbException _ When delException.Errors(0).NativeError = 3621 MessageBox.Show("An error occurred because of related order records.", "Error Deleting Customer", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Sub Catch delException As Exception MessageBox.Show(delException.Message, "Error Deleting Customer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Sub End Try ' Reload the list
LoadList()
Page 47
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'
Display the first record
RefreshIndividual() ' Disable the text boxes
ActivateEditing(False) End Sub
How It Works
When an exception occurs within the Try...Catch...End Try block, the Catch statements are compared when a When clause is used or when the code is simply executed. If a Throw statement is used, then an execution is thrown back up a level to the Try...Catch...End Try block containing the call to the routine where the Throw statement occurred. You can see an example of this in Figure 1.11.
Comments
Microsoft has gone to great length to let you control how you handle exceptions in .NET with the various languages. You can be as creative as you need to by using the Try...Catch...End Try block with all the clauses available. Exceptions bring back plenty of information so that you can create pretty slick error handling. You can use exceptions to create a centralized routine that logs errors, or even one that e-mails exception information to you from your applications.
[ Team LiB ]
Page 48
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.7 Put the Finishing Touches on a Data Bound Form
Besides handling the basics, you need to add some finishing touches to a data entry form, such as enabling/disabling controls based on whether you're on a record. This How-To shows you how to use the Enabled properties on controls to give the user more direction when using a Windows form (see Figure 1.12). Figure 1.12. You will create this complete form by How-To 1.7, with all the bells and whistles that users expect from a good data entry form.
Although the majority of the major issues are taken care of for the form you created so far in the chapter, your users become confused about when to push some of the buttons. How do you get the buttons to reflect when the users can click them, and what other finishing touches might help the form?
Technique
An important part of user interfaces is letting the user know when he has access to certain features on the form. In this case, you will see how to do the following:
Toggle the enabled property of the btnSave, btnCancel, btnNew, and btnDelete at the appropriate moments, such as when a record is highlighted in the list box.
Add a command button to close the form. Add code to the Closing event of the form that tests whether you have made changes to the current record, and if so, whether you want to save the changes.
You can see an example of particular command buttons being enabled based on the current action being performed in the form in Figure 1.13. Figure 1.13. This form allows users to access command buttons only when the functionality is available.
Page 49
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Steps
Continuing on with the form that you have been using, you are going to make the changes just mentioned in the previous bulleted list. 1. Start by modifying two routines already created: RefreshIndividual and
ActivateEditing subroutines. Then check whether a customer has been selected in lstCustomers. If not, then the two buttons, btnEdit and btnDelete, are disabled. If a
customer hasn't been selected, the two buttons are enabled, and the dsCustomerIndividual dataset control is refreshed. Listing 1.19 frmHowTo1_7.vb: Toggling the Enabled Property of the btnEdit and btnDelete Buttons
Private Sub RefreshIndividual() ' Clear individual customer dataset
Me.dsCustomerIndividual.Clear() If lstCustomers.SelectedIndex = -1 Then btnEdit.Enabled = False btnDelete.Enabled = False Else btnEdit.Enabled = True btnDelete.Enabled = True Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = lstCustomers.SelectedItem(0) ' Fill the dataset
Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual, "Customers") End If End Sub Similarly, you will add code to the ActivateEditing subroutine to toggle the Enable
Page 50
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
property of the various command buttons, depending on their purpose. Listing 1.20 shows the entire routine. Listing 1.20 frmHowTo1_7.vb: Toggling the Enabled Property of btnEdit and
btnDelete Buttons
Private Sub ActivateEditing(ByVal bEnable As Boolean) Dim oCurr As Object ' Loop through each of the controls on the form
For Each oCurr In Me.Controls() ' Check to see if the control is a text box
If TypeOf oCurr Is TextBox And oCurr.Name <> "txtCustLimit" Then ' If so, toggle the properties
If bEnable Then oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.Fixed3D oCurr.BackColor() = System.Drawing.Color.White Else oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.FixedSingle oCurr.BackColor() = Me.BackColor
End If oCurr.Enabled = bEnable End If Next ' Enable/Disable the appropriate buttons
btnEdit.Enabled = Not bEnable btnNew.Enabled = Not bEnable btnDelete.Enabled = Not bEnable btnCancel.Enabled = bEnable btnSave.Enabled = bEnable ' Set the focus to the CustomerID text box Me.txtCustomerID.Focus()
If bEnable Then
Page 51
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End If End Sub The specific lines of code added are shown here:
'
Enable/Disable the appropriate buttons btnEdit.Enabled = Not bEnable btnNew.Enabled = Not bEnable btnDelete.Enabled = Not bEnable btnCancel.Enabled = bEnable btnSave.Enabled = bEnable
These buttons are handled as the other buttons are by taking the opposite value to which bEnable is currently set, and using it to toggle the Enabled property. Finally, if the bEnable flag is True, then focus is moved to the txtCustomerID text box using the following lines of code:
'
Set the focus to the CustomerID text box If bEnable Then Me.txtCustomerID.Focus() End If End Sub
2.
Add a new command button, with the properties Name and Text set to btnClose and
&Close, respectively. Place the code in Listing 1.21 for the Click event.
Listing 1.21 frmHowTo1_7.vb: Close the Form
Private Sub btnClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnClose.Click Me.Close() End Sub 3. Add some code to the Closing event of the form. Listing 1.22 tests whether the btnSave button is enabled. If it is, the MessageBox method is evoked, asking the user if he wants to save changes that were made. If so, then the SaveRecord is called within a Try...Catch...End Try block. Listing 1.22 frmHowTo1_7.vb: Checking Whether the User Wants to Save a Record Before Closing
Private Sub frmHowTo1_7_Closing(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing ' ' If an edit or add has been requested, enabling the Save button, then prompt to save the record
If btnSave.Enabled Then
Page 52
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
If MessageBox.Show("Would you like to save the current record?", _ "Save Record?", MessageBoxButtons.YesNo) = _ DialogResult.Yes Then Try ' Save the information
SaveRecord() Catch saveException As Exception If MessageBox.Show("The following error has occurred: " & saveException.Message & vbCrLf & vbCrLf & _ "Continue with closing the form?", "Error Saving Record", MessageBoxButtons.YesNo) = DialogResult.No Then e.Cancel = True End If
End Try End If End If End Sub
How It Works
In the modifications made to the form in this How-To, many things happen depending on what is occurring. When the user clicks the btnEdit button, btnEdit, btnNew, and btnDelete are disabled, and btnCancel and btnSave are enabled. The opposite is true when btnCancel and
btnSave are pressed. If bEnable is True, then the focus is moved to the txtCustomerID text
box. When the txtClosed button is clicked, the application then checks whether the btnSave command button has been enabled, meaning data is being edited. If so, then the user is asked whether he wants to save the current record. If the user does, the system then saves the current information back to the server.
Comments
The tasks displayed in this How-To are just a few of the tasks you can do to make your forms look and feel more professional. They are also what users come to expect from database applications. Play with the form a bit more. You're sure to come up with a few more ideas.
[ Team LiB ]
Page 53
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.8 Bind Data to ComboBox and DataGrid Controls
Sometimes you might want to use a ComboBox control instead of a ListBox control to display a list of choices. You also might want to display information in a grid style based on the item chosen in that combo box. This How-To describes how to bind data to both ComboBox and DataGrid controls. Instead of using a ListBox control to display customers, you would like to use a ComboBox control to display them. After you choose a customer, you would like to display information about the orders that belong to that customer. How do you bind data to the ComboBox and then bind the
DataGrid control as well? Technique
To bind both the ComboBox and the DataGrid controls, you will use the same properties and coding techniques that you have used for the ListBox control. You will first create DataAdapter and DataSet controls to which to set the DataSource properties. The DataAdapter for the
DataGrid will include a parameter that will use the value selected in the ComboBox control.
You will set the DataSource properties of the controls to the DataSet created. That is all you really have to set for the DataGrid control. For the ComboBox control, you will also set the ValueMember and DisplayMember properties. You will then add code to fill the DataSet control to which the DataSource property is set for the
ComboBox control. Finally, you will create a subroutine to store the selected value in the ComboBox in the DataAdapter that was created for filling the DataSet on which the DataGrid control is
based. After the user has selected a value in the ComboBox that contains the customers, the DataGrid control displays the orders for that customer, as can be seen in Figure 1.14. Figure 1.14. Users can display the header information for customer orders using these two controls.
Steps
Page 54
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You will be starting with a fresh form. 1. 2. Add a new Windows Form called frmHowTo1_8. Add the OleDbDataAdapter and DataSet controls with the properties set forth in Table 1.7 .
Table 1.7. OleDataAdapter and DataSet Controls Object Property Setting
OleDataAdapter Name
odaCustomerList
SelectCommand OleDbSelectCommand1 CommandText SELECT CustomerID, CompanyName FROM Customers dsCustomerList dsCustomerList odaOrdersForCustomer
DataSet
Name DataSetName
OleDataAdapter Name
SelectCommand OleDbSelectCommand2 CommandText SELECT OrderID, OrderDate, RequiredDate, ShippedDate FROM Orders WHERE (CustomerID = ?) ORDER BY OrderDate dsOrdersForCustomer dsOrdersForCustomer
DataSet
Name DataSetName
3.
Tip
You will want to create the OleDbDataAdapter controls using the Data Adapter Configuration Wizard, and then set the name after the DataAdapter has been created. You will want to create the DataSet controls by right-clicking on the appropriate OleDbDataAdapter and choosing Generate Dataset. If you have questions about creating these controls, reread How-To 1.1.
Page 55
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Also, remember that when generating the DataSet, VS always changes the name by adding a 1 on the end and capitalizing the first letter. You might want to change it to what you really want in the properties directly.
4. Add the ComboBox and DataGrid controls, as well as the Label for the ComboBox, setting the properties as shown in Table 1.8.
Table 1.8. Label, ComboBox, and DataGrid Controls Property Settings Object Property Setting
Label
Name Text
Label1 "Customers to List Orders For:" cboCustomers dsCustomerList.Customers CompanyName CustomerID dgOrders dgOrdersForCustomer.Orders
ComboBox Name DataSource DisplayMember ValueMember DataGrid Name DataSource
5.
Add code shown in Listing 1.23 to the Load event of the form. This code fills the
dsCustomerList DataSet control based off the select statement used in the odaCustomerList OleDbDataAdapter control. After this occurs, the RefreshOrders
subroutine is called, displayed in Listing 1.24. Listing 1.23 frmHowTo1_8.vb: Filling the Dataset Used by the ComboBox Control
Private Sub frmHowTo1_8_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.odaCustomerList.Fill(Me.dsCustomerList) RefreshOrders() End Sub Listing 1.24 frmHowTo1_8.vb: Filling the Dataset Used by the DataGrid Control, Based on the Item Selected in the ComboBox Control
Private Sub RefreshOrders()
Page 56
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'
Clear Orders for customer dataset
Me.dsOrdersForCustomer.Clear() ' Check to see if an item was selected
If Me.cboCustomers.SelectedIndex <> -1 Then ' ' Store the selected customer ID into the parameter
the SQL data adapter Me.odaOrdersForCustomer.SelectCommand.Parameters(0).Value = _ Me.cboCustomers.SelectedItem(0) ' Fill the dataset
Me.odaOrdersForCustomer.Fill(Me.dsOrdersForCustomer) End If End Sub 6. Add the code in Listing 1.25 to the SelectedIndexChanged event of the cboCustomers ComboBox controls. Listing 1.25 frmHowTo1_8.vb: Refreshing the DataGrid Control Based on Selected Item
Private Sub cboCustomers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCustomers.SelectedIndexChanged RefreshOrders() End Sub
How It Works
When the form is first loaded or a new item is selected in the ComboBox control, the DataGrid control is filled with order information for the selected customer.
Comments
As you can see from this How-To, using the ComboBox control and DataGrid controls are not much tougher than using the ListBox control. The DataGrid control does offer quite a bit more power to let you create Main/Subform type forms such as invoices. You will see an example of this in the next How-To. The DataGrid control also lets you edit data.
[ Team LiB ]
Page 57
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 1.9 Drill Down to Data in the DataGrid Control
The DataGrid control in Visual Basic .NET is an effective way to display multiple records related to a base table, such as Customer and Orders tables. You can then drill down into individual orders to see the details. This How-To explains how to open an additional form with another DataGrid control and drill down to the order details. Although it is nice to see what orders a customer has, you would like to display more information about the orders. How do you drill down into the details of the orders displayed in the DataGrid control?
Technique
Using the form you started in How-To 1.8, you are going to allow the user to highlight a specific order. You are going to drill down to it by opening a new form and having that form's text boxes display order header information. Then you will use another DataGrid control to display order details. You can see this example in Figure 1.15. Figure 1.15. Drilling down to an order's detail.
Besides adding a new form, you will also create a new module to be used to declare a public variable for tracking the calling form. In the previous examples, the sample form was opened by declaring a variable in the Click event of the individual Button controls on frmMain. For this How-To, the declaration of the variable pointing to that specific form has been moved to a public module. You can see the code for the Click event for btnHowTo1_ 8 and btnHowTo_9 in Listing 1.26. Listing 1.26 frmMain.vb: Opening a New Form to Display Order Information
Private Sub btnHowTo1_8_Click(ByVal sender As System.Object, ByVal e As
Page 58
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html System.EventArgs) _ Handles btnHowTo1_8.Click Dim frm1_8 As frmHowTo1_8 frm1_8 = New frmHowTo1_8() frm1_8.Show() End Sub Private Sub btnHowTo1_9_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles btnHowTo1_9.Click frm1_9a = New frmHowTo1_9a() frm1_9a.Show() End Sub
Listing 1.27 presents the code for the module created, called modPublicVariables. Listing 1.27 modPublicVariables.vb: Declaring a Public Variable for a Form
Module modPublicVariables Public frm1_9a As frmHowTo1_9a End Module Steps
You will want to create a module as described in the "Technique" section of this How-To to open the form that you created in How-To 1.8. After you have created that module and added the Public variable declaration as shown in Listing 1.27, open the form from How-To 1.8 in Design. 1. Add a button control to the bottom-right side of the form, under the DataGrid control. Set the Name property to btnOrderDetail and the Text property to &Order Detail. 2. In the Click event of the btnOrderDetail, add the code shown in Listing 1.28. Listing 1.28 frmHowTo1_9.vb: Opening a New Form to Display Order Information
Private Sub btnOrderDetail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOrderDetail.Click Dim frm As New frmHowTo1_9b() frm.Show() End Sub 3. Create a new form and name it frmHowTo1_9b (or whatever you called it when following Listing 1.28). 4. Add some OleDataAdapters and DataSets to the form, as laid out in Table 1.9.
Page 59
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 1.9. OleDataAdapter and DataSet Controls for the frmHowTo1_9b Form Object Property Setting
OleDataAdapter Name
odaIndividualOrder
SelectCommand OleDbSelectCommand1 CommandText SELECT OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry FROM Orders WHERE (OrderID = ?) dsIndividualOrder dsIndividualOrder odaEmployees
DataSet
Name DataSetName
OleDataAdapter Name
SelectCommand OleDbSelectCommand2 CommandText SELECT EmployeeID, RTRIM(LastName) + ', ' + RTRIM(FirstName) AS FullName FROM Employees dsEmployees dsEmployees odaOrderDetails
DataSet
Name DataSetName
OleDataAdapter Name
SelectCommand OleDbSelectCommand3 CommandText SELECT OrderID, ProductID, UnitPrice, Quantity, Discount FROM [Order Details] WHERE (OrderID = ?) dsOrderDetails
DataSet
Name
Page 60
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataSetName
5.
dsOrderDetails
Add the controls that will use these data controls for data sources, found in Table 1.10.
Table 1.10. Controls to Display Order Information, Including Order Details Object Property Setting
Label
Name Text
Label1 "Order ID" Label2 "Order Date" Label3 "Employee" txtOrderID FixedSingle dsIndividualOrder - Orders
.OrderID
Label
Name Text
Label
Name Text
TextBox
Name BorderStyle Text
DateTimePicker Name
DateTimePicker1
DataBindings dsIndividualOrder - Orders. - Value OrderDate Format ComboBox Name DataSource Short cboEmployees dsEmployees.Employees
DisplayMember FullName ValueMember EmployeeID
SelectedValue dsIndividualOrder - Orders. EmployeeID DataGrid Name DataSource dgOrderDetails DsOrderDetails.Order_Details
Page 61
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6. Add the code in Listing 1.29 to the Load event of the new form you have created. The first thing that this code does is fill the DataSet control use by cboEmployees. Next, using the
CurrentCell.RowNumber property of the DataGrid control used on the frmHowTo1_9a form, the OrderID column is read in the specified row of the DataSet control called dsOrdersForCustomer.
The OrderID, which is stored in lngOrderID, is supplied to odaIndividualOrder and
odaOrderDetails. Then the OleDbDataAdapters are used to fill the datasets.
Listing 1.29 frmHowTo1_9b.vb: Loading the Appropriate Datasets
Private Sub frmHowTo1_9b_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim lngOrderID As Long ' Fill the dataset used for the Employee combo box.
Me.odaEmployees.Fill(Me.dsEmployees) ' ' Get the OrderID from the currently select order in the DataGrid control on the calling form.
lngOrderID = frm1_9a.dsOrdersForCustomer. _ Orders.Rows(frm1_9a.dgOrders.CurrentCell. _ RowNumber).Item("OrderID") ' Update the caption of the form with the order ID and customer " For " & frm1_9a.cboCustomers.Text ' Load the parameter for the order header with the InvoiceID
Me.Text = "Order #" & CStr(lngOrderID) & _
Me.odaIndividualOrder.SelectCommand.Parameters(0).Value = lngOrderID ' Fill the order header dataset
Me.odaIndividualOrder.Fill(Me.dsIndividualOrder) ' Load the parameter for the order detail with the InvoiceID
Me.odaOrderDetails.SelectCommand.Parameters(0).Value = lngOrderID ' Fill the order detail dataset
Me.odaOrderDetails.Fill(Me.DsOrderDetails) End Sub
How It Works
The user highlights one of the Orders in the dgOrders on the first form and then clicks the
btnOrderDetail button to open the second form. The second form is used to display the details of the order. When the second form is opened, the cboEmployee ComboBox control is loaded, and the OrderID is retrieved from dsOrdersForCustomer via dgOrders, located on the first form. The DataSets controls dsIndividualOrder and dsOrderDetails are then filled.
Page 62
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Comments
This is just a start of what can be done using the DataGrid control. You will see this control used in quite a few chapters, including Chapter 3 and 4. As you can see from the way the OrderID was retrieved from the first form, it can be a little confusing when you need to get to the data programmatically.
[ Team LiB ]
Page 63
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 2. Creating SQL Server Database Objects From Visual Studio .NET
You will learn about the following in this chapter:
Create a new SQL Server database from within Visual Studio .NET Define tables and fields Define a primary key and other indexes Define relations between tables Define defaults and constraints Create views Create stored procedures
When starting out with working with databases, it's a good thing to know how to create them. This example shows how to create a SQL Server database using Visual Studio .NET and also talks about servers and security.
[ Team LiB ]
Page 64
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Working with Tables, Columns, and Rows
The basic entity that holds data in your database is a table, which is analogous to the manila folder of customers. A table is made up of columns (also referred to as fields.) Picture a page of information that you keep on a customer. The information would have Last Name, First Name, Address, and so on. These would be columns in a table. The filled out page of information would be a row (or record) in your table, and it would be made up of columns. The database would be the filing cabinet, which would be made up of multiple tables (manila folders) with different subjects besides customers, such as invoices, parts information, and so on. Double-click on the Northwind node in the server explorer, you will then see a list of tables that are part of the database. If you open the Customers table in Design mode, you will see the various columns in the table. Then when you open your table to see the data, you will see the columns for each row or record in your table.
[ Team LiB ]
Page 65
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Utilizing Properties for Tables and Columns
Tables and columns, like other objects in your database, have properties that allow you to control the data that is going into your tables. For example, in the Customers table, you can see the properties for the first column, called CustomerID. The extent to which you use the properties depends on what your needs are. At the table level, you also have properties that you can utilize that help you create and enforce business rules, which are discussed later in this chapter. You will create your tables by breaking down your data into logical entities. When you do so, you need to keep in mind how you break them down, and you need to break them down so that they are created in what is called normalization. SQL Server has come a long way over the years. For every version, Microsoft works hard not only to make SQL Server more powerful, but also easier to work with. This includes tools that come with the product and from other applications. Visual Studio .NET is a good example of tools for working with SQL Server from another product. If you are not familiar with databases, here's a quick overview. Databases allow you to work with data in a manner that reflects the real world on the computer. You can take a real subject, such as Customers, and store that information in tables. A file cabinet is analogous to a database. Within the file cabinet you may have your client folders. Other folders might contain information on Orders or Invoices. One of these folders could be compared to a table of customers. Within the Customers folder, you might have individual pages of information on a customer. Each page that you have on an individual customer would be a row, or a record within a table. On each page, you would have pieces of information such as Customer Name, Address, Phone, and so on. These would be fields, or columns, within each row. In a database, you will also have objects that allow you to query information within tables and update information. In SQL Server, you will use Views, Stored Procedures, and Functions to view and update data within the database. To use these objects, you need to be able to create them. To create a database along with its tables in SQL Server, you can use code or tools that came with SQL, such as the Enterprise Manager, if you have installed one of the versions that include these tools. Fortunately, you can use tools that are built within Visual Studio .NET to create and modify your databases. The primary tool you will use is called the Server Explorer, as shown in Figure 2.1. Figure 2.1. From the Server Explorer within Visual Studio .NET, you can perform most of the tasks that are necessary to maintain a database.
Page 66
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
[ Team LiB ]
Page 67
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.1 Create a New SQL Server Database from Within Visual Studio .NET
Before working with a database, you have to be able to create it. Although you could use code to do this, you would rather do it right from Visual Studio. How do you create a new SQL Server database from within VS .NET?
Technique
As mentioned in the Introduction of this chapter, databases are basically file cabinets in computers. That sounds pretty simplistic, but if you take the information that you store in your file cabinets and transfer it over to the computer, you will end up with the same elements. You can physically create a new SQL Server database in several ways:
Use SQL Server's Enterprise Manager to create the database. Programmatically create the database. You can do this by using T-SQL and SQL-DMO, which are discussed in Chapters 6, "Creating Transact-SQL Commands," and 7, "Performing Common Database Tasks Using SQL-DMO," respectively.
Use a menu in the Server Explorer of Visual Studio .NET to perform this task.
You will use the last option to complete the task presented in this How-To.
Steps
To get started with this How-To, leave Visual Studio at the Start Page when you open it. Then place the cursor on the Server Explorer icon on the left side of the screen. Note The way that the Server Explorer and toolbox icons are laid out on the side of the screen varies according to how you set the Profile option in the My Profile settings on the Start Page either Visual Studio Developer or Visual Basic Developer.
After the Server Explorer has expanded, click on the plus symbol next to the Servers node. Then you can follow down the tree by clicking on your computer's name (SHADRACH2 in Figure 2.1) and then SQL Servers. Clicking on the name of the computer again, you will see the list of current databases that are set up by default in the Microsoft SQL Server Desktop Edition (MSDE). Although doing this was not necessary to create a new database, it does give you an idea of where you can see various databases in your system. Now you will learn how to create a database in VS .NET. 1. You can open the Create Database dialog box from within the Server Explorer in two ways. The first way is to right-click on the Data Connections node and choose Create New SQL Server Database. The second way is to right-click on the SQL Server instance to which you want to add the database in this case, SHADRACH2 and then choose New Database. Although both methods open the Create Database dialog box, the second method fills in the server name for you. 2. Fill in the name of the database you want to create in this case, Chapter2.
Page 68
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. Choose the type of security that you want to use with this database. If your network is strictly a Windows 2000 network, you can leave this as the default User Windows NT Integrated Security; otherwise, choose the option. Your Create Database dialog box should look like Figure 2.2. Figure 2.2. This is all the information you need to create a new database.
4.
Click OK to complete the dialog box and create the new database.
How It Works
Now you when you click on the plus sign for the new database, you will see branches in the tree view of the Server Explorer for the different database objects, described in this chapter's introduction.
Comments
The Microsoft Visual Studio and SQL Server teams have gone to a lot of effort to make VS .NET the only design tool you need to use to create databases and their objects. Sometimes you will need to perform tasks that are beyond what you can accomplish in the Server Explorer, but this chapter will stick to VS .NET. Now it's time to see how to create some of the objects that actually make a database useful.
[ Team LiB ]
Page 69
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.2 Define Tables and Fields
A SQL Server database doesn't do much good unless you have tables in it. This tutorial not only gives you information on how to create tables and fields, but also teaches you how to name them and what to look out for when creating them. Databases by themselves don't do much for you, but you need to be able to store data in them at the very least. To do this, you need to be able to create tables, which are made up of fields. How do you go about defining tables and fields in VS .NET?
Technique
Using the Server Explorer and accessing the Table designer, you are going to create a table called tblCustomers in the database that you created in the previous How-To. You will then add columns to the database that will store various pieces of information having to do with individual customers. Last, you will create another table called tblPhones and also create the necessary columns that will contain information about phone information for your customers.
Steps
After Visual Studio .NET is opened, expand the Server Explorer and locate your new database called Chapter2, created in How-To 2.1. Click on the plus sign by the database names so that the database object categories are listed. 1. Right-click on the Tables node under the Chapter2 database and choose New Table. You will then be presented with the Table Designer. Now you are ready to add the columns. 2. To add a column, you need to set four immediate properties:
o
Column Name. This is the name of the column. Don't use spaces or special characters, but do use proper case, and make sure that the name you give the column makes sense for what it contains. For instance, if the column is for the last name of a customer, put LastName for the Name property of the column.
o
Data Type. Depending on the type of data that will be entered into the column, this will be one of the many valid data types for SQL Server, shown here in Table 2.1.
Table 2.1. SQL Server Data Types Data Type Description Integer (whole number) data from up6 2
63 63
bigint
(
9,223,372,036,854,775,808) through 2 \ 1\up6 (9,223,372,036,854,775,807). 2^31 (
int
Integer (whole number) data from 2,147,483,648) through 2 (2,147,483,647).
31
1
smallint
Integer data from 2
15
15
(
32,768) through 2
1 (32,767).
Page 70
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
tinyint bit decimal
Integer data from 0 through 255. Integer data with either a 1 or 0 value. Fixed precision and scale numeric data from 10
38
+ 1 through 10
38
1.
numeric money
Functionally equivalent to decimal. Monetary data values from 2
63
(
63
922,337,203,685,477.5808) through 2 1 (+922,337,203,685,477.5807), with accuracy to a ten-thousandth of a monetary unit.
smallmoney
Monetary data values from 214,748.3648 through +214,748.3647, with accuracy to a ten-thousandth of a monetary unit. Floating precision number data from 1.79E + 308 through 1.79E + 308. Floating precision number data from 3.40E + 38 through 3.40E + 38. Date and time data from January 1, 1753, through December 31, 9999, with an accuracy of three-hundredths of a second, or 3.33 milliseconds. Date and time data from January 1, 1900, through June 6, 2079, with an accuracy of one minute. Fixed-length non-Unicode character data with a maximum length of 8,000 characters. Variable-length non-Unicode data with a maximum length of 8,000 characters. Variable-length non-Unicode data with a maximum length of 2 1 (2,147,483,647) characters.
31
float real datetime
smalldatetime
char
varchar text
nchar
Fixed-length Unicode data with a maximum length of 4,000 characters.
Page 71
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
nvarchar ntext
Variable-length Unicode data with a maximum length of 4,000 characters. Variable-length Unicode data with a maximum length of 2 1 (1,073,741,823) characters.
30
binary Varbinary image
Fixed-length binary data with a maximum length of 8,000 bytes. Variable-length binary data with a maximum length of 8,000 bytes. Variable-length binary data with a maximum length of 2 (2,147,483,647) bytes.
31
1
cursor sql_variant
A reference to a cursor. A data type that stores values of various SQL Server-supported data types, except text, ntext, timestamp, and sql_variant. A special data type that stores a result set for later processing. A database-wide unique number that is updated every time a row is updated.
table timestamp
uniqueidentifier A globally unique identifier (GUID).
o
Tip
Unicode is a character-encoding standard that uses 16-bit code values. This standard is used worldwide to represent all the characters that are used in modern computing. Traditional character sets are the previous character-encoding standards such as the Windows ANSI character set that use 8-bit code values or combinations of 8-bit values to represent the characters used in a specific language or geographical region. It is recommended that you use Unicode data types nchar, nvarchar, and ntext rather than their non-Unicode counterparts.
Page 72
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Also, use the variant length type data types whenever possible. Doing so will save disk space and save you from having to trim your values when you want to display the data in the fields.
o
Length. This varies depending on which data type you choose. For text data types, this will be the maximum length you expect to be entered into the column.
o
Allow Nulls. This specifies whether you will allow null values to be saved in the record for the column. This means that the user doesn't have to enter a value at all. This is sometimes a bad idea, such as when you have specific data that has to be entered, like Social Security Numbers.
For the first few columns in the table, enter the following data. You can see how the table will look in Figure 2.3. Figure 2.3. Fields for your first table.
Column Name LastName FirstName Address City State ZipCode
Data Type
Length 50 50 50 50 2 9
Allow Nulls Unchecked Unchecked Checked Checked Checked Checked
nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar
Page 73
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BirthDate MailingList EstimatedSales
3.
datetime bit money
8 1 8
Checked Checked Checked
Save the table by clicking on the X in the top-right corner of the Table Designer, and name the table tblCustomers when prompted. After you click the X, you are asked if you want to save the table. Then you are prompted for the name to save the table as.
How It Works
By entering the information in the various properties for each column, you are specifying how you want the data in your database to be treated. Generally, your users won't create tables; you will create the tables for the users, and they will fill the data into the tables using your applications. When the user fills in the data, the application and SQL Server control what type of data goes into the table, starting with what the data type of the data is and what the allowed length is. The Allow Nulls property determines whether the user even has to enter data.
Comments
Creating the tables, made up of columns and rows, is the basis for the database's purpose: storing information. Making sure that you use logical, descriptive names for columns, along with data types that help control how the data gets entered into the database, is key to a successful database. Plan out your tables ahead of time, examining each real-world object, and transfer those properties to the columns that make up the tables that represent your objects.
[ Team LiB ]
Page 74
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.3 Define a Primary Key and Other Indexes
Indexes are used to improve performance when querying data, such as searching on fields and sorting information. The primary key is an index that ensures that you have at least one unique value in each record, such as a Customer ID. This How-To discusses what the best candidates are for primary keys, as well as how to create them and other indexes. You have created a base table and have even entered data into it. How do you make sure that you have a way of finding specific records? LastName and FirstName fields won't work because you can have duplicates of those. You also want to make sure that when you search on fields, you get the best possible performance from SQL Server. Indexes can be created to help performance. How do you define a primary key field to make sure that you have unique records and can create other indexes as well?
Technique
Within the Server Explorer, you can use a field, such as a Social Security Number, and make that into a primary key field. By making a field the primary key field, you will need to make that field unique and prohibit null values there. The alternative to a current unique field is to create a field that is automatically incremented, called an identity field. This identity field can also be set as the primary key field, again so that the record is made unique. The primary key field will also be indexed. Besides creating the special primary key field, you can create indexes that perform two main functions:
Performance. Used to increase performance when the column is used for search criteria and sorting and when you're loading ranges of records.
Constraints. This is one of the jobs that the primary key field performs data that users can put into the table.
constraining the
Note When creating indexes for performance purposes only, take care that you don't go overboard. Although indexes help performance when searching and sorting, they can hurt performance when adding and updating data. This is mainly true when importing or adding large amounts of data. The other point is that when the table is small, you can over-index as well.
While you're in the table designer, you can get to Indexes, located on the Property Pages dialog box, by choosing Indexes/Keys from the View menu. You can see the Property Pages dialog box in Figure 2.4. Figure 2.4. You can create all the necessary indexes using this dialog box.
Page 75
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Within Indexes, you have some options to specify, such as whether you would like to have the values in the index be unique You will want to have tables where you have a lot of data and you will be deleting or updating large amounts of records at a time. You also will use a field in a range situation, such as using BETWEEN, >, >=, <, and <= for operators.
Steps
Using the Server Explorer, open the Chapter2 database and right-click on the tblCustomers that you created in the last How-To. Then select Design Table from the right-click menu. 1. Place the cursor in the first row, if it isn't already there. Click the right mouse button, and choose Insert Column from the menu. Next, fill in the properties of the field as follows:
Property
Value
Column Name DataType Length Allow Nulls Identity
CustomerID int 4 Unchecked Yes
Page 76
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
2. When you specify that you want to make this an identity field, the next two properties will be used. The first, Identity Seed, is what the column's values will be started at. The next property, Identity Increment, will be how records that are added will be incremented. 3. Right-click in the Column Name property of the CustomerID column, and then choose Set Primary Key from the menu. You have now set the CustomerID to be the primary key, and the screen should look similar to Figure 2.5. The index that you just created when you specified CustomerID to be the primary key falls into the constraint category of indexes. Figure 2.5. You need to have one primary key field per table.
4.
To create other indexes that will help performance, choose Indexes/Keys from the View menu to open the Property Pages dialog box.
5.
On the Indexes page, click the New button, and then fill in the following properties to add an index for the LastName field: Index Name with "IX_LastName" and Column Name with "LastName."
Tip If you sort on multiple columns such as LastName and FirstName together, which is quite common, you could add the FirstName column underneath the LastName column in the last step. This is called a compound index.
How It Works
When you create tables, you create your primary key columns and indexes at the same time. You can come up with indexes at a later date as well.
Page 77
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Comments
Be sure to create a primary key column for each of your tables, and use identity columns for primary columns whenever possible. SQL Server will take advantage of indexes you have created, but just be careful not to over-index. Remember to examine what columns you will be sorting and querying on. With particularly large tables, indexes become more important than ever.
[ Team LiB ]
Page 78
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.4 Define Relations Between Tables
Relationships define how your information needs to "relate" between tables in your database. For example, perhaps you have tables in your database called Customers, Orders, and Order Details as the sample Northwind database does. You would want to create relationships between these tables to make sure that data integrity is maintained as users enter data into the database. Taking this further, you need to make sure that each invoice has an existing customer for every invoice. This is called referential integrity. This How-To shows you how to create relationships as well how to view the relationships by using database diagrams. You have created a couple of tables where one relies on another to have data in it. In database terms, they are related. How do you create relationships between tables?
Technique
Referential integrity tells the database how tables are to relate to one another. You can use referential integrity to help control what data goes in each of tables, based on data in other tables. To maintain referential integrity, you need to create relationships between tables. An example of referential integrity from Northwind is that to have a record entered into the Orders table, you have to have a record entered into the Customers table. The two tables are related by the CustomerID field, which is found in both two tables. In the Customer table, the CustomerID field is the primary key, which means that it will be unique. In the Orders table, the CustomerID field is a foreign key, which means it points to a primary key in another table. You can see this displayed in the database diagram in Figure 2.6. Figure 2.6. The column CustomerID is the primary key in Customers and a foreign key in Orders.
Note Database diagrams are the main graphical way to view, edit, and print
Page 79
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
relationships. You will find them listed under the database you are working on in the Server Explorer. You can also get the Property Pages for tables from this dialog box and perform the majority of work with regard to interaction between tables, other than structure changes on tables.
Another purpose of referential integrity and relations is that you also can specify to do the following:
Prohibit a parent record (from table Customers, for example) from being deleted or the key field from being edited if a record exists in the child records (Orders).
If the column relating the tables is updateable, have the system allow the key column to be updated in the parent record, and have the child records reflect the change in the key columns. This is called cascade updates.
Have the child records be deleted if the parent record is deleted. This is called cascade deletes.
Three different types of relationships exist when you're creating the relations between tables:
One-to-many. Used when you have one record in the parent table, with many records in the child table. The Customers/Orders relationship that is displayed in Figure 2.6 is an example of this type of relationship. This is the most common type of relationship. If you look at the join line between the tables in Figure 2.6, you will see a key on the Customers end. This represents the one side, and the infinity symbol by the Orders table represents the many side.
One-to-one. One record in the parent table will have one related record in the child table. An example of this could be if you had private information for customers that you wanted to keep in a separate table. These two tables would have the same primary key column. This relation type is not used often because developers can use views to limit the data to which users have access.
Many-to-many. Records in the parent table can have many related records in the child table, and records in the child table can belong to many records in the parent table. An example of this can also be found in the Northwind database. Customers can have demographics tracked for them. Customers can have many demographic types, and demographic types can be assigned to many customers. This relationship is displayed in Figure 2.7. Figure 2.7. The Customers, CustomerCustomerDemo, and CustomerDemographics table make up this many-to-many relationship.
Page 80
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Steps
Using the Server Explorer, expand the Chapter2 database to see how to create a relationship. It helps to have more than one table. Because you have already created the table called tblCustomers, create the new table called tblCustomerPhones, with the following columns. Column Name PhoneID CustomerID PhoneType PhoneNumber Data Type Length 4 4 50 10 Allow Nulls Unchecked Unchecked Unchecked Unchecked Identity Yes No No No
int int nvarchar nvarchar
Set the PhoneID as the primary key and save the table as tblCustomerPhones. This table will contain the various phone numbers and types that an individual customer can have. This is an easy way to check out how to create a one-to-many relationship. 1. Right-click on Database Diagrams in the Chapter2 database tree in the Server Explorer. Choose New Diagram from the menu. The Add Table dialog box will appear. 2. Hold down the Shift Key and select both tblCustomers and tblCustomerPhones. Click the Add button to add the tables to the diagram, and then click the Close button. You will now see the two tables in the new database diagram. 3. Place the cursor on the primary key symbol in the CustomerID column of tblCustomers. Hold down the left mouse button and drag and drop the cursor over to the CustomerID column in tblCustomerPhones. The Create Relationships dialog box will be displayed, with the pertinent information filled in for you.
Page 81
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4. Select the Cascade Delete Related Records; that way, when a customer is deleted, the phone records that have been assigned will also be removed. You can see the final relationship in Figure 2.8. Click OK to accept this relationship. Figure 2.8. You have complete control over relationships from this dialog box.
How It Works
Creating proper relationships in your database controls how good your data is going to be. The old term "Garbage In, Garbage Out" has meaning in this case. When a user adds information to tables that have relationships set up, he has to enter the data in a certain order. In this case, a user needs to add customers before adding phone information. If customers are deleted, then the phones that have been assigned to them will be deleted as well.
Comments
You will set up your forms in a logical manner based on the way that relationships are set up. For instance, a good way to set up adding your phone numbers to the form would be to use the grid control to display your many phones for one customer. Another way to enhance this example would be to add another table to hold the phone types and then to link this new table to tblCustomerPhones via a link called PhoneTypeID. For more examples of relationships, check out the tables and their relationships in Northwind. Create a database diagram, add a table in which you are interested, and then view the related tables.
[ Team LiB ]
Page 82
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.5 Define Defaults and Constraints
One of the main concepts to keep in mind when you're creating databases is that you need to provide a means to keep garbage (bad data) out of your tables. Default values make sure that each new record begins with valid data. An example of this is if you want to make sure that a date is entered for the order date of an invoice. You could set up a default value of today's date for new records. Constraints allow you to specify what business rules you want to use with your tables, such as if you want to allow dates that are entered into the Order Date field to come after today's date. This How-To explains how to use defaults and constraints to their full potential and how to create them in Visual Studio .NET. You have started down the path of handling your business rules by creating tables and setting the data types of the columns in the tables. You have even set up relationships between tables. Now you want to make life easier for your users and suggest what values they could use, and more importantly, what values are acceptable. How do you do this by defining defaults and constraints?
Technique
By using default values, you can guide your users and save them time. For example, perhaps you have a mailing list application, and the user is entering addresses. If the majority of the entries are from Washington (or WA), then you could set the default property of the State field to be WA. Check constraints, not to be confused with the constraint type of index, allow you to create validation clauses that can control data that goes into the tables. An example of this would be if you didn't want someone from California (CA) entered into the addresses table from the last paragraph. You could then enter a constraint check that would read something like State <> 'CA'. Note The rest of this chapter will use the Northwind database because it has a great structure that makes it easy to show how to use necessary techniques.
For this How-To, in Northwind's Orders table, you are going to add a default value to the OrderDate column and a check constraint that validates the ShipDate to make sure it occurs on or after the OrderDate.
Steps
Using the Server Explorer, expand the tables branch in the Northwind database, right-click on the Orders table, and choose Design Table. 1. 2. Place the cursor in the OrderDate column. Type GetDate() in the Default Value property. The GetDate() function returns the current system date and time. This squares away the default value. 3. To enter the check constraint, open the Property Pages dialog box by right-clicking on the
Page 83
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
column and choosing Check Contraints from the menu. 4. 5. Click New on the Property Page dialog box. Enter ([ShippedDate] >= [OrderDate]) into the Constraint Expression. You can see the completed constraint in Figure 2.9. Notice that you can also specify when the constraint will be checked by selecting the options located at the bottom of the Check Constraints page. Figure 2.9. Constraints can be used to verify that data falls within business rules that you specify.
6.
Click OK to accept the new constraint.
How It Works
When a new record is saved to the Orders table, if no OrderDate is added, then the GetDate() will add the system date. After that, the constraint that was added will check to see that the ShippedDate entered falls on or after the OrderDate. If this is the case, then an error message will be displayed.
Comments
Default values make users' lives easier when they can be used. You can also use default values so that users will be less tempted to leave values blank, or NULL. Check constraints allow you to further control how data is entered into your database. They can be
Page 84
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
used both when modifying data and when adding new records. Be sure to set up what you need for constraints when you are creating the database.
[ Team LiB ]
Page 85
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.6 Create Views
After you figure out you want to use a view, the trick is to create it by using the designer. This How-To explains how to do this from within Visual Studio .NET, including specifying sort order and criteria. Now that you have your tables created, with relationships in place, you can add data by double-clicking the table name in the Server Explorer. I also know how to bind forms and controls to data using data binding from the last chapter. How do you create views, using VS .NET?
Technique
Within SQL Server, you can view and manipulate data using one of three ways:
Views. These allow you to display different views of your data, including joining tables, sorting (SQL Server 200x), and using criteria. Views are limited to using the SELECT statement, and they can be used as the base for updating as well displaying data. Views are great when you need to filter your data but want to be able to update like you would a single table.
Stored procedures. Perform bulk operations such as updating, inserting, and deleting records. You can also create select queries that can be sorted. Another difference from Views is that you can use multiple SQL and control-of-flow statements within a stored procedure. You can also use parameters with stored procedures.
User-defined functions. User-defined functions are one of three types: Scalar, Table, and In-Line. These types combine the best features of views and stored procedures into a single query that you can nest, pass parameters to, sort, and return values.
You can find more on stored procedures in How-To 2.7. When you want to have various views of your data that you will want to use throughout your application(s), you can create views to do so. You can then use the view to populate forms, controls, and reports. Note In versions of SQL Server prior to 2000, use of views was frowned upon because of performance and sorting limitations, among other reasons. This has changed with 2000, where views are more flexible and offer better performance.
Within Visual Studio .NET, you can create, update, and delete SQL Server views all from within the Server Explorer, within the desired database. To work with views, you will use the Views Designer. For new views, you will choose New View while right-clicking on the Views node in the database. If you're editing, choose Design View while right-clicking on the desired view. You will then be taken into the View Designer, as shown in Figure 2.10, with the view called Current Product List. Figure 2.10. Using the View Designer, you can see the tables you want to include, the fields you are using, the SQL Statement created, and even the data that will be returned.
Page 86
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
As you can see from Figure 2.9, the View Designer has the four main areas mentioned:
Diagram pane. This area allows you to display the table or tables(s) that you will be using in your view. This could also contain the following: other views, user-defined functions, sub queries (in FROM clause, and linked views. You will also see check boxes (or other objects) flowing down the left side of the tables. These allow you to choose fields that you want to include. You can also see some other icons along the right side of the tables, when grouping and sorting fields or when using criteria. You will see examples of these if you look through the existing views in Northwind. You can also join tables so that you can view data using multiple record sources.
Grid Pane. This is where you will specify how you want individual columns to be handled within the view. The following table describes each property:
Column Description Column Display of either the name of a data column used for the query or the expression for a computed column. The name you want to use in the result set. This allows you to either rename an existing column or name a new computed column. You might want to rename an existing column if you have the same column used in two different tables. The name of the table where the column is from. Whether to display the column in the results set. Whether you want to sort the column in ascending or descending order. If you don't want to sort on the column, leave it blank. Here you will specify where in the sorted columns you want to include this column. You can place a number that corresponds with the column order that
Alias
Table Output Sort Type Sort Order
Page 87
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
you want this column included in. Group By This is where you specify that you want to use the current column for aggregating information. To get this column to show, you need to choose Group By from the Query menu. Besides Grouping data on this column, you can also specify functions such as Min, Max, Count, and more. This column allows you to specify to which value you would like to compare the column to narrow down and return specific records. If you specify values in multiple columns, you will create a Boolean (AND) expression. Placing values in these columns will cause Boolean (OR) expressions to be created .
Criteria
Or
SQL Pane. You will see the SQL Select statement that is created by filling in the two previous panes mentioned.
Results Pane. As the title suggests, this pane will display the results of the view created when you click the Run Query toolbar button, which is the exclamation.
Steps
To learn how to create a view in Visual Studio .NET, you will create a view that displays all the orders for a given date, including the owners of each of the orders. You will also have the view sorted by CompanyName, then OrderID. Open the Server Explorer and expand the Northwind database. 1. Right-click on the icon on the Views node and select New View from the menu. The Add Table dialog box will then be opened. From the menu, you will select the tables, views, or functions that you want to include in the view. 2. Select Customers. Then, holding down the Ctrl key, select the Orders table. Click Add and then click Close. The tables will then be dropped into the Diagram pane, and you will be presented with the View Designer. One thing to notice is the symbol shown between the two tables, displayed in Figure 2.11. The symbol chosen by default in this case represents an inner join. An inner join is when values in the first table must match values from the second table, using the join column which, in this case, is CustomerID. Figure 2.11. Using this menu, you can specify how you want the tables to be joined.
Page 88
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You can see the symbols for the other two types of joins displayed in the right-click menu. These types of joins include Left Outer Join (Select All Rows From Customers) and Right Outer Join (Select All Rows From Orders.) Using the various types of joins, you can alter the data results that are returned. 3. Place checkmarks in the CompanyName column, from the Customers table, and then the OrderID and OrderDate columns, located in the Orders table. When you place the checkmark in the columns, you will see both the Grid pane and the SQL pane fill out, provided you have them showing. 4. Next, type the expression = '7/19/1996' into the Criteria column of OrderDate, located in the Grid pane. If you just type the date, VS will place the other values around it. You have now added criteria. Only those orders with this date will be returned. 5. Pick Ascending for the Sort Type of the CompanyName and OrderID columns. Notice that Sort Order will be filled in automatically, depending on the order in which you pick the Sort Type.
How It Works
When you click on the Run Query command, which is an icon on the toolbar, you will see two records displayed in the Results pane.
Comments
After a view has been created, you can use it in various ways throughout your applications. In the next chapter, you will see examples of using views with ADO.NET to populate various controls. You can also use view within views, store procedures, and user-defined functions. This is handy when you have a set of results that you want to use consistently in your applications and they rely on more than one table.
[ Team LiB ]
Page 89
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 2.7 Create Stored Procedures
Stored procedures allow you to perform bulk operations on records, such as updating, inserting, and deleting data as needed. This tutorial shows you how to create stored procedures as well as how to test them from within the Server Explorer. Viewing data is great, but you need to perform bulk operations such as adding, updating, and deleting records. You know that you will be using a stored procedure to perform these tasks, and you will be using them more than once in your application. How do you create stored procedures from VS?
Technique
Stored procedures are the way to go when you want add, delete, or update records or when you want to use a parameter. When you have a task that requires multiple actions, including temporary tables, stored procedures give you this ability. Stored procedures are powerful to use and easy to create. Note To create stored procedures, you will use what is called Transact-SQL (T-SQL). Although this chapter will present some simple commands to show the interface used to create stored procedures from VS .NET, Chapter 6, "Creating Transact-SQL Commands," goes into more detail on the commands of the language.
As with views, you will use a designer within Visual Studio. Unlike the Views designer, the stored procedure designer is not visual initially, but more text oriented. However, you can pull up a visual designer after you are in the text designer. When you're creating a new stored procedure, you will right-click on the Stored Procedures node in the database to which you want to add the stored procedure, and then you will choose New Stored Procedure. To edit existing stored procedures, you will highlight the stored procedure, right-click, and choose Edit Stored Procedure. After the stored procedure is open, you will see a select statement or a number of T-SQL statements. If it is a new stored procedure, you can right-click and choose Insert SQL. You will be taken to the Query Builder, which happens to look like the View designer. If it is an existing stored procedure, you can place the cursor within a block of SQL code, which is outlined with a blue line, and choose Design SQL Block from the right-click menu, as shown in Figure 2.12. Figure 2.12. You can also set break points in your stored procedures using this menu.
Page 90
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You will then see the SQL block displayed once again in the Query Builder. When specifying parameters that can be used as criteria in stored procedures, you will use the @ symbol in front of the parameter name, and declare them at the top of your stored procedure. Again, you can see this in Figure 2.12.
Steps
For this How-To, you are going to create a simple Select statement with a parameter, listing customers for a given city. If you're not already there, open the Server Explorer and expand the Northwind database. 1. Right-click on the Stored Procedures node, and then choose New Stored Procedure. You will be taken into a new page that is a template for stored procedure text. You will see the following listed: 2. 3. 4. 5. 6. 7. 8. 9. 11. */ /* SET NOCOUNT ON */ 10. AS 12. RETURN 13. Replace all the text displayed with the following: 14. 15. CREATE PROCEDURE dbo.spListCustomersForCountry 16. @parCountry char ) CREATE PROCEDURE dbo.StoredProcedure1 /* ( @parameter1 datatype = default value, @parameter2 datatype OUTPUT
Page 91
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
17. AS 18. 19. Select * From Customers where Country = @parCountry RETURN With this, you can see the use of the parameter. 20. Save the stored procedure.
How It Works
To test the stored procedure that you just created, you can right-click on the block of code and choose Design SQL Block from the menu. You can then click on the Run Query toolbar button and fill in the parCity parameter with USA when the dialog box is presented. You will then see the information displayed in the Results pane. You will see examples of using stored procedures in the next chapter, which discusses using ADO.NET with SQL Server objects.
Comments
Although you can create stored procedures on-the-fly and not save them in the database, it is sometimes necessary and desirable to save them permanently so that you can use the same code in different places in your application.
[ Team LiB ]
Page 92
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 3. Viewing Data With ADO.NET
In this chapter you will
Retrieve data using the DataReader object Retrieve results from SQL Server by using the DataTable object Locate records with the DataTable object Filter and sort records by using the DataView object
ActiveX Data Objects (ADO) was introduced a few years ago as a solution to accessing data that can be found in various forms, not only over a local area network (LAN), but over the Internet as well. ADO was the new generation of data access that replaced Remote Data Objects (RDO) and Data Access Objects (DAO), originally created for the JET database engine. JET was originally created for Microsoft Access, and was later used as a choice of databases for small- and medium-sized single- and two-tier database solutions. Then along came ADO.NET.
[ Team LiB ]
Page 93
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Differences Between ADO and ADO.NET
ADO and ADO.NET are different in several ways:
ADO works with connected data. This means that when you access data, such as viewing and updating data, it is real-time, with a connection being used all the time. This is barring, of course, you programming special routines to pull all your data into temporary tables. ADO.NET uses data in a disconnected fashion. When you access data, ADO.NET makes a copy of the data using XML. ADO.NET only holds the connection open long enough to either pull down the data or to make any requested updates. This makes ADO.NET efficient to use for Web applications. It's also decent for desktop applications.
ADO has one main object that is used to reference data, called the Recordset object. This object basically gives you a single table view of your data, although you can join tables to create a new set of records. With ADO.NET, you have various objects that allow you to access data in various ways. The DataSet object will actually allow you to store the relational model of your database. This allows you to pull up customers and their orders, accessing/updating the data in each related table individually.
ADO allows you to create client-side cursors only, whereas ADO.NET gives you the choice of either using client-side or server-side cursors. In ADO.NET, classes actually handle the work of cursors. This allows the developer to decide which is best. For Internet development, this is crucial in creating efficient applications.
Whereas ADO allows you to persist records in XML format, ADO.NET allows you to manipulate your data using XML as the primary means. This is nice when you are working with other business applications and also helps when you are working with firewalls because data is passed as HTML and XML.
[ Team LiB ]
Page 94
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Objects That Are Found in ADO.NET
As mentioned previously, the main object that is used with ADO.NET is the DataSet object. You can see the DataSet object and its properties, methods, and additional objects in Figure 3.1. Figure 3.1. ADO.NET has several more objects than ADO does.
Take a look at Table 3.1 to see a brief description of some of the objects that you will be using during this How-To. Table 3.1. ADO.NET Data Objects That Are Used to Manipulate Data Object Purpose This object is used in conjunction with the other data controls, storing the results that are returned by commands and the data adapters. Unlike the recordset from ADO and DAO, the data set actually brings back a hierarchical view of the data. Using properties and collections in the DataSet object, you can get overall relations, individual tables, rows, and columns.
DataSet
DataTable
One of the objects off of the data set, the DataTable object enables you to manipulate an individual table's worth of data. The data table is similar to the recordset object that is found in ADO.
Page 95
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataView
Using this object, you can filter and sort your data, keeping various views of the data. Each data table has a default view, which is the starting data view that can be modified and stored in a separate data view. This object enables you to manipulate the rows of data in your data tables. This can be thought of as a cache of data that you can manipulate by adding, deleting, and modifying records. You can then accept the changes back to the recordset, where you will then run SQL statements to update data back at the server.
DataRow
DataColumn As the name suggests, you can get information at the column level by using the DataColumn object. You can get schema information as well as data using this
object. For example, if you want to create a list box of names of fields, you could iterate through the DataColumn collection off a data row and retrieve all the names of the fields.
PrimaryKey This object allows you to specify a primary key for a data table. That way, when you
use the Find method of the data table, it knows which column to use . .NET also provides classes, called data providers, to work with ADO.NET objects to provide access to data. You can see some of those objects in Figure 3.2. Figure 3.2. You can use either OleDb classes or SQLClient classes for better performance.
Note Your Visual Studio .NET applications are made up of one or more assemblies. Each assembly contains one or more Namespaces. Namespaces are then made up of one or more classes (objects). Therefore, the Namespace for your OleDb objects is
System.Data.OleDb. You can find these objects using the Object
browser.
In Table 3.2, you can see a brief description of some of the objects that you will be using during this How-To.
Page 96
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 3.2. .NET Data Provider Classes That Are Used to Manipulate Data Object Purpose Similar to the ADO Command object, this allows you to execute stored procedures in code. Unlike the ADO version, however, you can create a DataReader object using the ExecuteReader method.
Command
Connection
This object opens a connection to the server and database with which you want to work. Unlike the ADO Connection object, the way that the connection remains open depends on the object with which you are working, such as a DataReader or
DataSet object. DataAdapter A real workhorse, the DataAdapter object allows you to create SQL statements
and fill datasets with the data. It also creates other necessary action queries, such as Insert, Update, and Delete ADO.NET command objects.
DataReader
This object creates a read-only, forward-only stream of data that allows you to quickly populate controls, such as ListBox and ComboBox controls. This object allows you to specify the parameter (or parameters if you use more than one) that DataAdapter objects can specify and use.
Parameter
Tip Chapter 1, "Developing Windows Forms Using Bound Controls," mentioned that the OleDb data controls are the ones that you will want to use for various types of backends, whereas the SQLClient data controls work strictly with SQL Server. The same is true of using these objects as well. If you know that you will just be using a SQL Server backend, you will get better performance by using the SQLClient objects because a layer is cut out.
You will get a chance to see all of the items listed in the previous two tables throughout the following How-Tos. Tip If you have to stick with ADO or just want to be stubborn, check out using ADO with .NET by reading Appendix A, "Desktop Development with ADO." Although ADO.NET does take more work sometimes to accomplish a task that you could do using ADO, the power and flexibility of ADO.NET is well worth the learning curve.
Note Although this chapter was written using Windows Forms, the majority of the objects can also be used in Web Forms as well as by using ADO.NET with ASP.NET. You will see this in Chapter 5, "Working with Date in Web Forms." You will learn various methods for achieving the same goal. When and
Page 97
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
how you use these methods will depend on the scenario.
All of the examples in this chapter can be found in the Solution called VB.NET Web site.
Chapter 3 on the
[ Team LiB ]
Page 98
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 3.1 Retrieve Data by Using the DataReader Object
In Chapter 1, you learned how to use bound controls to OleDb controls that could be included on the forms. Some developers prefer to use unbound controls to perform the same task. The DataReader object allows you to add items to a list box in a more efficient manner because it is only a read-and-forward-only type object. This How-To tells you how to generate a limited ListBox control by using a DataReader object. You want to create a limited list of customers. You don't want to use bound controls because you are a cool VB developer who knows better than that. You heard that the DataReader object is a fast way to get data. How do you retrieve data using the DataReader object to perform this task?
Technique
For this How-To, you will be using the ListBox control and loading items into it by using the
DataReader object. To get to the DataReader object, you need to look at the Command object.
The Command object in .NET works similarly to the ADO Command in that you will assign the stored procedure name or SQL statement to the CommandText property as well as the connection to use. One difference is that you will use the Open method of the Command object, and then the
ExecuteReader method, to create the DataReader object.
You will then use the Read method off of the DataReader object to perform two tasks. The first task is that when used in a loop, you can test for datareader.Read() to check whether to terminate the loop and also to iterate through the rows that the DataReader object returns. After you have the DataReader populated and you are iterating through the rows, you will load the data into the ListBox control. You will be using the Clear and Add methods, which were used in VB 6. In addition, you will use the BeginEdit and EndEdit methods, which speed up loading ListBox controls when you are loading a large amount of data. To view this example in design view, open the form called frmHowTo3_1.vb in the chapter's solution.
Steps
Open and run the VB.NET Chapter 3 solution. From the main form, click on the command button with the caption How-To 3.1. When the form loads, click on the Load List command button. You will see the list below fill with all the company names that start with A. You will be creating a form similar to one that was created in Chapter 1. Instead of using bound controls, however, you will use code along with ADO.NET to populate the ListBox control. 1. Create a Windows Form. Then place a Label, TextBox, ListBox, and Command button on the form with the properties that are listed in Table 3.3 set.
Table 3.3. Label, TextBox, ListBox, and Command Button Control Property Settings Object Property Setting
Label
Name
Label1
Page 99
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Caption TextBox Name Text ListBox Command Button Name Name Caption
2.
Customer txtCustLimit A lstCustomers btnLoadList Load List
Notice that the list box does not have the DataBindings properties set. That is because you will be using the ListBox control unbound. Look at Figure 3.3 to see what the form should look like. 3. Figure 3.3. Arrange the controls on the form that you created to look like this form.
4. 5. Before creating the code that will be attached to the Click event of the btnLoadList command button, you need to devise a support routine to create the connection string. Called BuildCnnStr, the function can been seen in Listing 3.1. This function takes a server and database names that are passed to it and creates a connection string. Listing 3.1 modGeneralRoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, _ ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";"
Page 100
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method is to pass back a string. The reason for this is that for some objects, you are asked for a Connection object, whereas in other objects, you just need a string. You will see BuildCnnStr called in the next step. 6. On the btnLoadList Command button, add the following code from Listing 3.2 to the Click event. In this routine, a SQL string is created and stored in the strSQL string, taking Text property of the txtCustLimit text box and adding it to a literal. Then, within a Try-Catch-End-Try block, a new instance of an OleDbCommand object called ocmdCust is created. The routine then follows the steps that are discussed in the Technique section. Listing 3.2 frmHowTo3_1.vb: Loading a List Box By Using the DataReader Object
Private Sub btnLoadList_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadList.Click Dim ocmdCust As OleDb.OleDbCommand Dim odrCust As OleDb.OleDbDataReader Dim strSQL As String '-- Create the SQL String strSQL = "Select CompanyName From Customers Where CustomerID Like '" & Me.txtCustLimit.Text & "%'" '-- Set up the exception catch Try '-- Create an instance of the command ocmdCust = New OleDb.OleDbCommand() With ocmdCust '-- Set up the connection of the command and the command text .Connection = _ New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) .Connection.Open() .CommandText = strSQL '-- Set up the data reader instance odrCust = .ExecuteReader(CommandBehavior.SequentialAccess) End With '-- Add the items to the list box. With lstCustomers .Items.Clear() .BeginUpdate() Do While odrCust.Read
Page 101
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
.Items.Add(odrCust.Item("CompanyName")) Loop .EndUpdate() End With Catch oexpData As OleDb.OleDbException MsgBox(oexpData.Message) End Try End Sub Note Something of interest to those VB developers is the fact that the lines of code that read as follows:
.Connection = _ New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind"))
actually declare, initialize, and use an OleDBConnection object in the single statement. This is new to .NET and is extremely useful.
How It Works
When the user clicks the btnLoadList button, the Command object is assigned the necessary properties, the connection is opened, and the ExecuteReader method is called. After the list has been cleared, the DataReader is iterated through, and the ListBox control is loaded.
Comments
The DataReader object is one of the most efficient ways to get data from the server and load lists into your application. Other options besides CommandBehavior.SequentialAccess are available that make the DataReader convenient to use. Most notable is CommandBehavior.SchemaOnly, which returns information only about the columns, and no data. You can use the Command object in a number of ways besides what was mentioned in this How-To. You will see additional examples of using the Command object with stored procedures to perform batch actions later in the chapter. You have seen how to use the ListBox control in a total unbound technique. In the next How-To, you will see a blend of using the ListBox control in a semibound technique, where you will bind the data at runtime.
[ Team LiB ]
Page 102
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 3.2 Retrieve Results from SQL Server by Using the DataTable Object
The data reader is great when you just want to load data into a ListBox or ComboBox control manually, but you can save some coding by binding the ListBox control to a data table at runtime, as well as providing the ability to get not only the displayed value, but the key column as well. This How-To demonstrates how to bind a limited ListBox control to a data table. Although getting the quick information is great, you need to be able to refer back to the table of information, and you don't want to have to open another connection to get there. You know that the DataTable object should allow you to perform this task. How do you get results from SQL Server by using the DataTable object?
Technique
Using the Windows Forms controls that were introduced in How-To 3.1, you will use a familiar object from Chapter 1 called the DataAdapter object. This time, instead of using the OleDbDataAdapter data control, you will use the OleDbDataAdapter class from the
System.Data.OleDb Namespace.
Using a similar technique that was used when filling a DataSet, you will instantiate the data adapter by assigning the SQL string and connection object. Then, instead of filling a DataSet object, you will fill a DataTable object. Because you will only be dealing with a table's worth of data, you just need to use a data table. That way, you will be able to perform lookups more conveniently, as shown in the next How-To. For now, the next step will be to assign the following properties of the list box:
DataSource. This will be set to the DataTable object in this case, dtCust. DisplayMember. This specifies which column from the data table to use for display in the
list box.
ValueMember. Here, you will specify which column you want to use for the value that is
retrieved when an item is selected from the list box.
By programming the ListBox control using this technique, you can access the ValueMember column in the SelectItem property of the list box.
Steps
Open and run the VB.NET Chapter 3 solution. From the main form, click on the command button with the caption How-To 3.2. When the form loads, click on the Load List command button. You will see the list below fill with all the company names that start with A. 1. To save time, you can make a copy of the form that was created in the first How-To in this chapter. 2. Replace the btnLoadList Click event with the following code listed here in Listing 3.3. That's it. After creating the SQL string that will be used and storing it in strSQL, the data adapter called odaCust is created. The odtCust data table is then filled using odaCust. Last, the DataSource, DisplayMember, and ValueMember properties are set for the lstCustomers list box. This was all accomplished with a Try-Catch-End-Try block of code.
Page 103
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 3.3 frmHowTo3_2.vb: Loading a List Box By Using the DataTable Object
Private Sub btnLoadList_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadList.Click Dim odaCust As OleDb.OleDbDataAdapter Dim dtCust As DataTable = New DataTable() Dim strSQL As String '-- Create the SQL String strSQL = "Select CustomerID, CompanyName From Customers " & _ "Where CustomerID Like '" & Me.txtCustLimit.Text & "%'"
'-- Set up the exception catch Try '-- Create an instance of the data adapter, ' and then fill the data table odaCust = New OleDb.OleDbDataAdapter(strSQL, _ BuildCnnStr("(local)", "Northwind")) odaCust.Fill(dtCust) '-- Bind the data to the list box lstCustomers.DataSource = dtCust lstCustomers.DisplayMember = "CompanyName" lstCustomers.ValueMember = "CustomerID" Catch oexpData As OleDb.OleDbException MsgBox(oexpData.Message) End Try End Sub
How It Works
When the user clicks on the btnLoadList button, the data adapter called odaCust is instantiated. The data adapter is passed strSQL and the connection string that is created by the function called
BuildCnnStr, which was introduced in the first How-To in this chapter. The data table is then filled, and then the DataSource, DisplayMember, and ValueMember properties of the ListBox control
are assigned.
Comments
Using the data table sets up the scene for using the list box in retrieving data in the next How-To. Remember: By using the DataTable object, you can assign both the display value and the data item to be tracked.
[ Team LiB ]
Page 104
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 3.3 Locate Records with the DataTable Object
Using the DataTable object, you can use another object called the DataRow object that allows you to locate a specific row in the data table. This is useful when you want to present your users with a search mechanism for your form. This How-To shows you how to locate a specific row within your data table and how to use the same data table for two different purposes. After you have your DataTable object loaded in memory, you want to be able to locate specific records within the DataTable object. How do you locate records in the DataTable object?
Technique
For this How-To, you are going to use a ComboBox control instead of a ListBox control. You will use the same technique for loading the combo box as you would the list box. The change comes when you select an item from the combo box. When an item is selected in the combo box, the SelectedIndexChanged event is fired off. Within this event, you will take the combo box's SelectedItem, which gives the ValueMember that is located in the selected row, and use that with the Find method off the DataTables Rows collection. With the data row located, the corresponding columns are loaded into text boxes on the form, as shown in Figure 3.4. Figure 3.4. This combo box will point the user to a specific customer.
Steps
Open and run the VB.NET Chapter 3 solution. From the main form, click on the command button with the caption How-To 3.3. When the form loads, pick a new customer from the list that is presented in the customer ComboBox control. You will see the text boxes below the ComboBox
Page 105
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
control display new data that corresponds to the chosen customer. 1. 2. Create a new Windows Form. Add some labels, combo boxes, and text boxes, as listed in Table 3.4.
Table 3.4. Label, TextBox, and ComboBox Control Property Settings Object Property Setting
Label
Name Caption
Label1 Customer cboCustomers Label2 Customer ID Label3 Company Name Label4 Address Label5 City txtCustomerID txtCompanyName txtAddress txtCity
ComboBox Label
Name Name Caption
Label
Name Caption
Label
Name Caption
Label
Name Caption
TextBox TextBox TextBox TextBox
3. 4.
Name Name Name Name
You will also want to make sure that the Text properties in the TextBox controls are blank. In the class module for the form, add the following two Private declarations just below the line of code that reads Windows Form Designer generated code.
5. 6. Private modaCust As OleDb.OleDbDataAdapter
Page 106
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
7. Private mdtCust As DataTable = New DataTable() These lines of code declare a data adapter and a data table that will be used throughout the form. Note
Adding the m on the front tells you that it is a moduleor member-level variable. Also, remember that although you are declaring this at the form level, the connection that is used for the data adapter is not going to be left open the whole time the form is. When the data table is filled, the connection is opened. Then the data is accessed locally using XML under the covers. It is disconnected from the server.
8. Add the code shown in Listing 3.4 to the Load event of the form. Almost identical to the code in the last How-To to load a ListBox control, this code sets modaCust to a SQL String and the connection string to be used. mdtCust is then filled using the Fill method of
modaCust. Next, the first element in the DataColumn array called dc is set to the CustomerID column. mdtCustPrimaryKey is then set to the DataColumn array. Last, the DataSource, DisplayMember, and ValueMember properties are set.
Listing 3.4 frmHowTo3_3.vb: Loading a ComboBox by Using the DataTable Object
Private Sub frmHowTo3_3_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim strSQL As String Dim dc(1) As DataColumn '-- Set up the exception catch Try '-- Create the data adapter and fill the data table modaCust = New _ OleDb.OleDbDataAdapter("Select * From Customers", _ (BuildCnnStr("(local)", "Northwind"))) modaCust.Fill(mdtCust) '-- Set up the primary key for the data table dc(0) = mdtCust.Columns("CustomerID") mdtCust.PrimaryKey = dc '-- Bind the data to the combo box cboCustomers.DataSource = mdtCust cboCustomers.DisplayMember = "CompanyName" cboCustomers.ValueMember = "CustomerID"
Page 107
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Catch oexpData As OleDb.OleDbException MsgBox(oexpData.Message) End Try End Sub The PrimaryKey property that was set will be used in the code for the next step by the Find method of mdtCust's Rows collection. 9. This last bit of code needs to be added to the SelectedIndexChanged event of the
cboCustomers ComboBox control. As with the last step, when a data column was set up for the PrimaryKey property, in this step an array is specified to pass the SelectedItem value to find the Find method. The text boxes' Text properties are then set to the column values by using the ToString method.
Listing 3.5 frmHowTo3_3.vb: Locating a Record in the Data Table, and Then Assigning Values to Text Boxes
Private Sub cboCustomers_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles cboCustomers.SelectedIndexChanged Dim drCurr As DataRow Dim aFindValue(0) As Object '-- Load the item to look up, and use the find method aFindValue(0) = cboCustomers.SelectedItem(0) drCurr = mdtCust.Rows.Find(aFindValue) '-- Load up the fields on the form txtCustomerID.Text = drCurr("CustomerID").ToString txtCompanyName.Text = drCurr("CompanyName").ToString txtAddress.Text = drCurr("Address").ToString txtCity.Text = drCurr("City").ToString End Sub
How It Works
When a user picks a customer from the cboCustomer ComboBox control, the code then locates the desired value within the mdtCust data Table using the Find method off the rows collection. Text boxes are then loaded from the row that is retrieved.
Comments
Locating records within a data table and data row is pretty easy when you're using the methods that are supplied. ADO.NET provides the control you need, not only at the overall hierarchical level, but also at the row and column levels.
[ Team LiB ]
Page 108
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 3.4 Filter and Sort Records Using the DataView Object
After your data is loaded into the data table, you will probably want to be able to view your data using different filters and sort orders. To do this, you can use the DataView object. This How-To goes into detail and shows you how to take advantage of the DataView control to manipulate your data. Although you can put data into the DataGrid control and let the users sort data using the columns, you want to display a ComboBox control and let users pick a field from the drop-drown list. How can you filter and sort records using the DataView object to present your data in different ways?
Technique
This How-To displays a set of command buttons that display a letter and an extra command button that displays all records. A data adapter, data table, and data view are declared at the form level. The data adapter is created and the DataTable is filled when the form is loaded with all customers. Using a DataColumn object, a combo box is filled by getting the names of each column that is in the data table. You can see this form in action in Figure 3.5. Figure 3.5. Selecting a letter here limits the data displayed in the DataGrid control.
Using the command buttons, a routine is called that creates a DataView object, sets the
RowFilter property, and then assigns the data view to the DataSource property of a DataGrid
control.
Page 109
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Tip Although the RowFilter allows you to filter data based on a criteria such as CompanyName Like 'A%', you can set another property to display data based on the state of the row in which data occurs. The property is called RowStateFilter. You can set the RowStateFilter to one of the following
DataViewRowState values in Table 3.5.
Table 3.5. Label, TextBox, and ComboBox Control Property Settings Setting Description New rows Current rows including unchanged, new, and modified rows Deleted rows A current version, which is a modified version of original data (see ModifiedOriginal)
Added CurrentRows Deleted ModifiedCurrent
ModifiedOriginal The original version (although it has since been modified and is available as ModifiedCurrent) None OriginalRows Unchanged
None Original rows including unchanged and deleted rows Unchanged row
The Sort property of the DataView object is used when a column name is chosen from the
ComboBox. The current setting of the Sort property is compared to the column name that is
chosen. If the Name matches, then the expression DESC is added to the value that is assigned to the Sort property.
Steps
Open and run the VB.NET Chapter 3 solution. From the main form, click on the command button with the caption How-To 3.4. When the form loads, click on different letters that are displayed. You will see the data grid display different customers based on their first letter. If you choose a column name from the Column to Sort On ComboBox control, the data grid will then be sorted based on the column chosen. 1. 2. 3. Create a new Windows Form. Add a GroupBox control with the text property set to Click on a Letter. Now you will be creating buttons that you will place within the GroupBox control you just created. The buttons will have their property set as listed in Table 3.6.
Page 110
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 3.6. Buttons Property Settings Object Property Setting
Button
Name Caption
btnA A btnB B btnC C
Button
Name Caption
Button
Name Caption
... Button Name Caption Button Name Caption
4.
btnZ Z btnAll All
Add the DataGrid, the Label, and the ComboBox controls shown in Listing 3.6.
Table 3.7. DataGrid, Label, and ComboBox Controls Property Settings Object Property Setting
DataGrid Label Label ComboBox
5.
Name Name Caption Name
dgCustomers Label1 Column to Sort On: cboSortColumns
In the class module for the form, add the following three Private declarations just below the line of code that reads Windows Form Designer generated code. These three objects will be used throughout the form.
6. 7. 8. 9. Private modaCust As OleDb.OleDbDataAdapter Private mdtCust As DataTable = New DataTable() Private mdvCust As DataView = New DataView()
10. Add the following code to the Load event of the form as shown in Listing 3.6. This code starts out by setting up the modaCust data adapter to grab all the customers to fill the data
Page 111
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
table called mdtCust. Note that at this point, the data grid has not been filled. The next task is to load cboSortColumns with the column headings by iterating through each of the data columns in mdtCust and adding them to the Items collection in
cboSortColumns. Last, the SetDataViewFilter routine is called. This routine is discussed
in step 8. Listing 3.6 frmHowTo3_4.vb: Loading the Data Table to Be Used in the Form, and Adding Column Names to a ComboBox Control
Private Sub frmHowTo3_4_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim strSQL As String Dim dcCurr As DataColumn '-- Set up the exception catch Try '-- Create the data adapter and fill the data table modaCust = New _ OleDb.OleDbDataAdapter("Select * From Customers", _ (BuildCnnStr("(local)", "Northwind"))) modaCust.Fill(mdtCust) '-- Load the column names into the sort ComboBox control For Each dcCurr In mdtCust.Columns Me.cboSortColumns.Items.Add(dcCurr.ColumnName) Next SetDataViewFilter("B") Catch oexpData As OleDb.OleDbException MsgBox(oexpData.Message) End Try End Sub 11. For each of the command buttons that has a single letter, add the first subroutine displayed here in Listing 3.7 to each of its Click events. For the btnAll Button control, add the second subroutine to the Click event. Each Button control will pass the letter that it represents to the subroutine called SetDataViewFilter, discussed in the next step. The btnAll code simply passes the empty string. Listing 3.7 frmHowTo3_4.vb: Click Events for Each of the Button Controls
Private Sub btnA_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnA.Click SetDataViewFilter("A") End Sub Private Sub btnAll_Click(ByVal sender As System.Object, _
Page 112
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal e As System.EventArgs) Handles btnAll.Click SetDataViewFilter("") End Sub 12. Add the subroutine that is found in Listing 3.8 to the class module of the form. This routine takes the letter value that is passed in strFilterLetter as a parameter. The first task to perform is assigning the DefaultView of the mdtCust DataTable object to the mdvCust data view. Next, the RowFilter property of mdvCust is set to compare the CompanyName column with the Like expression using the strFilterLetter and the % (wildcard). Note that if "" is passed to strFilterLetter, all the records will be listed. Finally, mdvCust is set as the DataSource for dgCustomers, which is the DataGrid control. Listing 3.8 frmHowTo3_4.vb: Setting the RowFilter Property for a DataView Object
Sub SetDataViewFilter(ByVal strFilterLetter As String) mdvCust = mdtCust.DefaultView mdvCust.RowFilter = "CompanyName Like '" & strFilterLetter & "%'" dgCustomers.DataSource = mdvCust End Sub 13. Add the piece of code that is shown in Listing 3.9 to the SelectdIndexChanged event of the cboSortColumns ComboBox control. This routine compares the current setting of
mdvCust's Sort property to the current column name chosen in cboSortColumns. If the two are the same, then the column name is assigned to the Sort property with the DESC keyword added on. If not, then the name of the column is assigned to the Sort property.
Listing 3.9 frmHowTo3_4.vb: Specifying a Column on Which to Sort
Private Sub cboSortColumns_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cboSortColumns.SelectedIndexChanged '-- Check to see if the column is currently the sorted field. ' ' If it is, sort on the column in descending order. Otherwise, set the sort to the name of column.
If mdvCust.Sort = Me.cboSortColumns.Text Then mdvCust.Sort = Me.cboSortColumns.Text & " DESC" Else mdvCust.Sort = Me.cboSortColumns.Text End If End Sub
How It Works
When the user clicks on a letter, the data view is created, and the data grid reflects the new data. When a field is selected from the ComboBox control, the Sort property of the data view is set and the data grid automatically reflects the new sort order, also showing an arrow in the column heading. If the user chooses the field again, the column will sort in descending order.
Page 113
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Comments
Using the DataView object, you can keep track of multiple views of your data and display them for the users' use. You can also access all of the default views of the data tables in your data set using the DefaultViewManager. Note Some people might think that the sorting combo box that was added to this example is unnecessary. It was added for two reasons. First, it shows how to use the Sort property of a DataView object. Second, it's convenient for the user. The user might not want to have to scroll over to a column that is not displayed in the data grid. By using the combo box, he can sort on fields that are not currently displayed.
[ Team LiB ]
Page 114
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 4. Manipulating Data With ADO.NET
In this chapter you will
Edit data and update changes made to an ADO.NET DataSet object Add and delete rows in a dataset with ADO.NET Execute parameterized stored procedures in ADO.NET Create and execute on-the-fly batch updates by using ADO.NET
In Chapter 3, "Viewing Data with ADO.NET," you saw how to use ADO.NET to display data in various forms. However, there is so much more to ADO.NET, such as manipulating your data by modifying current data, as well as inserting and deleting data. ADO.NET gives you the tools you need to accomplish these tasks with some of the objects you were introduced to in Chapter 3 . A few more steps are required to manipulate data using ADO.NET then there were in ADO. The main reason for this is that ADO.NET is disconnected; therefore, after you have saved your changes to the ADO.NET objects, such as a dataset, you need to commit those changes back to the server. You will see how to do this in this chapter. The good news is that after you learn how to have the objects update and commit the data back to the server for one task, such as editing of data, you will use the same basic commands for the other tasks as well. Let's get started.
[ Team LiB ]
Page 115
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 4.1 Edit Data and Update Changes That Are Made to an ADO.NET DataSet Object
Listing and viewing data is easy. What you really need to do is to be able to edit and update data. You know you can use the DataSet object and some of its objects and methods to perform this task. How do you edit and update data using the DataSet object?
Technique
In this How-To, you will use the DataAdapter, DataSet, DataTable, and DataRow objects. You have experienced some of the properties and methods of each of these objects before. In this chapter, you are going to be using the following properties and methods that are shown in Table 4.1. Table 4.1. DataAdapter, DataSet, DataTable, and DataRow Properties and Methods Object /Method Property Description Fills DataSet and DataTable objects.
DataAdapter
Fill
CommandBuilder GetUpdateCommand Creates an Update command and places it into the data adapter's UpdateCommand property. DataAdapter DataAdapter UpdateCommand Close
Holds the SQL statement for the update. Closes the connection off the UpdateCommand. The syntax is dataadapter.UpdateCommand.Connect.Close().
DataAdapter DataSet DataSet
Update Tables Rows
Performs the update command against the dataset. Represents a collection of tables found within a dataset. Contains a collection of rows within a specified table in a dataset. Sends the changes back to the server. Retrieves the data from the column that is specified in the DataRow and returns it as a string value. Begins the editing of a DataRow, allowing you to replace values in the columns.
DataSet DataRow
AcceptChanges ToString
DataRow
BeginEdit
DataRow
EndEdit
Completes the editing of a DataRow.
You will see these objects with their properties and methods used in the following steps.
Steps
Open and run the VB.NET Chapter 4 solution. From the main form, click on the command button with the caption How-To 4.1. When the form loads, click on the Load List button to display the customers that begin with the letter A. Click the Edit button. You will notice that the fields have now taken on a sunken look. Place the cursor into the City field and change the value to Dunkirk. Now
Page 116
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
click Save. If you move off the record and move back on, you will notice that the value has been saved. This form looks similar to the form created in Chapter 1. The difference is that this time you will not be using controls that are bound at design time. You can see the form in Figure 4.1. 1. 2. Create a new Windows Form. Add the following controls, setting the properties as listed in Table 4.2.
Table 4.2. Controls Property Settings Object Property Setting
Label
Name Caption
Label1 Customer txtCustLimit A btnLoadList Load List lstCustomers Customer ID Company Name Contact Contact Title Address City Region Country Phone Fax txtCustomerID txtCompanyName txtContact
TextBox
Name Text
Button
Name Caption
ListBox Label Label Label Label Label Label Label Label Label Label TextBox TextBox TextBox
Name Caption Caption Caption Caption Caption Caption Caption Caption Caption Caption Name Name Name
Page 117
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox Button
Name Name Name Name Name Name Name Name Name Caption
txtContactTitle txtAddress txtCity txtRegion txtPostalCode txtCountry txtPhone txtFax btnEdit &Edit btnSave &Save btnCancel
&Cancel
Button
Name Caption
Button
Name Caption
3.
Note
Notice that the Text property of the text boxes is not being set at design time. In Chapter 1, "Developing Windows Forms Using Bound Controls," they were set to columns of a dataset that was included on the form. In this How-To, they will be set at run-time.
4. In the class module for the form, add the following three Private declarations just below the line of code that reads Windows Form Designer generated code. These three objects will be used throughout the form. 5. 6. 7. 8. 9. 10. 11. Private Sub btnLoadList_Click(ByVal sender As System.Object, _ 12. 13. 14. '-- Move the loading of the list to a subroutine for ByVal e As System.EventArgs) Handles btnLoadList.Click Dim mdsCustIndiv As New DataSet() Dim modaCustIndiv As OleDb.OleDbDataAdapter Dim mdrCustIndiv As DataRow Enter the following code as the Click event for btnLoadList:
Page 118
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
15. 16. 17. 18. End Sub ' additional(calls)
LoadList()
19. Create the LoadList routine by entering the following code into the form you created for this How-To. This code creates and fills a data table using a data adapter. The string that the data adapter uses creates a Select statement by using the txtCustLimit text box. The
DataSource, DisplayMember, and ValueMember properties of the list box are then bound. Last, the LoadIndividual routine is called, which is described in the next step.
20. 21. Private Sub LoadList() 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. table 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. End Sub LoadIndividual() Catch oexpData As OleDb.OleDbException MsgBox(oexpData.Message) End Try '-- Bind the data to the list box lstCustomers.DataSource = dtCustList lstCustomers.DisplayMember = "CompanyName" lstCustomers.ValueMember = "CustomerID" odaCustList = New OleDb.OleDbDataAdapter(strSQL, _ BuildCnnStr("(local)", "Northwind")) odaCustList.Fill(dtCustList) '-- Create an instance of the data adapter; then fill the data '-- Set up the exception catch Try '-- Create the SQL String strSQL = "Select CustomerID, CompanyName " & _ From Customers Where CustomerID Like '" & _ Me.txtCustLimit.Text & "%'" Dim strSQL As String Dim odaCustList As OleDb.OleDbDataAdapter Dim dtCustList As DataTable = New DataTable()
55. Create the LoadIndividual routine by entering the following code in the form you created for this How-To. Taking the SelectedItem from the list box, a data adapter is created, and a dataset is filled. Next, the individual DataRow is created. Last, each of the TextBox
Page 119
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
controls is loaded with the value from the column with the corresponding name. Notice the use of the Try-Catch-End-Try to ignore controls that don't have a like column in the
DataRow.
56. 57. Private Sub LoadIndividual() 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. '-- By trapping the exception this way, errors are ignored. Try oCtl.text = mdrCustIndiv(strName).ToString Catch oexp As Exception End Try strName = Mid(oCtl.Name, 4) If TypeOf oCtl Is TextBox Then For Each oCtl In Me.Controls '-- Run through the text boxes on the form, and '-- if they match up with a field from the record, ' load them. End Try Exit Sub MessageBox.Show("Error loading individual data: " _ & oexpData.Message) Catch oexpData As OleDb.OleDbException '-- Grab the individual data row mdrCustIndiv = mdsCustIndiv.Tables("Customers").Rows(0) '-- Fill the dataset modaCustIndiv.Fill(mdsCustIndiv, "Customers") Try '-- Load the individual record into the dataset strSQL = "Select * from Customers Where CustomerID = '" & Me.lstCustomers.SelectedItem(0) & "'" modaCustIndiv = New OleDb.OleDbDataAdapter(strSQL, _ BuildCnnStr("(local)", "Northwind")) If Me.lstCustomers.SelectedIndex <> -1 Then mdsCustIndiv.Clear() Dim strSQL As String Dim strName As String Dim oCtl As Object
Page 120
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
103. 104. 105. 106. 107. 108. 109. End If End Sub Next End If
110. Enter the following code to the Click event for lstCustomers: 111. 112. Private Sub lstCustomers_Click(ByVal sender As Object, 113. 114. 115. 116. 117. 118. End Sub 119. Enter the following code to the Click event for btnEdit: 120. 121. Private Sub btnEdit_Click(ByVal sender As System.Object, 122. 123. 124. 125. 126. 127. End Sub 128. Create the ActivateEditing routine by entering the following code in the form you created for this How-To. Introduced in Chapter 1, this code goes through each of controls on the form, looking for text boxes, then setting the BorderStyle and BackColor properties based on whether the controls are to be enabled or disabled. The Enabled property of each control is then set as well. 129. 130. Private Sub ActivateEditing(ByVal bEnable As Boolean) 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. oCurr.BackColor() = System.Drawing.Color.White oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.Fixed3D '-- If so, toggle the properties If bEnable Then '-- Check to see if the control is a text box If TypeOf oCurr Is TextBox And oCurr.Name <> "txtCustLimit" Then '-- Loop through each of the controls on the form For Each oCurr In Me.Controls() Dim oCurr As Object '-- Enable the editing of the form ActivateEditing(True) ByVal e As System.EventArgs) Handles btnEdit.Click '-- Fill the current list item's individual dataset LoadIndividual() ByVal e As System.EventArgs) Handles lstCustomers.Click
Page 121
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. End Sub 165. Enter the following code to the Click event btnSave: 166. 167. Private Sub btnSave_Click(ByVal sender As System.Object, _ 168. 169. 170. 171. 172. 173. 174. 175. 176. End Sub '-- Disable the text boxes ActivateEditing(False) '-- Save the information SaveRecord() ByVal e As System.EventArgs) Handles btnSave.Click End If Next oCurr.Enabled = bEnable End If oCurr.BackColor() = Me.BackColor oCurr.BorderStyle() = _ System.Windows.Forms.BorderStyle.FixedSingle Else
177. Create the SaveRecord routine by entering the following code in the form that you created for this How-To. Using a DataRow object, the BeginEdit method is called, and then each of the controls is stored back into the columns of the same names, if they exist. The EndEdit method is then called to complete the editing of the DataRow. A CommandBuilder object is created to create the Update command for the DataAdapter object. The DataAdapter Update method is called to update the dataset with the data changed and then the AcceptChanges of the DataSet object. This accepts all the changes for all the objects and posts the data back to the server. Finally, the connection is closed for the UpdateCommand of the DataAdapter object. 178. 179. Private Sub SaveRecord() 180. 181. 182. 183. 184. 185. 186. 187. 188. '-- Run through the text boxes on the form, and '-- if they match up with a field from the record, '-- Start the editing in the datarow. mdrCustIndiv.BeginEdit() Dim oCtl As Object Dim strName As String
Page 122
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. End Sub End Try Catch excData As Exception '-- Perform the update SQL command; then close the connection modaCustIndiv.Update(mdsCustIndiv, "Customers") mdsCustIndiv.Tables("Customers").AcceptChanges() modaCustIndiv.UpdateCommand.Connection.Close() '-- Have the command builder create an update SQL command modaCustIndiv.UpdateCommand = ocbCustIndiv.GetUpdateCommand '-- Create an instance of the command builder Dim ocbCustIndiv As OleDb.OleDbCommandBuilder ocbCustIndiv = New OleDb.OleDbCommandBuilder(modaCustIndiv) Try '-- Finish the editing of the data row mdrCustIndiv.EndEdit() Next End If '-- By trapping the exception this way, errors are ignored. Try mdrCustIndiv(strName) = oCtl.text Catch oexp As Exception End Try strName = Mid(oCtl.Name, 4) If TypeOf oCtl Is TextBox Then '-- place the value back in the record. For Each oCtl In Me.Controls
229. Enter the following code to the Click event btnCancel: 230. 231. Private Sub btnCancel_Click(ByVal sender As System.Object, _ 232. 233. 234. 235. 236. 237. 238. End Sub '-- Use the BindingContext class to cancel the current editing. LoadIndividual() ActivateEditing(False) ByVal e As System.EventArgs) Handles btnCancel.Click
Page 123
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 4.1. Although this looks like the form created in Chapter 1, you have more control over this version with unbound controls.
How It Works
When the user clicks on the btnLoadList Button, the lstCustomers list box is loaded via the
odaCustList data adapter and dtCustList data table. The first customer's information is then loaded in the text boxes on the right side of the form. When the btnEdit button is clicked, the look
of the text boxes is changed to sunken, and they are enabled for editing of the text. After changing the data, when the user clicks on the btnSave button, the data is then stored back into the server, and the text boxes are changed to disabled. If the btnCancel is clicked, the text boxes are changed to disabled.
Comments
Although it takes a bit more code to handle the editing and updating of data with unbound controls versus bound controls, you might like it better because you can control the code. With bound controls, the code is written for you. The code that is displayed here can be modified to be more generic so that you don't have to write individual routines for each form.
[ Team LiB ]
Page 124
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 4.2 Add and Delete Rows in a Dataset with ADO.NET
Again using the OleDbDataAdapter and OleDbCommandBuilder objects, this How-To shows you how to use unbound controls with the dataset to add and delete rows from SQL Server. As with editing and updating data, you need to be able to add and delete rows using the dataset. How do you perform this task?
Technique
The main difference between this technique and the previous one will be which action command you will use with the DataAdapter object. You will also be presented with the Add method on the
Rows collection. Steps
Open and run the VB.NET Chapter 4 solution. From the main form, click on the command button with the caption How-To 4.2. When the form loads, click on the Load List button to display the customers that begin with the letter A. Click the Add button. You will notice that the fields have now taken on a sunken look and that they are cleared. Fill in the Customer ID and Company Name text boxes with AAA1 and Another Example. Now click Save. If you move off the record and move back on, you will notice that the value has been saved. Now select the new record you added, and click the Delete button. The record disappears, and the list box is updated to reflect the deletion. 1. 2. Make a copy of the form you created in the last How-To. Add two buttons for adding and deleting records, setting the properties as listed here in Table 4.3.
Table 4.3. Add and Delete Buttons Property Settings Object Property Setting
Button
Name Caption
btnAdd &Add btnDelete &Delete
Button
Name Text
3.
Add the following line of code where you placed the other module-level variable declarations. This variable will be set to True in the btnAdd click event, and it can be used when saving the record.
4. 5. 6. Dim mblnAdd As Boolean Enter the following code to the Click event btnAdd. The first task is to set the mblnAdd variable to True. Then the routine clears the current text in the text boxes. It also enables the text boxes by calling ActiveEditing. 7.
Page 125
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. End Sub ActivateEditing(True) Next End If '-- By trapping the exception this way, errors are ignored. Try oCtl.text = "" Catch oexp As Exception End Try strName = Mid(oCtl.Name, 4) If TypeOf oCtl Is TextBox And oCtl.name <> "txtCustLimit" Then '-- Clear the fields For Each oCtl In Me.Controls mblnAdd = True Dim oCtl As Object Dim strName Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
36. Replace the SaveRecord routine with the following code in the form that you created for this How-To. The first change is to add the lines of code that test mblnAdd; if they're True, call the NewRow method off the dataset's Tables collection, specifying the Customers table. The DataRow returned is assigned to mdrCustIndiv. You can then enter the other changes wherever the blnAdd variable is queried. 37. 38. Private Sub SaveRecord() 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. '-- Run through the text boxes on the form, and '-- if they match up with a field from the record, '-- place the value back in the record. For Each oCtl In Me.Controls '-- Start the editing in the datarow. mdrCustIndiv.BeginEdit() If mblnAdd Then mdrCustIndiv = mdsCustIndiv.Tables("Customers").NewRow End If Dim oCtl As Object Dim strName As String
Page 126
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. Catch excData As Exception MessageBox.Show("Error Occurred: " & excData.Message) End Try '-- Close the connection If mblnAdd Then modaCustIndiv.InsertCommand.Connection.Close() LoadList() Else modaCustIndiv.UpdateCommand.Connection.Close() End If '-- Perform the specified SQL command; then close the connection modaCustIndiv.Update(mdsCustIndiv, "Customers") mdsCustIndiv.Tables("Customers").AcceptChanges() If mblnAdd Then '-- Have the command builder create an Insert SQL command modaCustIndiv.InsertCommand = ocbCustIndiv.GetInsertCommand Else '-- Have the command builder create an update SQL command modaCustIndiv.UpdateCommand = ocbCustIndiv.GetUpdateCommand End If '-- Create an instance of the command builder Dim ocbCustIndiv As OleDb.OleDbCommandBuilder ocbCustIndiv = New OleDb.OleDbCommandBuilder(modaCustIndiv) If mblnAdd Then mdsCustIndiv.Tables("Customers").Rows.Add(mdrCustIndiv) End If Try '-- Finish the editing of the datarow mdrCustIndiv.EndEdit() Next End If '-- By trapping the exception this way, errors are ignored. Try mdrCustIndiv(strName) = oCtl.text Catch oexp As Exception End Try strName = Mid(oCtl.Name, 4) If TypeOf oCtl Is TextBox Then
Page 127
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
105. 106. End Sub
107. Enter the following code to the Click event btnCancel. 108. 109. Private Sub btnCancel_Click(ByVal sender As System.Object, _ 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. End Sub LoadIndividual() ActivateEditing(False) If mblnAdd Then mblnAdd = False End If '-- Cancel the current editing. ByVal e As System.EventArgs) Handles btnCancel.Click
122. Enter the following code to the Click event btnDelete. Follow the comments to see what is happening. 123. 124. Private Sub btnDelete_Click(ByVal sender As System.Object, 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. LoadList() ActivateEditing(False) Catch excData As Exception MessageBox.Show("Error Occurred: " & excData.Message) End Try '-- Close the connection modaCustIndiv.DeleteCommand.Connection.Close() '-- Perform the specified SQL command; then close the connection modaCustIndiv.Update(mdsCustIndiv, "Customers") mdsCustIndiv.Tables("Customers").AcceptChanges() '-- Have the command builder create a Delete SQL command modaCustIndiv.DeleteCommand = ocbCustIndiv.GetDeleteCommand '-- Instantiate the command builder ocbCustIndiv = New OleDb.OleDbCommandBuilder(modaCustIndiv) '-- Delete the record from the datarow object mdrCustIndiv.Delete() Try Dim ocbCustIndiv As OleDb.OleDbCommandBuilder ByVal e As System.EventArgs) Handles btnDelete.Click
Page 128
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
153. 154. End Sub
How It Works
When a user clicks the Add button, the text boxes are all blanked out, and the mblnAdd flag is set as True. Then, after the user adds his information and clicks the Save button, the new record is added back to the server. If the Cancel button is clicked, the individual customer to whom the list is currently pointed is loaded into the text boxes. When the Delete key is pressed, the current record is deleted from the server. Then the customer list is refreshed, and the first customer in the list is displayed in the text boxes.
Comments
As you can see, adding and deleting a record does not take much more than editing and updating a record using ADO.NET. Using the commands in this How-To and the prior one, you can set it up to handle updating and canceling of multiple records as well.
[ Tea m LiB ]
Page 129
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 4.3 Execute Parameterized Stored Procedures in ADO.NET
To take advantage of stored procedures to their full power, you need to be able to pass parameters so that specific criteria can be used. This How-To describes how to create parameters off the OleDbCommand objects to pass parameters to SQL Server. You need to execute a parameterized stored procedure in your application. How do you do this using Visual Basic .NET and ADO.NET?
Technique
In ADO, you have a Command object to execute stored procedures, among other tasks. In ADO.NET, you also have a Command object that performs basically the same task. In fact, many of the properties and methods that you use are the same. You can see a list of those in Table 4.4. Table 4.4. Objects That Are Used for This Technique, with Properties and Methods Object Property Description/Method
Connection ConnectionString Contains the connection string that is used. Connection Open
Opens the connection that the Command object uses.
Command
cmdText
Specifies the SQL statement to use. Can be SQL statement or names of objects such as tables or stored procedures. Uses the Connection object. Specifies the type of command you want to execute. Can be one of the following command types: StoredProcedure,
Command Command
Connection CommandType
DirectTable, or Text. Command Command Parameters ExecuteReader
Parameters to pass to the stored procedure. Creates a DataReader object with the data that the command object specifies.
DataReader Read
Reads the next record in the DataReader, and also tests the end of the data returned.
DataReader GetString
Returns the current record, getting the column specified, and returns it as string. Returns the current record, getting the column specified, and returns it as 32-bit integer.
DataReader GetInt32
You will use these objects and their properties and methods for the following steps.
Steps
Open and run the VB.NET Chapter 4 solution. From the main form, click on the command button
Page 130
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
with the caption How-To 4.3. When the form loads, click on the View button to display the orders for the customer ID that is specified. By default, this is ALKI. A TextBox control is then displayed on the bottom of the form. You can see the form in Figure 4.2. 1. 2. Create a new Windows Form. Add the following controls, setting the properties as listed in Table 4.5.
Table 4.5. Controls Property Settings Object Property Setting
Label
Name Caption
Label1 Products and Quantities Ordered By: txtCustID ALFKI btnView &View txtResults
TextBox Name Text Button Name Text TextBox Name
MultiLine True
3. Enter the following code to the Click event btnView. This code takes the connection and creates the command object. The name of the stored procedure is passed, and the command type is specified, which is CommandType.StoredProcedure. Next, parameters and the DataReader are created. The last task is to iterate through the data and add it to the display text box. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. '-- Specify the parameters. ocmdCustHist.Parameters.Add("@CustomerID", Me.txtCustID.Text) Try '-- Specify the name of the stored procedure ocmdCustHist.CommandType = CommandType.StoredProcedure Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) Dim ocmdCustHist As New OleDb.OleDbCommand("CustOrderHist", ocnn) Dim odrCustHist As OleDb.OleDbDataReader Private Sub btnView_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnView.Click
Page 131
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. End Try End Sub Catch excpData As Exception MessageBox.Show("Error Occurred: " & excpData.Message) Loop '-- Iterate through the data loaded, building the results string. Do While odrCustHist.Read Me.txtResults.Text &= odrCustHist.GetString(0) & _ ", " & odrCustHist.GetInt32(1) & vbCrLf '-- Establish the DataRead object. odrCustHist = _ ocmdCustHist.ExecuteReader(CommandBehavior.SequentialAccess) '-- Open the connection object. ocnn.Open()
Figure 4.2. This form uses the Command object with a stored procedure to populate the TextBox control.
How It Works
When the user clicks on the View button with Customer ID filled in, the text box below is filled in, displaying order information for that customer.
Comments
Using the technique presented here, you can pretty well perform the majority of the tasks you need to by using Command objects and stored procedures.
[ Team LiB ]
Page 132
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 4.4 Create and Execute On-the-Fly Batch Updates by Using ADO.NET
Sometimes in database applications, you want to create and execute stored procedures that don't currently exist. When you have a situation in which you need to use highly dynamic stored procedures that might use criteria that is entirely created at runtime, you might need to create those stored procedures on-the-fly. This How-To shows you how to create and execute these stored procedures. It's great that you can execute stored procedures that are already created, but what if you need to generate one at runtime? How do you do this?
Technique
To perform this How-To, you will be utilizing the OleDBCommand object, and feeding in the
CommandText property from a text box. The text box is set to "Update Employees Set City = 'Redmond' Where City = 'Seattle'" to give you something to start with. Steps
Open and run the VB.NET Chapter 4 solution. From the main form, click on the command button with the caption How-To 4.4. When the form loads, you will see an example update statement in a text box. Click on the Execute button to execute the update statement. A TextBox control is then displayed on the bottom of the form showing the number of records that are affected. You can the form in Figure 4.3. Figure 4.3. This form uses the Command object with a SQL statement passed to execute the specified action.
Note The number of records affected might be different on your system depending on what you have been doing with the Northwind data.
1. 2.
Create a new Windows Form. Add the following controls, setting the properties as listed in Table 4.6.
Table 4.6. Controls Property Settings
Page 133
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Object
Property
Setting
Label
Name Caption
Label1 Update Statement to Execute: btnExecute txtSQL Update Employees Set City = 'Redmond' Where City = 'Seattle'
Button
Name
TextBox Name Text
MultiLine True Label Name Caption TextBox Name
3.
Label2 Records Affected: txtRecsAffected
Enter the following code to the Click event btnExecute. When the command is instantiated in this case, the string in the txtSQL text box is passed as the CommandText. The CommandType is set as CommandType.Text. The connection is then open. Finally, the command is executed with the ExecuteNonQuery method, with the ToString passing back the number of records that were affected to the Text property of the txtRecsAffected text box.
4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. End Sub Tip End Try Catch excpData As Exception MessageBox.Show("Error Occurred: " & excpData.Message) Me.txtRecsAffected.Text = ocmdPhoneUp.ExecuteNonQuery.ToString '-- Open the connection object. ocnn.Open() Try '-- Specify the name of the stored procedure ocmdPhoneUp.CommandType = CommandType.Text Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) Dim ocmdPhoneUp As New OleDb.OleDbCommand(Me.txtSQL.Text, ocnn) Private Sub btnExecute_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnExecute.Click
Page 134
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Use a Try…Catch…End Try block to trap any exceptions that might occur when working with ADO.NET. In this case, the error is trapped and a message box displays the error. Remember that exceptions that are not trapped will cause the application to fail.
How It Works
When a valid SQL statement is entered into the text box with the label Update Statement to
Execute: and the Execute button is clicked, the command entered is executed, and the number of
records that were affected is returned.
Comments
The Command object is a real workhorse when it comes to performing bulk operations, whether working with store procedures already created or when using statements that have been created on-the-fly.
[ Team LiB ]
Page 135
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 5. Working With Data In Web Forms
In this chapter you will:
Dealing with stateless Programming Use bound controls with Web forms Validate data using validation controls Populate DropDown and ListBox controls Display data using the Table control Display data using the Repeater control Display, sort, and page data in the DataGrid control Add, edit, and delete data using the DataGrid control Hyperlink from a row in the data grid to a detail page
With .NET, developing for the Web becomes easier than ever. ASP.NET is actually even fun to work with. In the past, ASP proved quite a task to develop applications in. Now, however, you can develop your Web applications in much the same way you do Windows desktop applications, with few major differences.
[ Team LiB ]
Page 136
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Dealing with Stateless Programming
One of the big differences lies in the fact that Web pages are still inherently stateless. This means that when you move from page to page, you tend to lose the data that the pages use. Although this is not a big problem when you are creating simple Web pages that perform easy tasks, when you begin creating real applications, especially dealing with databases or data that users input, this factor can be a big hassle.
State Management on the Client
In the past, the statelessness of Web pages was dealt with to an extent in a number of ways on the client side:
Cookies. Small files that a Web application creates. Cookies store data on the local machines of those who are accessing the Web application. A couple of problems exist with just using cookies. First, cookies are stored on the local machine, so the machine (or browser) must allow them. Second, the type of data that can be stored in cookies is limited.
Query strings. Information that is appended to the end of a page's URL. You will see examples of this when you're creating hyperlinks and calling new Web pages.
Hidden fields. An HTML field that is hidden to the user. These are not visible to the class module either.
Control.ViewState property. Provides a dictionary object for retaining values between multiple requests for the same page. Note that this is the method that the page uses to preserve page and control property values between round trips.
Although some of these management techniques have been used in ASP, they are still valid in .NET, and they are useful given the correct circumstances. When you're developing in ASP.NET, some additional solutions are available for state management. Those solutions are handled on the server side.
Server-Side Solution to State Management
Depending on the information that you want to retain, .NET has a number of ways to handle state management. Although you could use the methods just mentioned, a few other options are available as well:
Application state. You can save values to this object Application("ItemName") = value by using an instance of the HttpApplicationState class, but all those people who are in the application at that time will be able to see it.
Session state. This option allows you to maintain state for the individual session. This is discussed further in the next section.
Database support. SQL Server helps you to maintain state by adding values to the Temp database on the server.
Using the Session Object
The Session object is pretty straightforward to work with. When you assign the variable, you will use the following syntax:
Page 137
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Session("SessionVariableName") = Value SessionVariableName is in fact used inside the quotes. It can be whatever you want to call it. Value can be any type of variable, including a DataTable object, as you will see in the steps that
follow. Sometimes, you can stash the data table and a Boolean variable to the Session object. Following is one of the lines of code that stores the data table:
Session("MyLookupData") = mdtLookupData MyLookupData is the name of the entry that is created in the Session object. mdtLookupData is the variable name of the DataTable object, declared at the module level.
When you're reading a variable, you will turn the statement around and add a CType() function to convert the value to the desired type.
Variable = CType(Session("SessionVariableName",Type)
In the instance of a data table, such as the one used in this How-To, you would see something like this:
mdtLookupData = CType(Session("MyLookupData"), DataTable)
Note that you can use other conversion functions besides CType(). If you don't convert the value, then the Object type will be returned. Another task that is necessary to perform is testing whether the entry in the Session object has been made. You do this by testing the Session entry against the Nothing keyword, as seen here:
'Put user code to initialize the page here If Not (Session("MyLookupData") Is Nothing) Then mdtLookupData = CType(Session("MyLookupData"), DataTable) End If
This code is used in the Load event of the page. If the entry has been created in the Session object, then the data is loaded into the variable. You can also use the opposite as well. If the entry in the Session object is Nothing, then create the entry. This is just a quick and simple way of taking advantage of the Session object. There are probably hundreds of other ways to take advantage of the Session object. For more information on this, check out Session State in the .NET Framework Developer's Guide, which is part of the help provided by Visual Studio. Type in "state management in ASP.NET" for the index to locate the Session object topic. You can find all of the examples in this chapter in the Solution called Visual Basic .NET on the Web site. Chapter 5
[ Team LiB ]
Page 138
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.1 Use Bound Controls with Web Forms
I want to create a Web Form that allows my users to view data much like my Windows Forms and be able to use data bound controls on it. How do I use data bound controls on a Web Form?
Technique
The data objects that you used in Chapter 1, "Developing Windows Forms Using Bound Controls," including OleDbDataAdapter, datasets, and so on, will be used with Web Forms as they would with Windows Forms. The main difference between Windows Forms and Web Forms in this case is the extra steps needed to handle round trips to the server from the client machines. For discussion on OleDBDataAdapters and datasets, see Chapter 1 .
The IsPostBack Property
One property that you will be using when you're developing Web forms is the IsPostBack property, which is used in the Load event of the Web Form. That's right Web Forms now have an event model much like Windows Forms. You can now work with the Web Form properties and Web server control properties from the Web page's class module. The IsPostBack property is set to True if the load event is fired on a round trip from the server. Therefore, the first time a Web Form is loaded, IsPostBack is False.
Web Server Controls Versus HTML Controls
Within ASP.NET Web Forms, you now have the ability to use either your classic HTML controls, which are available for compatibility purposes, or the new Web server controls, which, because they run on the server, have the following advantages:
You can access Web server control properties and methods from the Web Forms class module, but not with HTML controls.
Because Web server controls are rendered from the server side, on the client side they come through as pure HTML, and they are compatible with more browsers and earlier versions.
Web server controls generally have more features than their HTML counterparts, and in some cases, they can be bound to data.
Note You can change some of the HTML controls to Web server controls by placing the control on the Web Form, right-clicking on the control, and choosing Run as Web Server Control from the pop-up menu. After choosing this menu option, you can see the object in your code behind your page.
Note Although you will be dealing with a ListBox Web server control, it has different properties and methods than the Windows Form ListBox control. These are discussed in the following steps.
Page 139
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
The AutoPostBack Property
Web server controls have a property called AutoPostBack. This property tells .NET to post back to the server, which is something you need to do if you want to have an event fire off, such as the SelectedIndexChanged event of the lstCustomers list box. This is also true for Button controls that are used.
The DataBind Method
When you're binding Web server controls in this case, a ListBox control to data such as DataSet or DataTable objects, you need to invoke the DataBind method of the control that is being bound. You need to do this when data changes, as you will see in the following steps.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.1: Using Data Bound Controls with Web Forms. When the Web Form loads, you will see a list box filled with customers, and the details for the first customer will be displayed in the list (see Figure 5.1). Figure 5.1. Arrange the controls on the form you created to look like this form.
To start off, you will be creating a Web Form that is similar to a Windows Form that was created in Chapter 1. You will actually be creating the form exactly the way you did in the first chapter with the Windows Form, with the exception of a few commands in the code.
Page 140
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
1. Create a Web Form. Then place the controls listed in Table 5.1 with the following properties set. You will be using Northwind for the database to connect to.
Table 5.1. Label, TextBox, ListBox, and Command Button Control Property Settings Object Property Setting
OleDbDataAdapter ID SelectCommand
odaCustomerList Select CustomerID, CompanyName From Customers dsCustomerList odaCustomerIndividual Select * From Customers Where Customer ID = ?
DataSet
ID
OleDbDataAdapter ID SelectCommand ID ID DataSource DataTextField
DataSet ListBox
dsCustomerIndividual lstCustomers dsCustomerList CompanyName
DataValueField CustomerID AutoPostBack Label Label Label Label Label Label Label Label Label Caption Caption Caption Caption Caption Caption Caption Caption Caption True Customer ID Company Name Contact Contact Title Address City Region Country Phone
Page 141
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label TextBox
Caption ID Text ID Text ID Text ID Text ID Text ID Text ID Text ID Text ID Text ID
Fax txtCustomerID dsCustomerIndividual Customers.CustomerID txtCompanyName dsCustomerIndividual Customers.CompanyName txtContactName dsCustomerIndividual Customers.Contact txtContactTitle dsCustomerIndividual Customers.ContactTitle txtAddress dsCustomerIndividual Customers.Address txtCity dsCustomerIndividual Customers.City txtRegion dsCustomerIndividual Customers.Region txtPostalCode dsCustomerIndividual Customers.PostalCode txtCountry dsCustomerIndividual Customers.Country txtPhone
TextBox
TextBox
TextBox
TextBox
TextBox
TextBox
TextBox
TextBox
TextBox
Page 142
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text ID Text ID NavigateURL
2.
dsCustomerIndividual Customers.Phone txtFax dsCustomerIndividual Customers.Fax hplReturnToMain wfrmMain.aspx
TextBox
HyperLink
Add the code in Listing 5.1 to the Load event of the page. (Double-click on the page to bring up the code.) The first command you see is the if statement, which tests to see whether the page is being loaded for the first time. If it is, then the dsCustomerList dataset is filled using the odaCustomerList OleDbDataAdapter. Next, the DataBind method is called. Last, the first item in lstCustomers is selected, and the RefreshIndividual routine is called, which is described in the next step. Listing 5.1 wfrmHowTo5_1.aspx.vb: Loading the Page
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Perform only the first time the page is loaded If Not Page.IsPostBack Then '-- Fill the customer list box dataset Me.odaCustomerList.Fill(Me.dsCustomerList) '-- Bind the list box to the dataset Me.lstCustomers.DataBind() '-- Pick the first customer in the list and ' display the individual's data Me.lstCustomers.SelectedIndex = 0 RefreshIndividual() End If End Sub 3. Add the code in Listing 5.2 to the class module of the page, creating the
RefreshIndividual routine. The routine starts off by clearing the dataset and then tests
to make sure a customer is selected. Next, the data adapter parameter is supplied with the item that is selected in lstCustomers, which will be the CustomerID. dsCustomerIndividual is filled, and the DataBind method of each of the text boxes is called. Listing 5.2 wfrmHowTo5_1.aspx.vb: Listing Detail Information About the Customers
Page 143
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub RefreshIndividual() '-- Clear individual customer dataset Me.dsCustomerIndividual.Clear() If lstCustomers.SelectedIndex <> -1 Then Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = _ lstCustomers.SelectedItem.Value '-- Fill the dataset Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual, "Customers") '-- Call the DataBind method for each of the text boxes Me.txtCustomerID.DataBind() Me.txtCompanyName.DataBind() Me.txtContactName.DataBind() Me.txtContactTitle.DataBind() Me.txtAddress.DataBind() Me.txtCity.DataBind() Me.txtRegion.DataBind() Me.txtCountry.DataBind() Me.txtPostalCode.DataBind() Me.txtPhone.DataBind() Me.txtFax.DataBind() End If End Sub 4. Add the code in Listing 5.3 to the SelectedIndexChanged event of lstCustomers. Listing 5.3 wfrmHowTo5_1.aspx.vb: Calling the RefreshIndividual Routine for Each New Customer Who Is Selected
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles lstCustomers.SelectedIndexChanged RefreshIndividual() End Sub
Comments
Using bound controls on Web Forms or unbound controls, for that matter, such as list boxes does not take much more work than it does in Windows Forms. Except for maintaining the data, binding can take more work with the round trips to the server to deal with, as you will see in How-To 5.7.
[ Team LiB ]
Page 144
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.2 Validate Data Using Validation Controls
I want to be able to validate various types of data entry without having to wait for an error to come back from the server. Can I validate my data on my Web Form? Note A note of caution: Through the writing and tech editing of this chapter, there have been some inconsistencies noted in the reaction of some of the validator controls. The tech editor and I both contend that this area might have some .NET bugs. This is also the reason for the lack of coverage in the CustomValidator.
Technique
One new feature found in ASP.NET is the inclusion of Validation Web server controls. These validation controls allow you to specify other controls of which you want to validate based on data entered into the controls. You can then do the following:
Have the Validation control display an error message. Test at a page level to see if all controls that are being validated are valid. Display a list of error messages for all the controls that are being validated.
Available Validation Web Server Controls
You will find the controls for validation in the toolbox, and can see them listed in Table 5.2, with a description of what they validate. Table 5.2. Validation Web Server Controls Control Description Validates whether the specified control has been left blank. Compares the values in two controls and validates whether they are equal. Checks to see if the value entered into a control falls within a range that is specified.
RequiredFieldValidator CompareValidator
RangeValidator
RegularExpressionValidator Compares a value entered into a control to see if it matches an
entered mask, such as 999-99-9999, which is the U.S. Social Security Number.
CustomValidator
Allows you to create custom functions on both the client and server side for validation. Used to consolidate the messages that all validation controls return on a page into a list-like format.
ValidationSummary
Page 145
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
The main properties you will set on a validation control are FieldToValidate and ErrorMessage. Note The CustomValidator control is different in that you will create functions to perform the validation. Other than these, the validation controls require no coding unless you want to validate the whole page.
Testing Page Validation in Code
Depending on what is required, you can test for validation at the page level using the Page.Validate method. When you call this method, all the Validation controls are retested, and the Page.IsValid property is set. You can use the IsValid property in a condition statement to perform tasks based on the value of the IsValid property, as shown in the last step of this How-To.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.2: Validate Data Using Validation Controls. When the Web Form loads, you will see a number of text boxes with instructions on how to see the various validation checks. Here is the Web Form in Design view (see Figure 5.2). 1. Create a Web Form. Then place the controls listed in Table 5.3 and shown in Figure 5.2 with the following properties set.
Table 5.3. Control Property Settings for Validation Controls Web Form Object Property Setting Required Field Validator Example (Leave Blank to Test)
Label
Text
TextBox
ID
txtRequiredExampl e
Compare Validator Example (Enter Two Different Values in These Text Boxes)
Label
Text
TextBox TextBox
ID ID
txtCompareFirst txtCompareSecond
Page 146
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label
Text
Range Validator Example (Enter a Number Outside the Range 1 and 10)
TextBox Label
ID Text
txtRangeExample
Regular Expression Validator Example (Enter a SSN not matching 999-99-9999)
TextBox
ID
txtRegularExprExa mple
Custom Validator Example (Enter a State Other Than WA or CA)
Label
Text
TextBox Button
ID ID Text
txtCustomExample btnTestValidators
Test Validators Page Validation Errors
Label
Text
RequiredFieldValidato ToValidate r Control ErrorMessage
txtRequiredExampl e
Here is the message for the Required Field Validator
CompareValidator
ControlToCompare txtCompareFirst ControlToValidat txtCompareSecond e ErrorMessage
Here is the message for the Compare Validator
RangeValidator
ControlToValidat txtRangeExample
Page 147
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
e MaximumValue MinimumValue ErrorMessage 10 1
Here is the message for the Range Validator
RegularExpressionVali ControlToValidat txtRegularExprExa dator e mple ValidationExpres \d{3}-\d{2}-\d{4} sion ErrorMessage
Here is the message for the Regular Expression Validator
ValidationSummary HyperLink
HeaderText ID NavigateURL
Error Summary List hplReturnToMain wfrmMain.aspx
2.
Note
For the ValidationExpression property of the
RegularExpressionValidator, you will want to click
the builder button beside the property and choose the SSN from the list of expressions.
3. Add the code in Listing 5.4 to the Click event of btnTestValidator. You can see an example here of how you might use the Validate method for the page, and act based on when the IsValid property is set. Listing 5.4 wfrmHowTo5_2.aspx.vbs Testing to See If All Controls That the Validation Controls Handle Are Valid
Private Sub btnTestValidators_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestValidators.Click '-- Forces the Validation controls to validate Page.Validate() If Page.IsValid Then '-- Code if all controls are valid
Page 148
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Else '-- Code if even one of the controls isn't valid End If End Sub Figure 5.2. These controls aren't seen on your Web forms unless a validation error occurs.
Comments
You normally wouldn't have the ValidationSummary control on the same page if you were listing the individual error messages using the Validation controls. It is nice to be able to have all the errors show up in a list sometimes. Tip You can affect the way the list looks in the ValidationSummary control by setting the DisplayMode property. You have the choice of using a list, a bulleted list, or a paragraph. You can also display a message box instead of a list by setting the ShowMessageBox property to True and the ShowSummary property to
False.
Note You can display one message in the individual validation controls and another in the ValidationSummary control. The ErrorMessage property is reflected in the ValidationSummary list, whereas the Text property of
Page 149
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
the individual validation controls displays something different if it's set.
[ Team LiB ]
Page 150
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.3 Populate DropDown and ListBox Controls
I saw in this chapter's first How-To how to bind a ListBox control to a dataset that was created in the design. How do I populate DropDown and ListBox controls on a Web Form using code at runtime?
Technique
ListBoxes and DropDowns, which are equivalent to ComboBoxes on Windows Forms, have different properties that are used for data binding than their Windows counterparts. Besides these properties, displayed in Table 5.4, you also need to use the Databind method and session object to track the data table that is created for products. Table 5.4. Properties Used to Bind Columns to Controls Property Description Column in data source to use for displaying in the DropDown or ListBox control.
DataTextField
DataValueField Column in data source that is the lookup value.
Note You can use a property called DataFormatString to format the
DataTextField data for display in the ListBox or DropDown controls.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.3: Populate DropDown and ListBox controls. When the Web Form loads, you will see a Categories dropdown with the Beverages category selected and the products for that category in the list box with the label Products. If you click on a product, the three text boxes are loaded on the right of the page (see Figure 5.3). 1. Create a Web Form. Then place the controls listed in Table 5.5 and seen in Figure 5.3 with the following properties set.
Table 5.5. Control Property Settings for Validation Controls Web Form Object Property Setting
Label DropDown
Text ID AutoPostBack
Categories: ddCategories True
Page 151
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label ListBox
Text ID AutoPostBack
Products: lstProducts True Product ID Product Name Unit Price txtProductID Transparent txtProductName Transparent txtUnitPrice Transparent hplReturnToMain wfrmMain.aspx
Label Label Label TextBox
Text Text Text ID BackColor
TextBox
ID BackColor
TextBox
ID BackColor
HyperLink
ID NavigateURL
2.
As with some of the other chapters' projects, a support routine needs to be built to create the Connection string. Called BuildCnnStr, the function can been seen in Listing 5.5. This function takes a server and database name passed to it and creates a connection string. Listing 5.5 modGeneralRoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method would be to pass back a string. The reason for this is that for some objects, you are asked for a Connection object, but for others, you are asked for just a string. 3. In the class module for the Web Form, add the following Private declaration just below the line of code that reads Web Form Designer Generated Code.
Page 152
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4. 5. Private mdtProducts As New DataTable() This line of code declares a DataTable object that you will use throughout the Web Form. However, in addition to using this variable, you will use the Session object to retain the data between round trips to the server. 6. Add the code in Listing 5.6 to the Load event of the page. This code creates a DataAdapter object and then fills the dtCategories DataTable object. The ddCategories DropDown control is bound to dtCategories. The LoadProducts routine is called to load the products into the lstProducts ListBox control, which is described in the next step. Finally, the Session object is checked to see if the item MyProductsTable has been saved to it, and if so, it is loaded back into the mdtProducts variable. Listing 5.6 wfrmHowTo5_3.aspx.vb: Initializing the Page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not Me.IsPostBack Then Dim dtCategories As New DataTable() Dim odaCategories As _ New OleDb.OleDbDataAdapter( _ "Select CategoryID, CategoryName From Categories", BuildCnnStr("(local)", "Northwind")) '-- Fill the data table odaCategories.Fill(dtCategories) '-- Assign the properties and bind the dropdown. ddCategories.DataValueField = "CategoryID" ddCategories.DataTextField = "CategoryName" ddCategories.DataSource = dtCategories ddCategories.DataBind() LoadProducts() End If '-- Load the products data table back from the session variable If Not (Session("MyProductsTable") Is Nothing) Then mdtProducts = CType(Session("MyProductsTable"), DataTable) End If End Sub 7. In the class module for the page, create the LoadProducts routine that is displayed in Listing 5.7. This code looks similar to other routines that generate a DataTable object and then assign the properties to bind mdtProducts to the lstProducts ListBox control. mdtProducts is then added to the Session object for round trips to the server.
Page 153
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 5.7 wfrmHowTo5_3.aspx.vb: Creating the LoadProducts Routine
Private Sub LoadProducts() Dim odaProducts As New OleDb.OleDbDataAdapter( _ "Select * From Products Where CategoryID = " & ddCategories.SelectedItem.Value, _ BuildCnnStr("(local)", "Northwind")) mdtProducts.Clear() odaProducts.Fill(mdtProducts) '-- Assign the properties and bind the list box. lstProducts.DataValueField = "ProductID" lstProducts.DataTextField = "ProductName" lstProducts.DataSource = mdtProducts lstProducts.DataBind() '-- Save the data table out to a session variable for round trips Session.Item("MyProductsTable") = mdtProducts End Sub 8. Add the code in Listing 5.8 to the SelectedIndexChanged event off the ddCategories DropDown control. Listing 5.8 wfrmHowTo5_3.aspx.vb: Calling the LoadProducts Routine When a New Category Is Chosen
Private Sub ddCategories_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles ddCategories.SelectedIndexChanged LoadProducts() End Sub 9. Add the code in Listing 5.7 to the SelectedIndexChanged event off of lstProducts. This code takes the SelectedIndex property of the lstProducts ListBox control and helps retrieve the row in the DataTable object. The individual columns are then loaded into the corresponding text boxes on the page. Listing 5.9 wfrmHowTo5_3.aspx.vb: Locating the Row in the mdtProducts DataTable Object
Private Sub lstProducts_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles lstProducts.SelectedIndexChanged With mdtProducts.Rows(lstProducts.SelectedIndex) txtProductID.Text = .Item("ProductID")
Page 154
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
txtProductName.Text = .Item("ProductName") txtUnitPrice.Text = .Item("UnitPrice") End With End Sub Figure 5.3. DropDown and ListBox controls used to display data on this Web Form.
Comments
One of the main items to note, besides the use of the Session variables, is the use of the ddCategorie.SelectedItem.Value and lstProducts.SelectedIndex. These are two ways to use items that are selected in the DropDown and ListBox objects, respectively. After you have used the Session object to keep variables during round trips to the server, it becomes more intuitive as you use it.
[ Team LiB ]
Page 155
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.4 Display Data Using the Table Control
.NET has a number of controls available for displaying data. How do I know which control to use to display data, and how do I use the Table control to display data?
Technique
When you're first deciding to list data on your Web forms, you have a few Web server controls to choose from:
Table. This Web server control allows you to create a read-only table type display of data. This control is not data bound, and it uses the TableColumn and TableRow objects for creation.
Repeater. This control is used to display read-only lists. You can use hyperlinks and program the ItemCommand event so that you can perform actions when items are selected. You must use templates to format the display. Templates are discussed in How-To 5.5, as is the Repeater control. This is a great control for quick lists.
DataList. Using this control, you will use templates not only to display, but also to select and edit data in the list.
DataGrid. By far, this is the most powerful of the controls. In addition, it gives you the most control over manipulating data. You display, sort, edit, and use various types of controls in each column. The last three How-Tos in this chapter thoroughly cover the DataGrid control.
Anatomy of the Table Web Server Control
You can create the Table Web server control at design time, or as shown in this How-To, at runtime. The control is created by adding the TableRows and TableCells to the Table control. The TableRows and TableCells are controls in their own right. You can see the objects, properties, and methods that you will use to create the Table Web server control in Table 5.6. Table 5.6. Using a Standard Method of Creating Objects Within Objects to Construct a Table Web Server Control Object Property Description
TableCell Controls Controls are added to an individual TableCell object using the Add method of the Controls collection. In this example, a LiteralControl object is
used to display information.
TableRow Cells
The Add method of the TableRow.Cells collection adds a new cell to the
TableRow. Table Rows
The Add method of the Table.Rows adds the TableRow object to the collection of rows for the Table control. You will see these objects and methods used in step 4. Note One of the issues with using the Table control is that it does not persist in trips to the server and back. Therefore, you need to reconstruct the
Page 156
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
control in the page Load event, checking with the IsPostBack property. If you are tracking a lot of changes with the Table control, this is another good reason to use one of the other controls listed at the beginning of this technique.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.4: Display Data Using the Table Control. When the Web Form loads, you will see a DropDown control displaying the list of categories. Below the DropDown control, you will see a Table control with the products for the selected category (see Figure 5.4). 1. Create a Web Form. Then place the controls listed in Table 5.7 and seen in Figure 5.4 with the following properties set.
Table 5.7. Property Settings for Label, DropDown, and Table Controls Object Property Setting
Label DropDown
Text ID AutoPostBack
Categories: ddCategories True tblProducts Both hplReturnToMain wfrmMain.aspx
Table
ID GridLines
HyperLink
ID NavigateURL
2.
Add the code in Listing 5.10 to the Load event of the page. If the page is first being loaded, then the dtCategories is filled and bound to the ddCategories dropdown. Last, the LoadProducts routine is called, which is described in the next step. Listing 5.10 wfrmHowTo5_4.aspx.vb: Loading the Categories DropDown and Product Table Controls
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not Me.IsPostBack Then Dim dtCategories As New DataTable()
Page 157
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim odaCategories As _ New OleDb.OleDbDataAdapter( _ "Select CategoryID, CategoryName From Categories", BuildCnnStr("(local)", "Northwind")) '-- Fill the data table, and bind it to the dropdown. odaCategories.Fill(dtCategories) ddCategories.DataValueField = "CategoryID" ddCategories.DataTextField = "CategoryName" ddCategories.DataSource = dtCategories ddCategories.DataBind() LoadProducts() End If End Sub 3. In the page's class module, create the LoadProducts routine shown in Listing 5.11. After creating a DataTable object called dtProducts and filling it with a DataAdapter object, the number of columns in the dtProducts is stored in intNumCols. A TableRow object is then created, which will be used for the heading row of the table. It displays the column heads. Then, for each of the columns, a TableCell object called tcHead is created. A LiteralControl is added to it, which is derived from the ColumnName property of the data table for each column. Each TableCell object is then added to the
TableRow object. After all the columns have been added, the TableRow object called
trHead is added to the tblProducts Table control. After the table headings have been created, the same commands are created for each row in the DataTable object. Listing 5.11 wfrmHowTo5_4.aspx.vb: Loading the Categories DropDown and Product Table Controls
Private Sub LoadProducts() Dim dtProducts As New DataTable() Dim drCurr As DataRow Dim intCurrRow As Integer Dim intCurrCell As Integer Dim intNumCols As Integer Dim odaProducts As New OleDb.OleDbDataAdapter( _ "Select * From Products Where CategoryID = " & ddCategories.SelectedItem.Value, _ BuildCnnStr("(local)", "Northwind")) odaProducts.Fill(dtProducts) intNumCols = dtProducts.Columns.Count
Page 158
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Create the headings for the displayed table Dim trHead As New TableRow() For intCurrCell = 0 To intNumCols - 1 Dim tcHead As New TableCell() tcHead.Controls.Add(New LiteralControl(dtProducts. _ Columns(intCurrCell).ColumnName)) trHead.Cells.Add(tcHead) Next tblProducts.Rows.Add(trHead) '-- Add the rows and cells For intCurrRow = 0 To dtProducts.Rows.Count - 1 drCurr = dtProducts.Rows(intCurrRow) Dim trNew As New TableRow() For intCurrCell = 0 To intNumCols - 1 Dim tcNew As New TableCell() tcNew.Controls.Add(New LiteralControl(drCurr.Item(intCurrCell))) trNew.Cells.Add(tcNew) Next intCurrCell tblProducts.Rows.Add(trNew) Next intCurrRow End Sub 4. Add the code in Listing 5.12 to the SelectedIndexChanged event of ddCategories. Listing 5.12 wfrmHowTo5_4.aspx.vb: Loading the Categories DropDown and Product Table Control
Private Sub ddCategories_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles ddCategories.SelectedIndexChanged LoadProducts() End Sub Figure 5.4. Using the Table control to display tables takes a lot of work.
Page 159
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
You can see from this example that using the Table Web server control takes a bit of work, and if you have a lot of data to display, it could take quite a while to build. Also, remember that you can't edit the data that is built into the control. If you have just a small amount of data to display, the Table Web server control could work out nicely.
[ Team LiB ]
Page 160
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.5 Display Data Using the Repeater Control
I have heard that the Repeater control is a great control for displaying a read-only list of values, including hyperlinks. How do I populate a Repeater control and take advantage of templates to display the data the way I want it to look?
Technique
The Repeater control allows you to list data in various formats, such as bulleted or numbered. It relies on the use of templates to display information in a list format. This How-To shows you how to use the Repeater control not only to display a list, but also to use a couple of different controls a Button and HyperLink to display another list using the Repeater control. The second list will be displayed using the button on the same page as the first list. The hyperlink will take you to another page to display the second list. A main tool in the creation of the Repeater control is the use of templates.
Use of Templates
Templates are used within HTML and allow you to include controls in your ASP.NET Web server controls. Within a template, you can specify various details about the area for which you are creating a template. Following is a list of the templates:
HeaderTemplate ItemTemplate FooterTemplate AlternatingItemTemplate SeparatorTemplate
You can get an idea of what each of the templates is used for by its name. Here is an example of the HeaderTemplate, used in this How-To:
List of Regions
These lines are literally used as a template for how you want the section to be laid out, as well as what data to display. For the ItemTemplate in this How-To, two controls are displayed: a button and a hyperlink, shown by this snippet of the HTML:
As the name implies, the DataBinder supplies data from the data source that is specified for the Repeater object. You will see how to bind the Repeater object in step 3.
Page 161
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Creating URLs On-the-Fly
In the NavigateURL of the hyperlink that was created, you can see the column DataItem.RegionURL being used. This is not a column that is found in the Regions table in Northwind. This column is created within the SQL statement that is supplied to a data adapter, by the following line of code:
odaRegions = New OleDb.OleDbDataAdapter("Select RegionID, _ 'wfrmHowto5_5b.aspx?RegID=' + Cast(RegionID as Char(2)) As RegionURL, RegionDescription From Region", BuildCnnStr("(local)", "Northwind"))
The RegionURL consists of a Web Form name and the statement ?RegID=Cast(RegionID as
Char(2)), which ASP.NET loads into the new page and passes to the RegionID of the page, letting the code within the page read the RegionID using the Request object, as displayed here: odaTer = New _ OleDb.OleDbDataAdapter(_ "Select TerritoryDescription From Territories Where RegionID = " & Request.Item("RegID"), _ BuildCnnStr("(local)", "Northwind"))
You will see both the creation and utilization of the URL in the steps that follow.
Programming Repeater Events by Using ItemCommand
When you're using buttons, you can program the response for when the buttons are pressed by using the ItemCommand event. This event is raised for all the controls that are used in the Repeater. You will see an example of this in step 5.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.4: Display Data Using the Repeater Control. You will then see a page open displaying a list of the regions (see Figure 5.5). Figure 5.5. This list includes both a button, displaying the RegionID, and a hyperlink, displaying the region description.
Page 162
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
If you click one of the buttons displaying the Region ID, then another list is displayed using the Repeater control. This list is displayed below the regions and contains the territories for the region clicked (see Figure 5.6). Figure 5.6. Another Repeater control is utilized for this list of territories.
When you click on the hyperlinks in the list, another page displays, with yet another Repeater control used to display the territories for the region chosen (see Figure 5.7). 1. Create a Web Form. Then place the controls listed in Table 5.8 with the following properties
Page 163
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
set.
Table 5.8. Property Settings Repeater and HyperLink Controls Object Property Setting
Repeater Repeater HyperLink
ID ID ID NavigateURL
repRegions repTeritories hplReturnToMain wfrmMain.aspx
2.
Switch to the HTML tab in the designer. By adding the repeaters and naming the repeaters in step 1, you will see a line of code that looks like this:
3. 4. Replace this line of code with the code displayed in Listing 5.13. This code lays out the templates that were described in the "Technique" section, as well as the button and hyperlink described. Note that the FooterTemplate, listed here, is not really used for anything. It was included so that you could see how to use it. It can be excluded. Listing 5.13 wfrmHowTo5_5a.aspx: HTML for the repRegions Repeater
List of Regions
5. Next, replace the HTML code inserted for the repTerritories repeater with the code in Listing 5.14. After the HeaderTemplate is specified, a Label control displays the
TerritoryDescription column.
Listing 5.14 wfrmHowTo5_5a.aspx: HTML for the repTerritories Repeater
Page 164
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
List of Territories
6. Add the code in Listing 5.15 to the Load event of the page. If the page is first being loaded, then the odaRegions DataAdapter fills the data table called dtRegions. dtRegions is set as the data source for repRegions, and DataBind method is called, binding the Repeater to the data table. Listing 5.15 wfrmHowTo5_5a.aspx.vb: Loading the repRegions Repeater Control
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not Me.IsPostBack Then Dim odaRegions As OleDb.OleDbDataAdapter Dim dtRegions As DataTable odaRegions = New OleDb.OleDbDataAdapter("Select RegionID, _ 'wfrmHowto5_5b.aspx?RegID=' + Cast(RegionID as Char(2)) As RegionURL, _ RegionDescription From Region", BuildCnnStr("(local)", "Northwind")) dtRegions = New DataTable() odaRegions.Fill(dtRegions) repRegions.DataSource = dtRegions repRegions.DataBind() End If End Sub 7. Add the code in Listing 5.16 to the ItemCommand event of repRegions. This code takes the Text property of the button, which is the RegionID, and uses it in the SQL string to supply the odaTer data adapter. Next, odaTer fills dtTer, which is then used as the data source for repTerritories. Listing 5.16 wfrmHowTo5_5a.aspx.vb: Loading the Categories DropDown and Product Table Control
Page 165
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub repRegions_ItemCommand(ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles repRegions.ItemCommand Dim odaTer As OleDb.OleDbDataAdapter Dim dtTer As DataTable odaTer = New _ OleDb.OleDbDataAdapter(_ "Select TerritoryDescription From Territories Where RegionID = " & CType(e.CommandSource, Button).Text(), _ BuildCnnStr("(local)", "Northwind")) dtTer = New DataTable() odaTer.Fill(dtTer) repTerritories.DataSource = dtTer repTerritories.DataBind() End Sub 8. Create another Web Form. Then place a Repeater control on it and set the ID of the Repeater to be repTerritories. Note
When you are saving and naming the Web Form created in this step, make sure you name it the same as that used in the code in step 4. Remember that it was the Web Form used in the RegionURL.
9. Switch to the HTML tab in the designer. Replace the line of code that has been created for the repTerritories Repeater control with the code shown in Listing 5.17. Listing 5.17 wfrmHowTo5_5b.aspx: HTML for the repTerritories Repeater on the Second Web Form
List of Terriories
Page 166
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
10. Add the code in Listing 5.18 to the Load event of the page. This code reads the RegionID first from the first Web Form using the Request object. Next, it is used to fill the dtTer data table, which is then assigned as the data source for repTerritories. Listing 5.18 wfrmHowTo5_5b.aspx.vb: Loading the repTerritories Repeater Control on the Second Web Form
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim odaTer As OleDb.OleDbDataAdapter Dim dtTer As DataTable odaTer = New OleDb.OleDbDataAdapter(_ "Select TerritoryDescription From Territories Where RegionID = " & Request.Item("RegID"), _ BuildCnnStr("(local)", "Northwind")) dtTer = New DataTable() odaTer.Fill(dtTer) repTerritories.DataSource = dtTer repTerritories.DataBind() End Sub Figure 5.7. A third Repeater control is utilized for this list of territories on a new page.
[ Team LiB ]
Page 167
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Comments
After you have used DataRepeater a couple of times, it is really quite simple to use. By playing with the templates, you can display fairly attractive lists that are nice and dynamic.
[ Team LiB ]
Page 168
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.6 Display, Sort, and Page Data in the DataGrid Control
The Table controls and DataRepeater are fine when I have small sets of data, but the display just keeps repeating and I have to write a bunch of code to change the sort order of the data. How do I create a table-like display that will show a set number of rows at a time and let me sort the data?
Technique
The DataGrid control is by far the most flexible and powerful of the controls used in ASP.NET for displaying data on your Web page. It gives you the ability not only to list data, but also to page through it and sort it nicely with headers, and even to edit data. This last feature will be saved for the next How-To. To perform the other tasks, you will use a combination of setting properties at design time and programming some events. In particular for the DataGrid control, you will add code to events raised by sorting and paging. This How-To will use the DataGrid bound at design time. You will also see a simple example of using the DataView object for sorting your data.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.6: Display, Sort, and Page Data in the DataGrid Control. You will then see all the territories loaded into a data grid. You can click the column headings, displayed in blue, to sort the columns, and you can click the arrows at the bottom to page through the data. You can see the Web Form in Design mode in Figure 5.8. 1. Create a Web Form. Then place the controls in Table 5.9 and Figure 5.8 with the following properties set.
Table 5.9. Property Settings for the Controls Used in This How-To Object Property Setting
OleDbDataAdapt ID er
odaTerritory
SelectComma SELECT nd Territories.TerritoryID, Territories.TerritoryDescript ion, Region.RegionDescription, Region.RegionID FROM Territories INNER JOIN Region ON Territories.RegionID = Region.RegionID
Page 169
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataSet DataView
ID ID Table
dsTerritory dvTerritory dsTerritory.Territories dgTerritory hplReturnToMain
DataGrid HyperLink
ID ID
NavigateURL wfrmMain.aspx
2. Right-click on the DataGrid control and choose Property Builder. You will then see the General tab of the DataGrid Property Builder. Set the properties as displayed in Figure 5.9. Figure 5.9. Setting the General properties of the DataGrid control.
3.
Click on the Columns tab. You can now add the columns TerritoryID, TerritoryDescription, and RegionDescription by clicking on the field in the available columns and then clicking the Add button for each one. You can then set the Header text for each to be TerritoryID, Territory, and Region respectively, by clicking on the column in the Selected Column list and changing the Header text property. When you are finished and you have the Region highlighted, it should look like Figure 5.10. Figure 5.10. Setting the columns for the DataGrid control is easy at design time.
Page 170
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Note
Be sure to uncheck the Create Columns Automatically at Run Time check box; otherwise, the columns will end up showing up twice once from you specifying them here at design time, and once when the code generates them.
4. Click on the Paging tab. Click on the Allow Paging check box, and type 10 for the Page Size (see Figure 5.11.) You can then close the Property Builder dialog box by clicking OK. Figure 5.11. Setting the Paging properties at design time for the DataGrid control.
Page 171
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
5.
Create the BindTheGrid routine in Listing 5.19. Note that you are now binding to the
DataView, rather than to a dataset.
Listing 5.19 wfrmHowTo5_6.aspx.vb: Binding the Data Grid to the DataView Control
Sub BindTheGrid() odaTerritory.Fill(dsTerritory) dgTerritory.DataSource = dvTerritory dgTerritory.DataBind() End Sub 6. Add the code in Listing 5.20 to the Load event of the page. Listing 5.20 wfrmHowTo5_6.aspx.vb: Loading the Page
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not Me.IsPostBack Then BindTheGrid() End If
Page 172
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 7. Add the code in Listing 5.21 to the PageIndexChanged event of dgTerritory. This routine takes the NewPageIndex and assigns it to the data grid's CurrentPageIndex. Next, if MySort exists in the ViewState object, it is assigned to the DataView control. MySort is stored in the next step. Listing 5.21 wfrmHowTo5_6.aspx.vb: Paging the Data Grid
Private Sub dgTerritory_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgTerritory.PageIndexChanged '-- Set the current page in the data grid Me.dgTerritory.CurrentPageIndex = e.NewPageIndex If Not (ViewState("MySort") = Nothing) Then dvTerritory.Sort = ViewState("MySort") End If BindTheGrid() End Sub 8. Add the code in Listing 5.22 to the SortCommand event of dgTerritory. When a column heading is clicked and sorting is turned on, this event is raised. This routine assigns the SortExpression to the Sort property of the dgTerritory. The SortExpression property is then stored in the ViewState object for round trips to the server, and then it is used in the code listed in step 6. Listing 5.22 wfrmHowTo5_6.aspx.vb: Sorting the Data Grid
Private Sub dgTerritory_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles dgTerritory.SortCommand dvTerritory.Sort = e.SortExpression.ToString ViewState("MySort") = e.SortExpression.ToString BindTheGrid() End Sub Figure 5.8. The DataGrid control is a great way to manipulate data.
Page 173
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
The DataView is a great control for seeing different views of your data by using a single dataset. As with the DataRepeater, working with some of the basic features in the data grid is pretty easy. It's when you have to start really manipulating data that it gets more difficult, as you will see in the next How-To.
[ Team LiB ]
Page 174
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.7 Add, Edit, and Delete Data Using the DataGrid Control
The Table controls and DataRepeater are fine when I have small sets of data, but the display just keeps going on and on, and I have to write a bunch of code to change the sort order of the data. How do I create a table-like display that will show a set number of rows at a time and let me sort the data?
Technique
One of the nice things about the DataGrid control that makes it so much more powerful than the other list controls is its ability to add, edit, and delete directly within the control. This How-To shows you how to create columns to manage your data using the DataGrid control.
Adding Buttons to the DataGrid Control
You will use the DataGrid control with more code this time so that you can work with data more. You will also be adding a couple of buttons to the DataGrid display to allow you to edit, delete, and update data. You will add buttons to the data grid by right-clicking on the control, choosing Property Builder, and then choosing the Columns tab. You can then select from the list of button types (see Figure 5.12). Figure 5.12. The buttons listed in Selected Columns are being used for this example.
Note Be sure to leave the Create Columns Automatically at Run Time check box checked. Unless you specify other columns or have the data loaded at run-time, you will end up with just the buttons, which would be pretty
Page 175
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
boring.
Using Events with Buttons on the Data Grid
After you have selected to include buttons in the data grid, you not only have to add the code to the events for the specific buttons, but you also have to make sure that ASP.NET knows the events to use. You can do this in a couple of ways. One way is to set the AutoEventWireUp attribute of the page to True. You can see this attribute in the first line of the Web page. By default, the attribute is set to False. After you add the buttons to the data grid, you will see the buttons in the DataGrid control.
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="wfrmHowTo5_7.aspx.vb" Inherits="VB.NET__Chapter_5.wfrmHowTo5_7"%>
However, a couple of disadvantages result from setting the AutoEventWire:
You have to use the required names for your events. Events sometimes end up being called twice on the form.
Microsoft recommends not setting the AutoEventWireUp to True. The other alternative is to add the events and HTML tags yourself. You will see the HTML code added in step 3.
Loading a Schema into a Data Table
Another option that is introduced in this How-To is the fill of a data table by using the FillSchema method of the data adapter. This means that the data table will be smart and know what the constraints and properties of the columns are before you try to save the data back to the server. The big benefit with using the FillSchema method with the DataGrid control is that it will be intelligent, and it won't let a user try to edit an auto increment column, such as an identity column. It will make such a column disabled. When you update the columns from the data grid back into the data table, you can also check to see if the column's AutoIncrement property is True. Unless you use the FillSchema method, the
AutoIncrement property will come back False, even if the actual column in the table on the server has it set to True. Additional Objects, Properties, and Methods Used to Handle Data
In addition to the FillSchema method of the data adapter, you will also use the Update method, which will call the Update, Delete, or Append statement, depending on the task that is being performed. The CommandBuilder object will generate your SQL statements used to send modifications back to the server.
Page 176
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
In addition to the methods mentioned for the data adapter, you will use some properties and methods of the data table to add, edit, and delete data. You can see a list of those objects, properties, and methods in Table 5.10. Table 5.10. Objects, Properties, and Methods of the DataTable Object Object Property/Method Description Deletes a row from the DataTable object (the data is not deleted from the server at this point).
DataTable.Rows Delete
DataTable.Rows Count
Returns the number of rows that are currently in the DataTable object. Creates a new DataRow object. Adds the DataRow object to the DataTable object. Turns off the schema checking that occurs when you're adding the new row to the DataTable object. Resets the DataTable status, including ending edits on
DataTable
NewRow
DataTable.Rows Add DataTable BeginLoadData
DataTable
AcceptChanges
DataRow objects. The DataRowState also changes. All
added and modified rows become unchanged, and deleted rows are removed.
DataTable
RejectChanges
Rejects the changes made since the last AcceptChanges was called. Lets you roll back changes if errors occur.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.7: Add, Edit, and Delete Data Using the DataGrid Control. You will then see all the regions loaded into a data grid. You can click on the Edit button to edit data, and so on. You can see the form created in Design view in Figure 5.13. 1. Create a Web Form. Then place the controls in Table 5.11 and Figure 5.13 with the following properties set. Don't worry about the Edit and Delete buttons displayed until the next step.
Table 5.11. Property Settings for the Controls Used in This How-To Object Property Setting
DataGrid Button Label
ID ID ID ForeColor
dgRegion btnAdd lblDispExcp #C00000 hplReturnToMain
HyperLink
ID
Page 177
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
NavigateURL
2.
wfrmMain.aspx
Right-click on dgRegion, and choose Property Builder from the pop-up menu. Click on the Columns tab. You are going to add Edit, Update, Cancel (one button choice), and Delete buttons, as displayed in Figure 5.12. Change the ButtonType of each button to PushButton. After you have selected the buttons, click OK.
3.
Now it's time to add the HTML code to connect the buttons to some code you will add in the following steps. In Listing 5.23, you can see the final HTML for the DataGrid control. The lines of code that you will need to add are the ones for OnUpdateCommand, OnCancelCommand, OnEditCommand, and OnDeleteCommand. By entering these lines as they are listed and creating the events as named, your code will work for the buttons in the DataGrid control. You will then add code behind in the following steps that will match these commands. Listing 5.23 wfrmHowTo5_7.aspx: Wiring Up Events for the DataGrid Control
4. Now it's time to add some Visual Basic code. In the class module behind the Web Form, add the following line of code just after the region that says Web Form Designer Generated Code. mdtRegion will be used throughout the form for managing the data and synchronizing with the data grid. mdtRegion will also be saved to the Session object (called RegionDT) for round trips to the server and back. You will see this in the next step. 5. 6. 7. Dim mdtRegion As New DataTable() Add the code in Listing 5.24 to the Load event of the Page. The task that occurs is checking for the existence of RegionDT in the Session object. If it exists, then this is a round trip, and you don't need to reload the data from the server. If it doesn't exist, then the Region table Schema is supplied using the FillSchema method, and then the DataTable object is filled. Next, the RegionDT and IsAdding Session variables are saved. The IsAdding session variable is used to track whether you are adding a record. Last, the data is bound to the DataGrid object using the BindTheGrid routine, which follows the Page_Load event in this listing. Listing 5.24 wfrmHowTo5_7.aspx.vb: Initially Loading the DataGrid Object and Tracking Session Variables
Page 178
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If (Session("RegionDT") Is Nothing) Then Dim odaRegion As OleDb.OleDbDataAdapter odaRegion = New _ OleDb.OleDbDataAdapter("Select RegionID as [Region ID], " & "RegionDescription as Region From Region", _ BuildCnnStr("(local)", "Northwind")) odaRegion.FillSchema(mdtRegion, SchemaType.Source) odaRegion.Fill(mdtRegion) Session("RegionDT") = mdtRegion Session("IsAdding") = False BindTheGrid() Else mdtRegion = CType(Session("RegionDT"), DataTable) End If End Sub Sub BindTheGrid() dgRegion.DataSource = mdtRegion dgRegion.DataBind() End Sub Tip
To figure out when the page is going back to the server, put a break point in the Page_Load event code. Then you can see the code break whenever you go back to the server. If you note which routine you were in before you went back to the server, you can then place code in it to save any data you need to.
8. Create the dgRegion_EditCommand routine as shown in Listing 5.25. This is one of the events specified in step 3. This code sets the EditItemIndex of the DataGrid object to the selected item and then binds the data.
Page 179
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 5.25 wfrmHowTo5_7.aspx.vb: Setting the Data Grid to Edit Mode
Sub dgRegion_EditCommand(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) '-- Clear the error display lblDispExcp.Text = "" '-- Turn on the editing by pointing the EditItemIndex ' to the ItemIndex
dgRegion.EditItemIndex = e.Item.ItemIndex BindTheGrid() End Sub 9. Add the code in Listing 5.26 to the Click event of btnAdd. The first task is to invoke the
BeginLoadData method for mdtLookupData. This turns off constraint checking while you're
loading data. You should turn this off so that it doesn't check for required fields until you actually edit the record, which is caused by the line of code setting the EditItemIndex property of the DataGrid object. The Session variables are then updated, with the
IsAdding item set to True. Lastly, the EditItemIndex of dgLookupData is then set, and the DataGrid bound to the data table using the BindTheGrid routine.
Listing 5.26 wfrmHowTo5_7.aspx.vb: Adding a New Record to the Data Table
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click Dim intColCnt As Integer Dim drCurr As DataRow lblDispExcp.Text = "" mdtRegion.BeginLoadData() '-- Add the row to the data table via the data row drCurr = mdtRegion.NewRow mdtRegion.Rows.Add(drCurr) '-- Set the Adding flag. Session("MyLookupData") = mdtRegion Session("IsAdding") = True '-- Set the item index based on the rows on this page only. dgRegion.EditItemIndex = mdtRegion.Rows.Count - 1 BindTheGrid()
Page 180
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 10. Create the dgRegion_DeleteCommand routine as shown in Listing 5.27. This is one of the events specified in step 3. This code is a lot like the code in the previous step, when the record was being added. The big difference in this step's code listing is that the deletion is posted back to the server, and in step 7, it wasn't. The deletion wasn't posted in that step because the server never knew anything about the record; it had only been added to the data table and not sent back to the server. You can see the data being updated back to the server for the add and edit in the next step. One other item to note is the RejectChanges method called in the Catch of the exception handling code. This way, if an error occurs, then the change is undone, the message is noted, and life goes on. The rest of this code follows pretty closely what was done in the previous step. Listing 5.27 wfrmHowTo5_7.aspx.vb: Deleting a Row in the Data Grid
Sub dgRegion_DeleteCommand(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) Dim intColCnt As Integer Dim cnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) '-- Create the command builder to update (post) the data ' in the data grid back to the server.
Dim odaRegion As OleDb.OleDbDataAdapter Try '-- Take the txtSQLString text and create the data table, ' and then set the data source of the data grid.
odaRegion = New _ OleDb.OleDbDataAdapter("Select RegionID as [Region ID], " & "RegionDescription as Region From Region", cnn) Dim ocbRegion As OleDb.OleDbCommandBuilder = _ New OleDb.OleDbCommandBuilder(odaRegion) '-- Delete the row from the data table mdtRegion.Rows(e.Item.ItemIndex).Delete() '-- Commands necessary to actually post back to server. cnn.Open() odaRegion.Update(mdtRegion) mdtRegion.AcceptChanges() cnn.Close()
Page 181
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Session("MyLookupData") = mdtRegion Session("IsAdding") = False '-- Just in case they were editing and press Delete, Clear. dgRegion.EditItemIndex = -1 Catch excp As Exception lblDispExcp.Text = excp.Message mdtRegion.RejectChanges() End Try BindTheGrid() End Sub 11. Create the dgRegion_UpdateCommand routine as shown in Listing 5.28. This is one of the events specified in step 3. This routine starts off by declaring DataAdapter and
CommandBuilder objects to update your data back to the server. Before the actual update, however, the current row that is being edited in the data grid is assigned to a DataRow
object. Then each of the items in the row is saved from the data grid cells to the column in the data row. Thanks to using the FillSchema method when you're filling the data table, the
AutoIncrement property will reflect whether a column is an Identity column. If the FillSchema method is not used, you have to handle the exception that occurs when you
try to write the value to the column. When you're writing the cells into the columns of the data row, the Trim function is used. Because of using the FillSchema method, the values are padded out as SQL Server columns generally are. The rest of the code runs similarly to step 8 in that the changes are accepted, written back to the server, and so forth. Listing 5.28 wfrmHowTo5_7.aspx.vb: Updating Changes Back to the Server
Sub dgRegion_UpdateCommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) Dim intColCnt As Integer Dim intColCurr As Integer Dim drCurr As DataRow Dim cnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) Dim blnAdding As Boolean Dim strCurrValue As String '-- Create the command builder to update (post) ' the data in the data grid back to the server. lblDispExcp.Text = ""
Page 182
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim odaTableData As OleDb.OleDbDataAdapter Try '-- Take the txtSQLString text and create data table; then set the ' data source of the data grid.
Dim odaRegion As New _ OleDb.OleDbDataAdapter("Select RegionID as [Region ID], " & "RegionDescription as Region From Region", cnn) Dim ocbTableData As OleDb.OleDbCommandBuilder = _ New OleDb.OleDbCommandBuilder(odaRegion) drCurr = mdtRegion.Rows(dgRegion.EditItemIndex) '-- Update the fields in the rows intColCnt = e.Item.Cells.Count For intColCurr = 2 To intColCnt - 1 If mdtRegion.Columns(intColCurr - 2).AutoIncrement = False Then drCurr.Item(intColCurr - 2) = _ Trim(CType(e.Item.Cells(intColCurr).Controls(0), _ TextBox).Text) End If Next '-- Commands necessary to actually post back to server. cnn.Open() odaRegion.Update(mdtRegion) mdtRegion.AcceptChanges() cnn.Close() Session("RegionDT") = mdtRegion Session("IsAdding") = False dgRegion.EditItemIndex = -1 BindTheGrid() Catch excp As Exception lblDispExcp.Text = excp.Message
End Try
Page 183
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 12. Create the dgRegion_CancelCommand routine as shown in Listing 5.29. This is one of the events specified in step 3. If you're in the middle of adding an entry, this code uses the EditItemIndex of the DataGrid object to the selected item. The value that EditItemIndex returns is used to position the pointer in mdtLookupData so that the Delete method can be called. After the code accepts the changes, it resaves the session variables and cleans up the page index for the DataGrid object by comparing the current page number relative to the pointer of the DataTable position to the CurrentPageIndex property. Regardless of whether the item is being added or edited, the code clears EditItemIndex by setting it to 1 and it rebinds the data grid by calling BindTheData(). Listing 5.29 wfrmHowTo5_7.aspx.vb: Cancelling Edits to the Data Grid
Sub dgRegion_CancelCommand(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) Dim blnAdding As Boolean '-- If you cancel while you're adding a record, you need to back the ' ' row out of the data table and data grid. You don't have to send it to the server because it really was never added to it.
lblDispExcp.Text = "" If CType(Session("IsAdding"), Boolean) Then mdtRegion.Rows(dgRegion.EditItemIndex).Delete() mdtRegion.AcceptChanges() Session("IsAdding") = False Session("RegionDT") = mdtRegion End If dgRegion.EditItemIndex = -1 BindTheGrid() End Sub Figure 5.13. The DataGrid control is a great way to manipulate data.
Page 184
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
Whew! This seems like a lot of work! The good news is that after you have created the code, you can cut and paste when you're creating new pages that use the same techniques. Remember that this How-To is a starting part, and it's by no means bullet proof. It is up to you to take this code to the next level.
[ Team LiB ]
Page 185
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 5.8 Hyperlink from a Row in the Data Grid to a Detail Page
Often, I need to zero in and display data based on a record in the DataGrid control. How do I display detail information in a separate page from a DataGrid control?
Technique
One of the types of columns that you can use in the data grid is the HyperLink column. This column makes it fairly easy to link pages based on data. To see how the HyperLink type column is used in this How-To, take a look at Figure 5.14. Figure 5.14. No code is required for link pages based on data.
By your specifying the URL Field to be ProductID and URL Format String to be
wfrmHowTo5_8b.aspx?ID={0}, the data grid automatically calls the wfrmHowTo5_8b.aspx and
passes the ProductID to the form when you click on a product.
Steps
Open and run the Visual Basic .NET Chapter 5 solution. From the main page, click on the hyperlink with the caption How-To 5.8: Hyperlink From a Row in the Data Grid to a Detail Page. You then see all the products loaded into a data grid. Notice that the products are actually hyperlinks (see Figure 5.15). Figure 5.15. These hyperlinks require no code to call a detail page.
Page 186
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When you click on a product, another page is displayed, with detail information supplied (see Figure 5.16). 1. Create a Web Form. Then place the controls in Table 5.12 and Figure 5.15 with the following properties set.
Table 5.12. Property Settings for the Controls Used on the First Page of This How-To Object Property Setting
OleDbDataAdapter ID
odaProducts
SelectCommand SELECT ProductID, ProductName FROM Products DataSet DataGrid ID ID DataSource DataKeyField DataMember HyperLink ID NavigateURL dsProducts dgProducts dsProducts ProductID Products hplReturnToMain wfrmMain.aspx
Page 187
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
2. Right-click on the DataGrid control and choose Property Builder. Click on the Columns tab and set the properties as displayed in Figure 5.14. Be sure to note the name of the form you are calling in the URL Format String so that you can name it the same in step 4. 3. Add the code in Listing 5.30 to the Load event of the page. Listing 5.30 wfrmHowTo5_8a.aspx.vb: Filling and Binding the Products to the DataGrid Object
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here odaProducts.Fill(DsProducts) dgProducts.DataBind() End Sub 4. Create another Web Form. Then place the controls in Table 5.13 and Figure 5.16 with the following properties set.
Table 5.13. Property Settings for the Controls Used on the Second Page of This How-To Object Label Label TextBox TextBox
5.
Property Text Text ID ID
Setting Product Name Unit Price txtProductName txtUnitPrice
Add the code in Listing 5.31 to the Load event of the page. In the SQL select statement created in this listing, the Request.Item is used to grab the productID that was passed from the first form. The dtProdIndiv data table is filled, and the individual column information is loaded into the text boxes. Listing 5.31 wfrmHowTo5_8b.aspx.vb: Loading the Detail Information Based on the ProductID
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here Dim odaProdIndiv As OleDb.OleDbDataAdapter odaProdIndiv = New _ OleDb.OleDbDataAdapter(_ "Select * From Products Where ProductID = " &
Page 188
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Request.Item("ID"), BuildCnnStr("(local)", "Northwind")) Dim dtProdIndiv As New DataTable() odaProdIndiv.Fill(dtProdIndiv) With dtProdIndiv.Rows(0) Me.txtProductName.Text = .Item("ProductName") Me.txtUnitPrice.Text = .Item("UnitPrice") End With End Sub Figure 5.16. You will use the request object in code on this page to retrieve detail data.
Comments
That's it! A good way to expand this example is to add the coding technique learned in the previous How-To for editing data. Using data with your Web Forms is not much harder than using Windows Forms. Just remember to stash some variables for round trips to the server and to bind your data.
[ Team LiB ]
Page 189
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 6. Creating Transact-SQL Commands
In this chapter you will
Retrieve unique records using only a select query Use variables and functions in T-SQL Use wildcards and ranges of values in a SQL query Find records in a table without corresponding entries in a related table Take advantage of using subqueries Create, modify, and delete tables Create a new table with data from existing tables Create and call SQL Server 2000 user-defined functions
Many databases use the SQL database language as the primary way of communicating from an application to the database and working with data. Transact-SQL (T-SQL) is an enhanced version developed to work with Microsoft SQL Server. Besides being able to handle standard SQL commands, T-SQL provides additional statements and commands that allow you to create database objects, maintain data, and use programmatic control from within stored procedures and user-defined functions. With T-SQL, you can perform pretty well any of the necessary tasks that you have from day to day. When you combine that with SQL-DMO, discussed in the next chapter, you can create quite advanced applications that take care of all your users' needs. Note This chapter takes you through creating SQL statements and more extensive routines by setting the command text of command objects. Normally, you would create stored procedures to perform these tasks. This chapter uses the technique it does so that you don't need to add stored procedures to your copy of the SQL Server Northwind database.
You can find all of the examples in this chapter in the Solution called Visual Basic .NET on the Web site.
Chapter 6
[ Team LiB ]
Page 190
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.1 Retrieve Unique Records Using Only a Select Query
I need to figure out which customers have invoices. The problem is that when I join the Customers with the Orders tables, I get the customers listed for each order. I only want each customer listed once. How do I return only those customers who have orders, but only once?
Technique
For this How-To, you will be using the DISTINCT clause on a SQL SELECT statement to limit the data to unique values. When you include the DISTINCT clause, SQL Server uses the columns that are returned to determine how to limit the data. For the opposite affect, you can include the ALL clause, although it is not necessary because this is the default. You will create two SELECT statements for this task. The first one is for all records:
SELECT Customers.CompanyName FROM Customers INNER JOIN Orders ON Customers .CustomerID = Orders.CustomerID
To limit the records, use the DISTINCT clause:
SELECT DISTINCT Customers.CompanyName FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.1. When the form loads, you will see two option buttons, Show All and Distinct, with Show All selected. The SELECT statement showing an inner join between customers and order is displayed in a Label control. You will also see a DataGrid control filled with multiple entries of customers displayed (see Figure 6.1). Figure 6.1. A common problem with inner joins is retrieving multiple records when you want to see just one per occurrence.
Page 191
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
If you click on the option button labeled Use Distinct, then the DataGrid control will be refreshed, but only one customer per set of orders will be displayed. 1. Create a Windows Form. Then place the controls listed in Table 6.1 with the following properties set, as displayed in Figures 6.1 and 6.2. Figure 6.2. Using the DISTINCT clause gives you control over displaying unique records.
Page 192
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 6.1. Control Property Settings for How-To 6.1 Object Property Setting
RadioButton
Name Checked
rbShowAll True rbDistinct SQL Statement lblSQLString Results dgResults
RadioButton Label Label Label DataGrid
2.
Name Text Name Text Name
As with some of the other chapters' projects, you need to build a support routine to create the Connection string. Called BuildCnnStr, the function can been seen in Listing 6.1. This function takes a server and database name passed to it and creates a connection string. Listing 6.1 modGeneralRoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, _
Page 193
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method would be to pass back a string. The reason for this is that for some objects, you are asked only for a Connection object, but other objects want just a string. 3. Add the code in Listing 6.2 to the Load event of the form. (Double-click on the form to bring up the code.) Listing 6.2 frmHowTo6_1.vb: Loading the Form
Private Sub frmHowTo6_1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load GenerateData(Me.rbDistinct.Checked) End Sub 4. Add the code in Listing 6.3 to the class module of the page, creating the GenerateData routine. This routine creates the necessary SQL SELECT statement based on whether
blnUseDistinct is true or false. If you look back at Listing 6.2, you will see that this is
the value of option button rbDistinct. After the SQL string is created, it is assigned to lblSQLString to display the string, and then it is used in a data adapter to fill a dataset. Last, the SQL string is assigned as the data source for the data grid dgResults. Listing 6.3 frmHowTo6_1.vb: Building the SQL String for Retrieving the Data
Sub GenerateData(ByVal blnUseDistinct As Boolean) '-- Build the SQL String Dim strSQL As String strSQL = "SELECT " If blnUseDistinct Then strSQL += "DISTINCT " End If strSQL += "Customers.CompanyName FROM Customers " strSQL += "INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID" '-- Store the SQL String Me.lblSQLString.Text = strSQL
Page 194
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Use the SQL String to build the data adapter and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblSQLString.Text, _ BuildCnnStr("(local)", "Northwind")) Dim dtResults As New DataTable() odaResults.Fill(dtResults) '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults End Sub 5. Add the code in Listing 5.4 to the CheckChanged event of the rbDistinct Radio Button control. Listing 6.4 frmHowTo6_1.vb: Regenerating the Data Based on the Radio Button That Is Checked
Private Sub rbDistinct_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles rbDistinct.CheckedChanged
GenerateData(Me.rbDistinct.Checked) End Sub Tip
You might have noticed that besides the loading of the form, I only call the GenerateData routine when the rbDistinct option button is changed, and not when the rbShowAll option button is changed. Because only two buttons are available, you only have to program one of the control's events. If you put it on both, you will have the routine called twice, which is not a good thing in this case.
Comments
It is hard to believe that just one word can affect the data that a SQL statement returns. For the most part, you will want to see all of the records that a SELECT statement returns, but it is nice to have the DISTINCT clause when you need to limit the data.
[ Team LiB ]
Page 195
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.2 Use Variables and Functions in T-SQL
I understand that I can use parameters in my stored procedures, but how do I use variables and functions within T-SQL?
Technique
It is time to expand the coding you do using T-SQL. In this book so far, you have pretty well been limited to single-line SELECT statements. Now you will learn how to use variables and built-in functions. To achieve this, look at the routine that will be created here:
DECLARE @Cust_Id nchar(5), @Order_Date datetime SET @Cust_Id = 'ANTON' SET @Order_Date = '11/27/1996' SELECT OrderID, OrderDate, ShippedDate, DateDiff(day, @Order_Date, ShippedDate) as Days_To_Ship FROM Orders WHERE CustomerID = @Cust_Id and OrderDate = @Order_Date Declaring Local Variables in T-SQL
You can use variables in T-SQL much like you would in your other coding languages. First, you must declare them. To declare variables in T-SQL, you will use the DECLARE statement, the ampersand with the variable name, and the data type. You can see an example of the variable declaration here, where nchar, with the length and datetime variables, is declared.
DECLARE @Cust_Id nchar(5), @Order_Date datetime
Note Besides the standard SQL Server data types, such as nchar, int, and
datetime, you can also declare and create a Table datatype. You will
see an example of this in How-To 6.8, found later in this chapter.
After you have declared the variables, you need to initialize them before you can use them.
Initialing Local Variables in T-SQL
To initialize the variables, you will use the SET command, shown in these two lines of code:
SET @Cust_Id = 'ANTON' SET @Order_Date = '11/27/1996'
By setting the initial values, you are then ready to use the variables within the rest of your procedure, any way that you need them, again, by using the @varname syntax.
Utilizing Built-In Functions
Within T-SQL, you can also use functions to perform some of the tasks needed, just as you do within Visual Basic. Not all of the functions are the same, nor are there necessarily as many. For
Page 196
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
instance, instead of a Date() function, which is used in Visual Basic, in T-SQL, you use the
GetDate() function. Functions also will not necessarily return the same values or accept the same
parameters. This How-To calls the DateDiff() function. As with Visual Basic's DateDiff() function, this function takes two dates, and based on the interval requested, it returns the difference between the two. To check out other functions that are available, you can look up the word function in the Books On-Line for SQL-SQL Server.
Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main page, click on the button with the caption How-To 6.2. When the form loads, you will see a SQL statement display in a label, and a DataGrid displayed below (see Figure 6.3). 1. Create a Windows Form. Then place the controls listed in Table 6.2 and seen in Figure 6.3 with the following properties set.
Table 6.2. Control Property Settings for This How-To
Object Label Label Label DataGrid
2.
Property Text Name Text Name
Setting SQL Statement lblSQLString Results dgResults
Add the code in Listing 6.2 to the Load event of the form. (Double-click on the form to bring up the code.) Creating the T-SQL routine described in the "Technique" section, this code then assigns the routine to the Text property of the Label called lblSQLString. It then creates a data adapter using the string and fills the dtResults DataTable. Last, the code assigns the data adapter as the data source for the dgResults data grid. Listing 6.5 frmHowTo6_2.vb: Storing the SQL Statement and Then Executing
Private Sub frmHowTo6_2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'-- Build the SQL String Dim strSQL As String strSQL = "DECLARE @Cust_Id nchar(5), @Order_Date datetime " & _ vbCrLf & vbCrLf strSQL &= "SET @Cust_Id = 'ANTON'" & vbCrLf strSQL &= "SET @Order_Date = '11/27/1996'" & vbCrLf & vbCrLf
Page 197
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
strSQL &= "SELECT OrderID, OrderDate, ShippedDate, " strSQL &= "DateDiff(day, @Order_Date, ShippedDate) as Days_To_Ship " strSQL &= "FROM Orders" & vbCrLf strSQL &= "WHERE CustomerID = @Cust_Id and OrderDate = @Order_Date" '-- Store the SQL String Me.lblSQLString.Text = strSQL '-- Use the SQL String to build the data adapter and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblSQLString.Text, BuildCnnStr("(local)", "Northwind")) Dim dtResults As New DataTable() Try odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults End Sub Figure 6.3. The Days_To_Ship is derived from using the DateDiff function with the OrderDate and ShippedDate.
Comments
For the most part, you will use parameters when you are creating your T-SQL routines. However, when you're creating multiple steps in your routines that are getting more complex, you'll use variables more often.
[ Team LiB ]
Page 198
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.3 Use Wildcards and Ranges of Values in a SQL Query
I need to be able to either search for a range of values, or at least be able to use wild cards with my query. How do I do this using T-SQL?
Technique
This is one of those fairly simple but necessary How-Tos. You will learn how to use a combination of both wild cards and a range of values. Here is the T-SQL routine that you will use for this How-To:
SELECT Customers.CompanyName, Orders.OrderID, Orders.OrderDate FROM Orders INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID WHERE Customers.CustomerID LIKE 'A%' AND Orders.OrderDate BETWEEN '11/01/1996' AND '12/01/1996'
Note The literal values have been used here, rather than the text box values that will be used in the How-To.
Using Wild Cards
Fairly similar to the wild cards of the old DOS days, wild cards in T-SQL are fairly straightforward to use. It is just a matter of knowing which one to use for which task. When using wild cards, you will use the LIKE operator, as seen in the SQL string for this How-To. You can see where the LIKE operator is used with A%. The % is used to specify anything after the given letter. In this case, it's used for anything starting with the letter A. (This operator will, of course, have to have the OrderDate fall between the dates specified, but we'll talk about this in a moment. You can use other wild cards as well, such as the following:
% (Percent sign). You use this to specify any given group of characters. If used before a
letter or group of letters, you are then specifying that you want values ending with those letters. For instance, if you specify %ing, you get skiing, flying, and so on.
_ (Underscore). You use this to specify a single character. For instance, if you type _ake,
then you would get four-letters words, such as lake, bake, and sake.
[] (Square brackets) This is a range or group of characters to compare against. For example, if you type [B-D]ake, you would get bake and cake. Another way to use it, with a group of letters, would be to type [BF]ake. In this case, you would get bake and fake, but
not the other letter that fall inbetween.
[^] (Caret). This is not within the given range or group. Opposite of the last entry, if you typed [^B-D]ake, you would get those words ending in ake, where the first letter doesn't
fall within B D. The same works for the group of letters as well.
Using BETWEEN
Page 199
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When you need to look at a range of values, whether it be numbers or dates, you use the BETWEEN operator. The syntax for BETWEEN is as follows:
table.column BETWEEN startingvalue AND endingvalue
This returns all records where the given column falls between the two values, including the two values. Because the BETWEEN statement mentioned a moment ago was Orders.OrderDate BETWEEN '11/01/1996' AND '12/01/1996', then those records with the OrderDate falling between 11/1/1996 and 12/1/1996 inclusively will be displayed.
Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.3. When the form loads, you will see a form that allows you to specify letter(s) for the company name to fill the data grid for, along with a range to specify for order dates (see Figure 6.4). 1. Create a Windows Form. Then place the controls listed in Table 6.3 with the following properties set, as displayed in Figure 6.4.
Table 6.3. Control Property Settings for This How-To Object Property Setting
Label TextBox
Text Name Text
Customer ID txtCustomerID A% Order Date: From To txtFromDate 11/01/1996 txtToDate 12/01/1996 SQL String lblSQLString Results dgResults
Label Label TextBox
Text Text Name Text
TextBox
Name Text
Label Label Label DataGrid
Text Name Text Name
Page 200
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
2. Add the following code in Listing 6.6 to the Load event of the form. (Double-click on the form to bring up the code.) Listing 6.6 frmHowTo6_3.vb: Calling GenerateData When Loading the Form
Private Sub frmHowTo6_3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load GenerateData() End Sub 3. In the class module for the form, add the code in Listing 6.7 to create the GenerateData routine. After creating the SQL statement, this routine assigns it to the Text property of lblSQLString. Then the string is used in a data adapter that was created to fill the
dtResults data table. Last, the data table is set as the data source for dgResults.
Listing 6.7 frmHowTo6_3.vb: Generating Data Using LIKE and BETWEEN Statements
Sub GenerateData() '-- Build the SQL String Dim strSQL As String strSQL &= "SELECT Customers.CompanyName, " & _ "Orders.OrderID, Orders.OrderDate " strSQL &= "FROM Orders INNER JOIN Customers " strSQL &= "ON Orders.CustomerID = Customers.CustomerID" & vbCrLf strSQL &= "WHERE Customers.CustomerID LIKE '" & _ Me.txtCustomerID.Text & "' AND " strSQL &= "Orders.OrderDate BETWEEN '" & Me.txtFromDate.Text strSQL &= "' AND '" & Me.txtToDate.Text & "'" '-- Store the SQL String Me.lblSQLString.Text = strSQL '-- Use the SQL String to build the data adapter and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblSQLString.Text, BuildCnnStr("(local)", "Northwind")) Dim dtResults As New DataTable() Try odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults
Page 201
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 4. Add the code in Listing 6.8 to the TextChanged events of txtCustomerID, txtFromDate, and txtToDate, respectively. These routines call GenerateDate when the values change. Listing 6.8 frmHowTo6_3.vb: Calling the GenerateData Routine When Text Is Updated
Private Sub txtCustomerID_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtCustomerID.TextChanged GenerateData() End Sub Private Sub txtFromDate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFromDate.TextChanged GenerateData() End Sub Private Sub txtToDate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtToDate.TextChanged GenerateData() End Sub Figure 6.4. A common problem with inner joins is retrieving multiple records when you just want to see one per occurrence.
Comments
By placing your use of wild cards and allowing for ranges of values, you can make your applications and the querying of data more versatile than ever!
[ Team LiB ]
Page 202
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.4 Find Records in a Table Without Corresponding Entries in a Related Table
I have a situation in which I need to find which clients don't have invoices. How do I do this?
Technique
To find out which records (customers) don't have corresponding records (invoices) in a related table, you have to have a better understanding of the types of joins that can be used between tables during queries. Before looking at the joins, following is the T-SQL statement that will be used in this How-To:
SELECT Customers.CustomerID, Customers.CompanyName FROM Customers LEFT OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID WHERE Orders.CustomerID IS NULL Types of Joins
You can use three types of joins to bring back different information. These join types include inner joins, left outer joins, and right outer joins.
Inner Join
This join displays records in which at least one record exists in each table for the joined field. This means that customers are displayed only if they have at least one invoice. If you want to see the CompanyName and OrderDate, the SELECT statement would be as follows:
SELECT Customers.CompanyName, Orders.OrderDate FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID Left Outer Join
You use this join when you want to see all of the records in the first table, but only those records in the second table that have matching records in the first table. An example of this would be if some customers didn't have invoices; all the customers would appear, but only those invoices that had customers assigned to them would be displayed. Note Normally, if your database is set up with referential integrity correctly, as Northwind is, you won't have any invoices without customers assigned to them.
The example SELECT statement for this will be used in the How-To. ON Customers.CustomerID = Orders.CustomerID WHERE Orders.CustomerID IS NULL
Remember, because you want only those customers without invoices, you need to check to see where Orders.CustomerID is NULL. Note
Page 203
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Although it is not strictly necessary to check whether the Orders.CustomersID is NULL, make sure to check for a column that would not be NULL if a record were there. OrderID would be another good column to check.
Right Outer Join
As you might have guessed by now, the right outer join is the opposite of the left outer join. Instead of listing all the customers and only those invoices that have customers, the right outer join shows you all records in the second table (invoices) and only those records from the first table (customers) in which there is a matching record on the joined column (CustomerID). One of the ways that the right outer join is used is to find bad data, such as non-relational data that could result from importing data from other systems. Use a SELECT statement similar to the one used for the left outer join type:
SELECT Customers.CustomerID, Customers.CompanyName FROM Customers RIGHT OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID WHERE Customers.CustomerID IS NULL
You will notice that instead of testing for Orders.CustomerID being NULL, you are checking to see if Customers.CustomerID is NULL.
Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.4. When the form loads, you will see the SQL String displayed with the data grid displaying customers who don't have orders (see Figure 6.5). 1. Create a Windows Form. Then place the controls listed in Table 6.4 with the following properties set, as displayed in Figure 6.5.
Table 6.4. Control Property Settings for This How-To Object Property Setting
Label Label Label DataGrid
2.
Text Name Text Name
SQL Statement lblSQLString Results dgResults
Add the following code in Listing 6.9 to the Load event of the form. (Double-click on the form to bring up the code.) The only difference in this routine from the previous How-To is the SELECT statement, which is described in the "Technique" section. Listing 6.9 frmHowTo6_4.vb: Using the Left Outer Join
Page 204
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub frmHowTo6_4_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '-- Build the SQL String Dim strSQL As String strSQL &= "SELECT Customers.CustomerID, Customers.CompanyName " strSQL &= "FROM Customers LEFT OUTER JOIN Orders " strSQL &= "ON Customers.CustomerID = Orders.CustomerID" & vbCrLf strSQL &= "WHERE Orders.CustomerID IS NULL" '-- Store the SQL String Me.lblSQLString.Text = strSQL '-- Use the SQL String to build the data adapter and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblSQLString.Text, _ BuildCnnStr("(local)", "Northwind")) Dim dtResults As New DataTable() Try odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults End Sub Figure 6.5. Using an outer join to retrieve records without corresponding records.
Comments
The majority of the time, you will be using the inner join rather than the outer joins. However,
Page 205
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
sometimes outer joins will be necessary, so you should experiment with them and get comfortable with them.
[ Team LiB ]
Page 206
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.5 Take Advantage of Using Subqueries
I think there are some duplicate records in one of my tables. Also, I need to know which of the cities (and regions) in a Northwind database has more than one customer in it. How can I use subqueries to perform these tasks?
Technique
To get the answers to the situations just presented, you will use a subquery in your T-SQL statement. A subquery is a complete SELECT statement. Following is the query that will be used for this How-To. It uses a subquery in the WHERE clause of the outer, or main query:
SELECT Customers.City, Customers.Region, Customers.CustomerID, Customers.CompanyName From Customers WHERE (((Customers.City) IN (SELECT Tmp.City FROM Customers As Tmp GROUP BY Tmp.City,Tmp.Region HAVING Count(*)>1 And Region = Customers.Region))) ORDER BY Customers.City, Customers.Region
You can see in this query that in the WHERE clause, the City column in Customers is used with an IN operator. The subquery in this case returns all the cities that are assigned to more than one customer. Note In this case, you are using a subquery much as you would a joined table or against another view. The nice thing about using the subquery is that you can see the entire query here, instead of opening another view that is joined. Performancewise, there is no benefit or degradation in using subqueries.
In addition to using subqueries in WHERE clauses, you can use them anywhere you would use an expression.
Steps
Open and run the "Visual Basic .NET Chapter 6" solution. From the main form, click on the button with the caption How-To 6.5. Much like a couple of the other How-Tos in this chapter, you will see the query displayed in the label on the top of the form, with the results displayed in the data grid object below (see Figure 6.6). 1. Create a Windows Form. Then place the controls listed in Table 6.5 with the properties set displayed in Figure 6.6.
Table 6.5. Control Property Settings for This How-To Object Property Setting
Label Label Label
Text Name Text
SQL Statement lblSQLString Results
Page 207
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataGrid
2.
Name
dgResults
Add the code in Listing 6.10 to the Load event of the form. (Double-click on the form to bring up the code.) Listing 6.10 frmHowTo6_5.vb: Loading and Executing the SQL Statement by Using the Subquery
Private Sub frmHowTo6_5_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '-- Build the SQL String that returns cities that ' have more than one customer in them. Dim strSQL As String strSQL = "SELECT Customers.City, Customers.Region, " & "Customers.CustomerID, Customers.CompanyName " strSQL &= "From Customers " strSQL &= "WHERE (((Customers.City) In " strSQL &= "(SELECT Tmp.City FROM Customers As Tmp " strSQL &= "GROUP BY Tmp.City,Tmp.Region HAVING Count(*)>1 " strSQL &= "And Region = Customers.Region))) " & _ "ORDER BY Customers.City, Customers.Region" Me.lblSQLString.Text = strSQL '-- Use the SQL String to build the data adapter and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblSQLString.Text, BuildCnnStr("(local)", "Northwind")) Dim dtResults As New DataTable() Try odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults End Sub Figure 6.6. Using subqueries in one step to retrieve information saves time and effort.
Page 208
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
Subqueries are a powerful tool for getting at your data in different ways. Following are some rules you have to remember when using subqueries:
You can only use an ORDER BY clause if you are using the TOP clause. If a table is being used in the subquery but not in the main query, then you cannot use columns from that table in the output of the main query.
You need to use parentheses around the subquery SELECT statement. You can't include a FOR BROWSE or COMPUTE clause in the subquery.
[ Team LiB ]
Page 209
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.6 Create, Modify, and Delete Tables
It is common in database applications to programmatically create, modify, and delete tables. How do I do this using T-SQL?
Technique
To perform these tasks, you will use the CREATE TABLE, ALTER TABLE, and DROP TABLE T-SQL statements. With these statements, you can handle any requirements that your application might have. Look at these statements one at a time.
Creating a Table Using CREATE TABLE
With the CREATE TABLE statement, not only can you specify columns and their data types, but you also can specify indexes, check constraints, and other table level properties. For this How-To, you will be use the following T-SQL statement:
CREATE TABLE ListsExample ( ListID smallint IDENTITY(1, 1) PRIMARY KEY CLUSTERED, LastName varchar(50) NOT NULL, FirstName varchar(50) NOT NULL, Age smallint , DateEntered datetime NOT NULL DEFAULT GetDate() CHECK (DateEntered <= GetDate()) )
This statement shows how to perform a number of different tasks: 1. 2. 3. 4. 5. 6. 7. 8. 9. LastName varchar(50) NOT NULL, 10. FirstName varchar(50) NOT NULL, 11. Age smallint , 12. Create a field with the Default Value set, and with a Check Constraint specified. 13. 14. DateEntered datetime NOT NULL DEFAULT GetDate() 15. CHECK (DateEntered <= GetDate()) ListID smallint IDENTITY(1, 1) PRIMARY KEY CLUSTERED, Create fields that can't be NULL, and using different data types: CREATE TABLE ListsExample Create an Identity column, which is the primary key: Specify the name of the table:
Modifying a Table Using ALTER TABLE
The example T-SQL statement used for modifying the table in this How-To is pretty simple in that it adds a column and removes (drops) a column:
ALTER TABLE ListsExample ADD MyNewColumn varchar(30)
Page 210
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html ALTER TABLE ListsExample DROP COLUMN Age
You can perform quite a few other tasks with this statement. You can even see by the syntax displayed here that you can handle many tasks, including dropping constraints.
ALTER TABLE table { [ ALTER COLUMN column_name { new_data_type [ ( precision [ , scale ] ) ] [ COLLATE < collation_name > ] [ NULL | NOT NULL ] | {ADD | DROP } ROWGUIDCOL } ] | ADD { [ < column_definition > ] | column_name AS computed_column_expression } [ ,...n ] | [ WITH CHECK | WITH NOCHECK ] ADD { < table_constraint > } [ ,...n ] | DROP { [ CONSTRAINT ] constraint_name | COLUMN column } [ ,...n ] | { CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [ ,...n ] } | { ENABLE | DISABLE } TRIGGER { ALL | trigger_name [ ,...n ] } }
You can do even more. Look at the Books Online for SQL Server to see complete coverage of this statement.
Deleting a Table Using the DROP TABLE Statement
This statement is the easiest, and it's a one liner:
DROP TABLE ListsExample
However, you need to keep some things in mind when you are trying to drop a table:
You can't use the DROP TABLE statement when the table is used in a relationship and is referenced in the FOREIGN KEY constraint. You will need to drop the other table or the constraint.
You will need to be the administrator or owner of the table to be able to use the DROP
TABLE statement. Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.6 (see Figure 6.7). 1. Create a Windows Form. Then place the controls listed in Table 6.6 with the following properties set, as displayed in Figures 6.7. You can't use the DROP TABLE statement on system tables.
Table 6.6. Control Property Settings for This How-To Object Property Setting
Page 211
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label Label Button
Text Name Name Text
SQL Statement to Create a Table lblCreateTable btnCreateTable Create Table SQL Statement to Modify a Table lblModifyTable btnModifyTable Modify Table SQL Statement to Delete a Table lblDeleteTable btnDeleteTable Delete Table
Label Label Button
Text Name Name Text
Label Label Button
Text Name Name Text
2.
Add the code in Listing 6.11 to the Load event of the form. (Double-click on the form to bring up the code.) This routine creates the SQL statements for all three tasks and assigns them to the appropriate label for display. Listing 6.11 frmHowTo6_6.vb: Loading the SQL Statements into the Appropriate Labels
Private Sub frmHowTo6_6_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '-- Build the SQL String for Creating a Table Dim strSQL As String strSQL = "CREATE TABLE ListsExample" & vbCrLf strSQL &= "(" & vbCrLf strSQL &= " strSQL &= " strSQL &= " strSQL &= " strSQL &= " strSQL &= " strSQL &= ")" Me.lblCreateTable.Text = strSQL strSQL = "ALTER TABLE ListsExample ADD MyNewColumn varchar(30) " & vbCrLf strSQL &= "ALTER TABLE ListsExample DROP COLUMN Age" ListID smallint IDENTITY(1, 1) " & _ LastName varchar(50) NOT NULL, " & vbCrLf FirstName varchar(50) NOT NULL, " & vbCrLf Age smallint , " & vbCrLf DateEntered datetime NOT NULL DEFAULT GetDate() " & vbCrLf CHECK (DateEntered <= GetDate())" & vbCrLf "PRIMARY KEY CLUSTERED," & vbCrLf
Page 212
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.lblModifyTable.Text = strSQL strSQL = "DROP TABLE ListsExample" Me.lblDeleteTable.Text = strSQL End Sub 3. Add the code in Listing 6.12 to the Click event of the btnCreateTable button. This routine calls the function PerformTask(), passing the text in the lblCreateTable label. PerformTask() is described in the next step. If you perform the task successfully, then a message box is displayed letting you know that all went as it should have. Listing 6.12 frmHowTo6_6.vb: Calling PerformTask() from the btnCreateTable Click Event
Private Sub btnCreateTable_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCreateTable.Click If PerformTask(Me.lblCreateTable.Text) Then MessageBox.Show("Table Created Successfully, " & _ _Look for ListsExample " & "Table in Northwind Database in Server Explorer", _ "Action Performed") End If End Sub 4. In the class module of the form created for this How-To, create the code displayed in Listing 6.13 for the PerformTask() function. This code creates a Connection object. Next, create a Command object that is based on the string passed in strSQL. Open the connection and execute the command. Notice that the execution of the command has been wrapped in the Try..Catch..End Try code block to make sure the command is executed correctly; if it's not, a message is displayed. Listing 6.13 frmHowTo6_6.vb: Executing the SQL Statement Passed in Using strSQL
Function PerformTask(ByVal strSQL As String) As Boolean Dim cnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) Dim cmdAction As New OleDb.OleDbCommand(strSQL) cmdAction.Connection = cnn cnn.Open() PerformTask = True Try
Page 213
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
cmdAction.ExecuteNonQuery() Catch excp As Exception MessageBox.Show(excp.Message, "Error with Action") PerformTask = False End Try cnn.Close() End Function 5. Add the code snippets in Listing 6.14 to the appropriate Click events for btnModifyTable and btnDeleteTable to the Load event of the form. Listing 6.14 frmHowTo6_6.vb: Calling PerformTask from btnModifyTable and
btnDeleteTable Click Events
Private Sub btnModifyTable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModifyTable.Click If PerformTask(Me.lblModifyTable.Text) Then MessageBox.Show("Table Modified Successfully, " & _ Look for ListsExample " & "Table in Northwind Database in Server Explorer", _ "Action Performed") End If End Sub Private Sub btnDeleteTable_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDeleteTable.Click If PerformTask(Me.lblDeleteTable.Text) Then MessageBox.Show("Table Deleted Successfully, " & _ "Look for ListsExample " & "Table in Northwind Database in Server Explorer", _ "Action Performed") End If End Sub Figure 6.7. A common problem with inner joins is retrieving multiple records when you just want to see one per occurrence.
Page 214
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
You don't have to add, modify, and delete tables manually. Just make sure that you back up your data before performing these tasks.
[ Team LiB ]
Page 215
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.7 Create a New Table with Data from Existing Tables
I often need to create new tables from existing data. If the table already exists, I need to delete the old table first. How do I do this using T-SQL?
Technique
To perform these tasks, you will create two T-SQL statements and use them in one Command object. Here are the two statements that will be used:
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'[Northwind].[dbo].[MyProdAndCat]')) DROP TABLE [Northwind].[dbo].[MyProdAndCat] SELECT Categories.CategoryName, Products.ProductName INTO MyProdAndCat FROM Categories INNER JOIN ProductsON Categories.CategoryID = Products.CategoryID"
The first statement checks for the existence of the particular table you will be creating, in this case MyProdAndCat. This statement demonstrates a couple of techniques that you can use in T-SQL:
Using the EXIST statement with a SELECT statement, querying the system table called sysobjects
Using an IF statement to conditionally execute another command, in this case the DROP
TABLE statement
Tip Now that you have learned this technique, you will want to use it repeatedly. Make sure you mark this page!
The last statement uses an inner join to join two tables displaying the CategoryName and ProductName. The clause that creates the new table is this:
INTO MyProdAndCat
This tells SQL Server to create a new table called MyProdAndCat from the SELECT statement that is specified.
Steps
Open and run the Visual Basic .NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.7. You will see the SQL string specified in the "Technique" section displayed in a label. If you click the Execute button, the new table is generated a SELECT statement is executed, and the results are displayed in the DataGrid object (see Figure 6.8). 1. Create a Windows Form. Then place the controls listed in Table 6.7 with the following properties set, as displayed in Figure 6.8.
Page 216
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 6.7. Control Property Settings for This How-To Object Property Setting
Label Label Label
Button
Text Name Text Name Text
SQL Statement lblSQLString Results btnExecute Execute dgResults
DataGrid
2. up the code.)
Name
Add the code in Listing 6.16 to the Load event of the form. (Double-click on the form to bring
Listing 6.16 frmHowTo6_7.vb: Storing the SQL Statement in the lblSQLString Label to Display and Use Later
Private Sub frmHowTo6_7_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Build the SQL String that returns cities that ' have more than one customer in them. Dim strSQL As String strSQL = "IF EXISTS (SELECT * from sysobjects " & vbCrLf strSQL &= " vbCrLf strSQL &= " vbCrLf & vbCrLf strSQL &= "SELECT Categories.CategoryName, Products.ProductName" & vbCrLf strSQL &= "INTO MyProdAndCat" & vbCrLf strSQL &= "FROM Categories INNER JOIN Products" & vbCrLf strSQL &= "ON Categories.CategoryID = Products.CategoryID" Me.lblSQLString.Text = strSQL End Sub 3. Add the following code in Listing 6.17 to the Click event of btnExecute. This code creates DROP Table [Northwind].[dbo].[MyProdAndCat]" & _ WHERE id = object_id(N'[Northwind].[dbo].[MyProdAndCat]'))" & _
Connection and Command objects by using the T-SQL routine discussed in the "Technique" section. Then the code executes the query. Next, a select query is run against the new table, and the DataSource property is set to the data table that was filled.
Listing 6.17 frmHowTo6_7.vb: Loading the Form
Private Sub btnExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExecute.Click Dim dtResults As New DataTable() Try
Page 217
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmd As New OleDb.OleDbCommand(Me.lblSQLString.Text) ocmd.Connection = ocnn ocnn.Open() ocmd.ExecuteNonQuery() ocnn.Close() '-- Use the SQL String to build the data adapter ' and fill the data table. Dim odaResults As _ New OleDb.OleDbDataAdapter("Select * From MyProdAndCat", BuildCnnStr("(local)", "Northwind")) odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property Me.dgResults.DataSource = dtResults End Sub Figure 6.8. These results are based on a new table created by the SQL string that is displayed.
Comments
You will probably want to go ahead and drop the new table after you are finished using it if you don't need to keep it around for any other purposes.
Page 218
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
[ Team LiB ]
Page 219
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 6.8 Create and Call SQL Server 2000 User-Defined Functions
In SQL Server 2000, I have heard that you can create user-defined functions (UDFs). Where would you use UDFs, and how do you create and call them from within T-SQL?
Technique
UDFs have been used for years in application development languages. You can now create them in SQL Server 2000 as well.
Creating SQL Server 2000 UDFs
You can create UDFs in SQL Server 2000 by using the CREATE FUNCTION command. Normally, you would do this using the Enterprise Manager or some tool, but here you will learn how to do it using VB.NET. Following is the function that will be created:
CREATE FUNCTION udf_ShowProdAndCat (@UnitPriceParm money) RETURNS @ProdAndCatTab TABLE ( ProductID int, ProductName nvarchar(80), CategoryName nvarchar(80), UnitPrice int ) AS BEGIN INSERT @ProdAndCatTab SELECT P.ProductID, P.ProductName, C.CategoryName, P.UnitPrice FROM Products AS P INNER JOIN Categories AS C ON P.CategoryID = C.CategoryID WHERE P.UnitPrice > @UnitPriceParm RETURN END
This function definitely looks a lot different from functions you have created in other languages, but it doesn't look as funky when you remember you are using T-SQL commands.
Passing Parameters to SQL Server UDFs
The parameter that is passed starts with the @ symbol, much like local variables that were discussed in How-To 6.1. You will also want to declare the data type.
Returning Scalar or Table Types from SQL Server UDFs
When returning values from a UDF, you will either pass back a scalar type, which is actually a single value of one of the standard data types, or pass back a new Table data type. The example for this How-To creates and returns a Table data type, specified with the following lines of code:
RETURNS @ProdAndCatTab TABLE ( ProductID int, ProductName nvarchar(80),
Page 220
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html CategoryName UnitPrice )
By including the opening and closing parentheses, you can specify and return an entire table's worth of data, but be careful not to because performance would not be good. This is the same as it would be using SQL Server data. You can then use this table that is returned in another T-SQL statement. After establishing the return value, in this case the table ProdAndCatTab, you need to create the body of code for the UDF. Note Although this return value has been called ProdAndCatTab, there is not going to be a table that you can access outside the function by that name. It will just be strictly for use in the calling statement.
nvarchar(80), int
Formatting the Body of Code for SQL Server UDFs
You can see from the block of code that follows that you need to have a BEGIN and END statement:
AS BEGIN INSERT @ProdAndCatTab SELECT P.ProductID, P.ProductName, C.CategoryName, P.UnitPrice FROM Products AS P INNER JOIN Categories AS C ON P.CategoryID = C.CategoryID WHERE P.UnitPrice > @UnitPriceParm RETURN END
Notice also that you will have INSERT @ProdAndCatTab and RETURN statements in there to create the Table return value. The rest of the code is much the same as other T-SQL statements.
Calling SQL Server 2000 UDFs
You can call UDFs from other T-SQL Statements, as displayed here for this How-To:
Select * From udf_ShowProdAndCat(" & Me.txtUnitPrice.Text & ")"
There, the UDF is called in a SELECT statement, and the parameter is passed.
Steps
Open and run the VB.NET Chapter 6 solution. From the main form, click on the button with the caption How-To 6.8 (see Figure 6.9). Figure 6.9. A common problem with inner joins is retrieving multiple records when you want to see only one per occurrence.
Page 221
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You will see the UDF described in the "Technique" section in a label. Click the button labeled Create UDF. If the UDF already exists, then a message box will tell you so. Otherwise, the UDF is created. Next, click the button labeled Use UDF. The data grid is then filled and the data is displayed. You can change the value in the Products Greater Than text box. Then click Use UDF again to see the new data displayed. 1. Create a Windows Form. Then place the controls listed in Table 6.8 with the following properties set, as displayed in Figure 6.9.
Table 6.8. Control Property Settings for This How-To Object Property Setting
Label TextBox Label Label Button
Text Name Text Name Name
Report Products Greater Than: txtUnitPrice SQL Statement Creating Temporary Table lblCreateUDF btnCreateUDF
Page 222
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text Label Label Button Text Name Name Text Label Text
Create UDF SQL Statement Using UDF lblUseUDF btnUseUDF Use UDF Results dgResults
DataGrid Name
2. up the code.)
Add the code in Listing 6.18 to the Load event of the form. (Double-click on the form to bring
Listing 6.18 frmHowTo6_8.vb: Create the UDF Code, and Assign It to a Label for Display and Use Later
Private Sub frmHowTo6_8_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '-- Create the UDF string Dim strSQL As String strSQL = "CREATE FUNCTION udf_ShowProdAndCat ( @UnitPriceParm money)" strSQL &= "RETURNS @ProdAndCatTab TABLE" & vbCrLf strSQL &= "(" & vbCrLf strSQL &= " strSQL &= " strSQL &= " strSQL &= " ProductID ProductName CategoryName UnitPrice int," & vbCrLf nvarchar(80)," & vbCrLf nvarchar(80)," & vbCrLf int" & vbCrLf
strSQL &= ")" & vbCrLf strSQL &= "AS" & vbCrLf strSQL &= "BEGIN" & vbCrLf strSQL &= " strSQL &= " strSQL &= " strSQL &= " vbCrLf strSQL &= " strSQL &= " strSQL &= " strSQL &= "END" ON P.CategoryID = C.CategoryID" & vbCrLf WHERE P.UnitPrice > @UnitPriceParm" & vbCrLf RETURN" & vbCrLf INSERT @ProdAndCatTab" & vbCrLf SELECT P.ProductID, P.ProductName," & vbCrLf C.CategoryName, P.UnitPrice" & vbCrLf FROM Products AS P INNER JOIN Categories AS C" & _
Me.lblCreateUDF.Text = strSQL '-- Create the SQL string that calls the UDF Me.lblUseUDF.Text = "Select * From udf_ShowProdAndCat(" & _ Me.txtUnitPrice.Text & ")"
Page 223
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 3. Add the code in Listing 6.19 to the Click event of btnCreateUDF. This code uses
Connection and Command objects to create the UDF based on the code that is provided.
Listing 6.19 frmHowTo6_8.vb: Creating the New UDF in SQL Server
Private Sub btnCreateUDF_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateUDF.Click Try Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmd As New OleDb.OleDbCommand(Me.lblCreateUDF.Text) ocmd.Connection = ocnn ocnn.Open() ocmd.ExecuteNonQuery() ocnn.Close() Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try MessageBox.Show("UDF Created") End Sub 4. Add the code in Listing 6.20 to the TextChanged event of the button txtUnitPrice. Listing 6.20 frmHowTo6_8.vb: Updating the SELECT Statement That Is Calling the UDF
Private Sub txtUnitPrice_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtUnitPrice.TextChanged Me.lblUseUDF.Text = "Select * From udf_ShowProdAndCat(" & _ Me.txtUnitPrice.Text & ")" End Sub 5. Add the code in Listing 6.21 to the Click event of the button btnUseUDF. This code fills a dataset based on the SELECT statement that calls the UDF. The code then assigns the dataset to the DataSource property of dgResults. Listing 6.21 Displaying Data Using the SELECT Statement in the Text Property of
lblUseUDF
Private Sub btnUseUDF_Click(ByVal sender As System.Object,
Page 224
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal e As System.EventArgs) Handles btnUseUDF.Click Dim dtResults As New DataTable() Try '-- Use the SQL String to build the data adapter ' and fill the data table. Dim odaResults As New OleDb.OleDbDataAdapter(Me.lblUseUDF.Text, BuildCnnStr("(local)", "Northwind")) odaResults.Fill(dtResults) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try '-- Assign the data table to the data grid's DataSource property. Me.dgResults.DataSource = dtResults End Sub
Comments
When you have to use the same T-SQL statements repeatedly, it is handy to be able to store that code somewhere, just like you can do with UDFs you create in Visual Basic. When using UDFs, you can use the value inline and save a number of steps when creating your T-SQL routines.
[ Team LiB ]
Page 225
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 7. Performing Common Database Tasks Using SQL-DMO
In this chapter you will
Create a dialog box to connect to a new database Back up and verify a SQL Server database Restore a SQL Server database Transfer tables between SQL Server databases Create a Detach/Attach SQL Server database dialog box
Regardless of the language you are now using for creating your database applications, if you are using SQL Server for your database, you still need to be able to perform basic database tasks on your back-end database. In addition, you will probably want to give your users the ability to perform these tasks without having to use Enterprise Manager. The way to allow the users to perform some of the common database tasks such as backing up and restoring the database is to take advantage of SQL-Distributed Management Objects (SQL-DMO) and Data Transformation Services (DTS). When you use the Backup/Restore Wizard (see Figure 7.1) in the Enterprise Manager, you are really using SQL-DMO, with the interface created for you. Figure 7.1. Under the covers, the SQL-DMO objects are being used to perform the requested tasks such as backup.
Page 226
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
The same also can be said of the DTS object model, used to create transformation packages and other services (see Figure 7.2.) Figure 7.2. As with SQL-DMO and backing up databases, when exporting data, SQL-DTS objects are used.
As this chapter describes each of the tasks that you will be able to accomplish, you will see more of the various objects, properties, and methods that you can use to accomplish your tasks.
[ Team LiB ]
Page 227
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Looking at the SQL Server DMF APIs
The SQL Distributed Management Framework is a framework of objects, services, and components used to manage Microsoft SQL Server 2000. It is made up of a few APIs that you can use to accomplish tasks in your applications. You can see how these APIs are used in Figure 7.3. Figure 7.3. Under the covers, the SQL-DMO objects are being used to perform the requested tasks.
Following is a brief description of each of the APIs. We will be using the last two directly in the rest of this chapter.
SQL-NS. SQL Namespace provides a way to actually call the Enterprise Managers dialog boxes and User Interface. SQL Namespace uses the other APIs listed.
SQL-DMO. SQL Distributed Management Objects give you access to the various objects within SQL Server, as well as some of the tasks that can be performed using the Enterprise Manager, so that you can perform them within your own application.
SQL-DTS. SQL Data Transformation Services allows you to create transformation packages and tasks, much like you would by using the DTS user interface.
[ Team LiB ]
Page 228
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Setting References in .NET for the SQL APIs
Before you can use the APIs within your .NET application, you need to create a reference to the particular library you are going to use. The libraries you will be using are COM libraries; therefore, you will not have certain benefits of using the .NET Framework, such as some of the performance gains. However, you can still use the libraries. Hopefully, if and when the libraries are updated to the framework, you will be able to convert your code over to use them. To access the necessary libraries, choose Add Reference from the Project menu. Click on the COM tab to display possible COM libraries. Next, click Select after highlighting the following libraries: Microsoft DTSPackage Object Library and Microsoft SQLDMO Object Library. Click OK to close the dialog box. At that point, if you open the Object Browser, you can expand the Interop.SQLDMO library and even highlight the SQL Server object to see the properties and methods available. This is shown in Figure 7.4. Figure 7.4. The objects displayed here are now available for use in your applications.
As you work through the following How-Tos, the various collections, objects, properties, and methods that you will be using will be listed as you need them. So many objects are available that it would take multiple pages to display the whole trees of the SQL-DMO and SQL-DTS object models.
[ Team LiB ]
Page 229
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 7.1 Create a Dialog Box to Connect to a New Database, Including Listing Available SQL Servers and Databases
Users sometimes need to connect to various databases. An example of this is a large company that might keep its site information in separate databases in the same or even different SQL Servers. Management might need to point the application to different site databases, depending on which one it needs to work with. This How-To shows you how to create a dialog box to let the user pick the SQL Server and database and then create a new connection based on the selections. Within a database application, it is necessary to allow users to select a SQL Server back end to which to connect. If you have created my application with the necessary flexibility, you should not have hard-coded SQL Server or database names within my application. How do you create a dialog box that lists available SQL Servers and databases and that the user can utilize to connect to a new database?
Technique
For this How-To, you will be using the base object in SQL-DMO, which is the Application object, and then the SQLServer object. You can use many objects off this object, the first layer of which is shown in Figure 7.5. Figure 7.5. These are just the tip of the iceberg as far as collections and objects used in SQL-DMO.
Page 230
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 7.1 presents the objects, properties, and methods that will be used for this -To. Table 7.1. SQL-DMO Objects Used for Listing SQL Servers, Databases, and Connecting to a Database Object Property/Method Description Collection used to hold the list of available servers
Application NameList
ListAllAvailableServers Method used to retrieve available servers on the
network
SQLServer
Connect
Connection string that connects you to the SQL Server, allowing you access to the databases Flag that specifies that you want to connect to the SQL Server using a trusted connection Collection of databases for the specified SQL Server
LoginSecure
Databases
Page 231
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You will also be using the OleDbConnection object.
Steps
Open and run the VB.NET Chapter 7 solution. From the main Windows form, click on the command button with the caption How-To 7.1. When the form loads, you will see the SQL Servers that are available on your network. If you are not on the network, you will only see a SQL Server called "local." If you click on a SQL Server and you are in fact using the Windows NT Integrated Security, then you will see the list of databases located in the chosen SQL Server. You can then select a database and then click the Connection button. If you are successful, you will see the connection string displayed in the text box at the bottom of the form. The form will then look like the form displayed in Figure 7.6. 1. Create a Windows Form. Then place the controls shown in Figure 7.6 with the following properties set.
Table 7.2. Label, ComboBox, ListBox, and Command Button Control Property Settings Object Property Setting
Label
Name Text
Label1 SQL Servers lstSQLServers Label2 Databases lstDatabases Label3 Connection String txtConnectionString Not Connected btnConnect Connect
ListBox Label
Name Name Text
ListBox Label
Name Name Text
TextBox
Name Text
Command Button
Name Text
Page 232
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
2. As with some of the other chapters' projects, before creating the code that will be attached to the Load event of the form, you need to create a support routine to create the
Connection string. Called BuildCnnStr, the function can be seen in Listing 7.1. This
function takes a server and database names passed to it and returns a connection string. You will want to create a basic module in which to keep the routine. Listing 7.1 modSQLDMORoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, _ ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method would be to pass back a string. The reason for this is that some objects ask for a Connection object, but others just want a string. 3. On the form, add the code in Listing 7.2 to the Load event. Listing 7.2 frmHowTo7_1.vb: Loading SQL Servers into a List Box
Private Sub frmHowTo7_1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Load up the SQL Servers LoadSQLServers(Me.lstSQLServers) End Sub 4. In the same module as step 2, create the routine called LoadSQLServers. After establishing an instance of the SQL-DMO application, the code calls the ListAvailableSQLServer method. If no names are loaded into the oNames namelist object (meaning that they were not available or you weren't on the network), then the (local) server is added to the list box. Otherwise, the list returned is added to the list box. The first item in the list box is then selected, causing the event described in the next step to be executed. Listing 7.3 modSQLDMORoutines.vb: Loading SQL Servers into a List Box
Sub LoadSQLServers(ByRef lstSQLServers As ListBox) Dim intCurrSQL As Integer Dim oNames As SQLDMO.NameList Dim oSQLApp As New SQLDMO.Application() '-- Load available SQL Servers into a NameList
Page 233
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
' (those that are able to be seen by the network)
oNames = oSQLApp.ListAvailableSQLServers '-- Load the local instance as first in the list, if not on the network. If oNames.Count = 0 Then lstSQLServers.Items.Add("(local)") End If '-- Load the namelist into the list box For intCurrSQL = 1 To oNames.Count lstSQLServers.Items.Add(oNames.Item(intCurrSQL)) Next intCurrSQL '-- Choose the first instance lstSQLServers.SelectedIndex = 0 End Sub Note
At this point, if you try to run your sample application, you might get an error that includes the text
QueryInterface for interface SQLDMO.NameList failed. on the ListAvailableSQLServer method. If
this is the case, then you need to install Service Release 2 for SQL Server 2000. This will take care of this problem.
5. Add the code listed in Listing 7.4 to the SelectedIndexChanged event of the list box called lstSQLServers. This routine starts by testing to see whether a SQL Server and database have been selected. If so, the routine enables the btnConnect button; otherwise, the button is disabled. The routine called GetSQLDatabases is then called, passing selected SQL Server and the lstDatabases list box. You can see the GetSQLDatabases routine listed in the next step. Listing 7.4 frmHowTo7_1.vb: Enabling or Disabling the btnConnect Button and Calling the Routine to Load the Database List Box
Private Sub lstSQLServers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstSQLServers.SelectedIndexChanged '-- If both the SQL Server and database are chosen, enable ' the Connect button. lstDatabases.SelectedItems.Count > 0 Then Me.btnConnect.Enabled = True Else Me.btnConnect.Enabled = False End If If lstSQLServers.SelectedItems.Count > 0 And _
Page 234
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) End Sub 6. Create the GetSQLDatabases routine by entering the code in Listing 7.5 to the new module that you created in step 2. The first task that this routine attempts is to connect to the server that is selected. If the routine can't connect, then the function is exited; otherwise, the names of the database that are within the SQL Server are loaded into the list box called lstDatabases. Listing 7.5 modSQLDMORoutines.vb: Retrieving Database Names for a Given SQL Server
Function GetSQLDatabases(ByVal strSQLServer As String, _ ByRef lstTemp As ListBox) Dim intDBs As Integer Dim db As Object Dim strDBs As String '-- Establish a connection to the server. If not, then exit the function. Dim osvr As SQLDMO.SQLServer osvr = New SQLDMO.SQLServer() osvr.LoginSecure = True Try osvr.Connect(strSQLServer) Catch excp As Exception MessageBox.Show("There is a problem retrieving " & _ "databases for this server. " & "Please check the name and try again. ", vbInformation, "Error with Server") Exit Function End Try '-- Clear the current list lstTemp.Items.Clear() '-- Load up the database names for the selected server into the list box. For Each db In osvr.Databases lstTemp.Items.Add(db.Name) Next End Function 7. Add the code from Listing 7.6 to the SelectedIndexChanged event of the lstDatabases list box. This code is similar to the listing in step 4 in that it enables the btnConnect button if an
Page 235
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
item is selected in both the lstSQLServers and lstDatabases list boxes. Listing 7.6 frmHowTo7_1.vb: Repopulating the List Boxes Based on the Current Category Selected
Private Sub lstDatabases_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles lstDatabases.SelectedIndexChanged '-- If both the SQL Server and database are chosen, ' enable the Connect button. lstDatabases.SelectedItems.Count > 0 Then Me.btnConnect.Enabled = True Else Me.btnConnect.Enabled = False End If End Sub 8. Add the code in Listing 7.7 to the Click event of the btnConnect button. In this routine, a If lstSQLServers.SelectedItems.Count > 0 And _
Connection object is instantiated and its Connection string is set to the chosen SQL
Server and database. If the connection has a problem opening, then the Text property of txtConnectionString is set to an error message. Otherwise, the Text property is set to the new connection string. Listing 7.7 frmHowTo7_1.vb: Calling the Routine to Reload the lstUnSelected List Box If This Check Box Is Changed
Private Sub btnConnect_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnConnect.Click Dim ocnn As New OleDb.OleDbConnection() Try '-- Create the connection string and open the connection ocnn.ConnectionString = BuildCnnStr(Me.lstSQLServers.SelectedItem, _ Me.lstDatabases.SelectedItem) ocnn.Open() Catch excp As Exception Me.txtConnectString.Text = "Error with Connection" Exit Sub End Try Me.txtConnectString.Text = ocnn.ConnectionString End Sub
Page 236
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 7.6. This form works great for logging users into a database using Windows NT Integrated Security.
How It Works
When the form opens, the SQL Servers that are available on the network are loaded into the first list box on the form. When the user clicks on a specific SQL Server, then the databases from that SQL Server are loaded into the Databases list box. The user can then select a database from the list. When the user does this, the Connect button is enabled. If the user then clicks on the Connect button, the connect string is loaded into the text box on the bottom of the form.
Comments
Like the others, this How-To is set up to use the Windows NT Integrated Security. If you wanted to use the SQL Server security, you could add text boxes for login name and password and then supply them when calling certain methods such as the Connect method in the code listed in step 6. You would also then set the LoginSecure property used in the same listing to False. This How-To is great for exactly what it does: letting the user (or administrator) pick a new SQL Server and database to connect to if necessary. You can then save this connection string to a Public variable and use it with all your connection objects. You will also be using similar controls and code for the rest of the How-Tos in this chapter.
[ Team LiB ]
Page 237
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 7.2 Back Up and Verify a SQL Server Database
Backing up a database is probably one of the most important features to incorporate into your application. If you leave it up to the user to use the Enterprise Manager to back up the database, then it won't happen. You can arrange to have the backup scheduled, but sometimes you need to back it up at a moment's notice. This How-To shows you how to create a custom dialog box that will allow the user not only to back up your SQL Server database, but also to verify the backup. Your users need to have a method for backing up and verifying their databases without using Enterprise Manager. How do you create a dialog box that would let them back up and verify their databases?
Technique
To accomplish this task, you will once again use the SQL-DMO objects. A couple of the new objects you will use are the Backup and BackupDevices objects. You can see some of the additional objects, along with the properties and methods that will be used, in Table 7.3. Table 7.3. Additional SQL-DMO Objects Used for Backing Up and Verifying a Database Object Property/Method Description This property allows you to specify what type of backup that you want to take place. The choices are SQLDMOBackup_Database,
Backup
Action
SQLDMOBackup_Differential, SQLDMOBackup_Files, and SQLDMOBackup_Log. BackupSetDescription This property allows you to specify a description for the
backup set.
BackupSetName Database
This property is the Backup set name. This property allows you to specify the database to back up. This property specifies the devices you will be backing up to. This method initializes the Backup process. This property allows you to specify how to handle the truncate log when backing up. This method performs the actual backup. This is a collection of backup devices for a SQL Server.
Devices
Initialize TruncateLog
SQLBackup BackupDevices BackupDevice Name ReadBackupHeader
Thisis the name of a specific backup device. This method reads in the header information for a backup, returning a QueryResults object. This is the individual property information about a backup.
QueryResults
ColumnName
Page 238
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
GetColumnString
This is the actual value for individual header information.
Using the objects listed in Table 7.3, you will create a form with options for the user to back up his database and verify the information after it has been saved. Note Not all the possible options will be included in the form created for this How-To. For example, you could allow the user to back up the database to a separate file and give him additional options for the type of backup to perform. Odds are good that you will not want to give the users all the options they could have; that is one of the reasons you want to create the dialog box here instead of letting users use the Enterprise Manager.
Steps
Open and run the VB.NET Chapter 7 solution. From the main Windows form, click on the command
button with the caption How-To 7.2. As with How-To 7.1, a user clicks on the SQL Server that he wants to display the databases of. He can then choose the database and backup device. From there, the user can click the Backup button to perform the backup. You can then click on the verify button to have information about the backup displayed in the text box at the bottom of the form. The form will look similar to the one displayed in Figure 7.7. 1. Create a Windows Form. Then place the controls shown in Figure 7.7, with the following properties set as in Table 7.4.
Table 7.4. Controls and Their Property Settings Object Property Setting
Label
Name Text
Label1 SQL Servers lstSQLServers Label2 Databases lstDatabases Label3 Backup Devices lstBackupDevices btnBackup
ListBox Label
Name Name Text
ListBox Label
Name Name Text
ListBox Command Button
Name Name
Page 239
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text Label Name Text TextBox Name Text Label Name Text Panel Groupbox Name Name Text Radio Button Name Checked Text Radio Button Name Checked Text Groupbox Name Text Radio Button Name Checked Text Radio Button Name Checked Text Radio Button Name Checked
&Backup Label4 Backup Set Name txtBackupSetName MyTestBackup Label5 Options Panel1 grpAction Action rbFull True Full rbIncremental False Incremental grpTruncateLog Truncate Log rbNoLog
True
No Log rbNoTruncate False No Truncate rbTruncate False
Page 240
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text Label Name Text TextBox Name Text Checkbox Name Text TextBox Name Multiline Scrollbars Command Button Name Text Command Button Name Text
2.
Truncate Label5 Backup Set Description txtBackupSetDescription MyTestBackup chkInitialize Initialize? txtVerify True Both btnVerify &Verify btnClose &Close
On the form, add the code in Listing 7.8 to the Load event. This will look familiar to How-To 7.1. For an examination of the LoadSQLServers routine, check out step 4 in that How-To. Listing 7.8 frmHowTo7_2.vb: Calling the Routine That Loads Available SQL Servers into a List Box
Private Sub frmHowTo7_2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '-- Load up the SQL Servers LoadSQLServers(Me.lstSQLServers) End Sub 3. On the lstSQLServers list box, add the code in Listing 7.9 to the SelectedIndexChanged event. This routine calls both the GetSQLDatabases, described in step 6 of How-To 7.1, and GetBackupDevices, described in the next step. Listing 7.9 frmHowTo7_2.vb: Populating the lstDatabases and lstBackupDevices List Boxes
Private Sub lstSQLServers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstSQLServers.SelectedIndexChanged
Page 241
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) GetBackupDevices(Me.lstSQLServers.SelectedItem, Me.lstBackupDevices) End Sub 4. Create the GetBackupDevices routine by entering the code in Listing 7.10 into the new module you created in How-To 7.1. The first task attempted by this routine is to connect to the server that is selected. Next, the names of the backup devices that are within the SQL Server are loaded into the list box called lstBackupDevices. Listing 7.10 modSQLDMORoutines.vb: Retrieving Backup Device Names for a Given SQL Server
Public Sub GetBackupDevices(ByVal strSQLServer As String, _ ByRef lstBackupDevices As ListBox) Dim oDevice As SQLDMO.BackupDevice '-- Log on to the SQL Server. Dim osvr As SQLDMO.SQLServer = New SQLDMO.SQLServer() osvr.LoginSecure = True osvr.Connect(strSQLServer) lstBackupDevices.Items.Clear() '-- Iterate through the backup devices. For Each oDevice In osvr.BackupDevices lstBackupDevices.Items.Add(oDevice.Name) Next End Sub 5. On the btnBackup button, add the code in Listing 7.11 to the Click event. After connecting to the chosen SQL Server, a Backup object is instantiated. Next, certain properties of the
Backup object, called oBackup, are set to values that are specified on the form. The SQLBackup method is called off the Backup object, and the connection is closed. Last, the variables are cleared (set to Nothing) and a message box is displayed.
Listing 7.11 frmHowTo7_2.vb: Performing the Backup
Private Sub btnBackup_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnBackup.Click '-- Create a connection to the server Dim osvr As New SQLDMO.SQLServer() osvr.LoginSecure = True osvr.Connect(Me.lstSQLServers.SelectedItem) '-- Create a Backup object, and set the necessary properties ' based on options chosen on the form.
Page 242
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim oBackup As New SQLDMO.Backup() With oBackup If Me.rbFull.Checked Then .Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database Else .Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Differential End If .BackupSetDescription = Me.txtBUSetDescription.Text .BackupSetName = Me.txtBUSetName.Text .Database = Me.lstDatabases.SelectedItem .Devices = "[" & Me.lstBackupDevices.SelectedItem & "]" If Me.rbNoLog.Checked Then .TruncateLog = _ SQLDMO.SQLDMO_BACKUP_LOG_TYPE.SQLDMOBackup_Log_NoLog ElseIf Me.rbNoTruncate.Checked Then .TruncateLog = _ SQLDMO.SQLDMO_BACKUP_LOG_TYPE.SQLDMOBackup_Log_NoTruncate Else .TruncateLog = _ SQLDMO.SQLDMO_BACKUP_LOG_TYPE.SQLDMOBackup_Log_Truncate End If .Initialize = Me.chkInitialize.Checked '-- Execute the backup .SQLBackup(osvr) End With '-- Disconnect from the server and clean up. osvr.DisConnect() osvr = Nothing oBackup = Nothing MessageBox.Show("Database Backed Up", "Task Completed", _ MessageBoxButtons.OK) End Sub 6. Add the code in Listing 7.12 to the Click event of btnVerify. After connecting to the SQL Server, the code iterates through each of the backup devices for the server and locates the one that the form specifies. After the specific backup device is located, the ReadBackupHeader method is called, with an SQLDMO.QueryResults object returned. Each row of the QueryResults is read, and then the information is displayed in a text box called txtVerifyDisplay. From there, the SQLServer object is disconnected.
Page 243
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 7.12 frmHowTo7_2.vb: Performing the Backup
Private Sub btnVerify_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnVerify.Click Dim oDevice As SQLDMO.BackupDevice Dim oResults As SQLDMO.QueryResults Dim intRowCount As Integer Dim intColCount As Integer '-- Create a connection to the server Dim osvr As New SQLDMO.SQLServer() osvr.LoginSecure = True osvr.Connect(Me.lstSQLServers.SelectedItem) '-- Iterate through the devices For Each oDevice In osvr.BackupDevices If oDevice.Name = Me.lstBackupDevices.SelectedItem Then '-- If found, display the results oResults = oDevice.ReadBackupHeader For intRowCount = 1 To oResults.Rows For intColCount = 1 To oResults.Columns Me.txtVerifyDisplay.Text &= _ oResults.ColumnName(intColCount) & " - " Me.txtVerifyDisplay.Text &= _ oResults.GetColumnString(intRowCount, _ intColCount) & vbCrLf & vbCrLf Next Next End If Next '-- Disconnect and clean up osvr.DisConnect() osvr = Nothing oDevice = Nothing oResults = Nothing End Sub 7. Add the code in Listing 7.13 to the Click event of btnClose. Listing 7.13 frmHowTo7_2.vb: Performing the Backup
Page 244
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub btnClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnClose.Click Me.Close() End Sub Figure 7.7. Creating a form for backing up and verifying a SQL Database gives you control over what options the user has when performing the task.
How It Works
After the form loads, the user can select the SQL Server, database, and backup device. When the user clicks the button labeled Perform Backup, a SQLDMO Backup object is created. The Backup object gives you the same capabilities as if you were using the Enterprise Manager except that you control them. Only put options on the form that you want to have the user set, and then set the other options yourself, as you deem necessary. After setting the options, the SQLBackup method performs the backup. By using the QueryResults object off the BackupDevice, you have a means of looking at some of the properties of the backup and verifying them to make sure the database did indeed get backed up.
Comments
You could enhance this utility in a number of ways, a couple of which include the following:
Page 245
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Add a text box for letting the user specify a filename for the backup, rather than using a backup device.
Allow the user to add backup devices. Currently, only existing backup devices can be used.
Just be careful on what options you give the user so he doesn't shoot himself in the foot.
[ Team LiB ]
Page 246
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 7.3 Restore a SQL Server Database
Sometimes the user needs to restore a database, and again, it is nice if he doesn't have to go to Enterprise Manager to accomplish this task. This How-To explains how to use the Restore object from SQL-DMO to accomplish this task. It's all well and good to be able to back up and verify a SQL Server database, but what about being able to restore the database if necessary? How do you create a dialog box to restore a SQL Server database?
Technique
For this How-To, you will use the Restore object of the SQL-DMO object model. You can see the properties and methods that will be used in Table 7.5. Table 7.5. Properties and Methods of the Restore Object Property/Method Description
Action
This property allows you to specify what type of backup you want to take place. The choices are found in the SQLDMO.SQLDMO_RESTORE_TYPE namespace and are SQLDMORestore_Database, SQLDMORestore_Files,
SQLDMORestore_Log. Database Devices
This property allows you to specify the database name to restore to. This property shows which device(s) you are restoring from.
ReplaceDatabase This property tells whether to replace the database. SQLRestore
This method causes the restore to be executed .
Using the objects listed in Table 7.5, you will create a form with options for the user to restore his database.
Steps
Open and run the VB.NET Chapter 7 solution. From the main Windows Form, click on the command button with the caption How-To 7.3. You will then see the form displayed in Figure 7.8. Figure 7.8. This form restores a SQL Server database.
Page 247
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
As with How-To 7.2, a user clicks on the SQL Server for which he wants to display the databases. He can then choose the database and backup device. From there, the user can click the Restore button to restore the database. 1. Create a Windows Form. Then place the controls shown in Figure 7.8, with the following properties set as in Table 7.6.
Table 7.6. Label, ListBox, DataGrid, and Command Button Controls Property Settings Object Property Setting
Label
Name Text
Label1 SQL Servers lstSQLServers Label2 Databases lstDatabases Label3 Backup Devices lstBackupDevices btnBackup &Backup Label4
ListBox Label
Name Name Text
ListBox Label
Name Name Text
ListBox Command Button
Name Name Text
Label
Name
Page 248
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text Panel CheckBox Name Name Text Checked Command Button Name Text
2.
Options Panel1 chkReplaceDB Replace Database? True btnClose &Close
On the form, add the code in Listing 7.14 to the Load event. This will look familiar from the first How-To. For an examination of the LoadSQLServers routine, check out step 4 in How-To 7.1. Listing 7.14 frmHowTo7_3.vb: Calling the Routine That Loads Available SQL Servers into a List Box
Private Sub frmHowTo7_3_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Load up the SQL Servers LoadSQLServers(Me.lstSQLServers) End Sub 3. On the lstSQLServers list box, add the code in Listing 7.15 to the SelectedIndexChanged event. This routine calls both GetSQLDatabases, described in step 6 of How-To 7.1, and
GetBackupDevices, described in step 4 of How-To 7.2.
Listing 7.15 frmHowTo7_3.vb: Populating the lstDatabases and lstBackupDevices List Boxes
Private Sub lstSQLServers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstSQLServers.SelectedIndexChanged GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) GetBackupDevices(Me.lstSQLServers.SelectedItem, Me.lstBackupDevices) End Sub 4. On the btnRestore button, add the code in Listing 7.16 to the Click event. After logging into the server, the Restore object is created and its properties are set from the form. The
SQLRestore method is invoked and the connection is closed.
Listing 7.16 frmHowTo7_3.vb: Performing the Backup
Private Sub btnRestore_Click(ByVal sender As System.Object, _
Page 249
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal e As System.EventArgs) Handles btnRestore.Click '-- Create a connection to the server Dim osvr As New SQLDMO.SQLServer() osvr.LoginSecure = True osvr.Connect(Me.lstSQLServers.SelectedItem) '-- Create the restore object, set the properties from the form, ' and execute the restore. Dim oRestore As New SQLDMO.Restore() With oRestore .Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database .Database = Me.lstDatabases.SelectedItem .Devices = "[" & Me.lstBackupDevices.SelectedItem & "]" .ReplaceDatabase = Me.chkReplaceDB.Checked .SQLRestore(osvr) End With '-- Disconnect and clean up. osvr.DisConnect() osvr = Nothing oRestore = Nothing MessageBox.Show("Database Restored", "Task Completed", _ MessageBoxButtons.OK) End Sub 5. Add the code in Listing 7.17 to the Click event of btnClose. Listing 7.17 frmHowTo7_3.vb: Performing the Backup
Private Sub btnClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnClose.Click Me.Close() End Sub
How It Works
The Restore object is the counter object to the Backup object, allowing you to restore databases that have been backed up. As with the Backup object, you can either specify the properties yourself or let the user choose them on the form.
Comments
Again, you need to be careful which options you let the user specify and which you specify yourself. This is a utility that you might want to secure; only let an administrator have access to it so that
Page 250
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
users don't accidentally overwrite a good database with an old one. As with the backup, you could enhance this utility by allowing the user to specify a file to restore from instead of a backup device.
[ Team LiB ]
Page 251
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 7.4 Transfer Tables Between SQL Server Databases
Users sometimes need to transfer (copy) tables between SQL Server databases. This How-To shows how to allow the user to choose multiple tables and copy them from one database to another as well as tables from two different databases on two different SQL servers. One of the tasks your clients have you perform for them using the Enterprise Manager is to transfer objects, such as tables, between SQL Server databases. How do you create a dialog box that would allow the user to transfer databases between two SQL Server databases?
Technique
Unlike the earlier How-Tos in this chapter, you will be using the SQL-DTS object model in addition to SQL-DMO. You can see the objects, properties, and methods that will be used from SQL-DTS in Table 7.7. Table 7.7. SQL-DTS Objects That Are Used to Perform the Transfer of Tables from One SQL Server Database to Another Object Property/Method
Package
Steps.New Tasks.New Steps.Add Tasks.Add Execute
Step
TaskName Name
Task CustomTask
CustomTask Name SourceServer SourceUseTrustedConnection SourceDatabase
DestinationServer DestinationUseTrustedConnection DestinationDatabase CopyAllObjects IncludeDependencies IncludeLogins IncludeUsers
Page 252
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DropDestinationObjectsFirst CopySchema CopyData AddObjectForTransfer
Using the items just listed, you will create a form with options to transfer tables between two SQL databases.
Steps
Open and run the VB.NET Chapter 7 solution. From the main Windows form, click on the command button with the caption How-To 7.4. You will then see a form allowing you to pick SQL Servers on the network to transfer from and to. After you have chosen these, you can then select which databases you want to transfer from and to. After choosing from the database to transfer from, you are then presented with a list of tables to transfer from. You can then highlight multiple tables, as shown in Figure 7.9. Figure 7.9. Transferring tables between SQL Server databases.
Tip One of the options included as a property of the CustomTask object is
IncludeDependencies. This option specifies whether to have DTS
transfer related tables as well as the selected table(s). This could be put as an option on the form as well. For this example, I have it set to True.
1.
Create a Windows Form. Then place the controls shown in Figure 7.9, with the following properties set as in Table 7.8.
Table 7.8. Label, ListBox, and Command Button Controls
Page 253
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Property Settings Object Property Setting
Label
Name Text
Label1 From SQL Servers lstFromSQLServer Label2 To SQL Servers lstToSQLServer Label3 Transfer from Database lstFromDB Label4 Transfer to Database lstToDB Label5 Table(s) to Transfer lstTables MultiSimple btnTransfer &Perform Transfer
ListBox Label
Name Name Text
ListBox Label
Name Name Text
ListBox Label
Name Name Text
ListBox Label
Name Name Text
ListBox
Name SelectionMode
Command Button Name Text
2.
On the form, add the code in Listing 7.18 to the Load event. This will look familiar from How-To 7.1. For an examination of the LoadSQLServers routine, check out step 4 in that How-To. Different from the other How-Tos in this chapter thus far, however, is the fact that the LoadSQLServers routine is called twice: once for the lstFromSQLServer, and a second time for the lstToSQLServer. Listing 7.18 frmHowTo7_4.vb: Calling the Routine That Loads Available SQL Servers into a List Box
Private Sub frmHowTo7_4_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load LoadSQLServers(Me.lstFromSQLServer)
Page 254
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
LoadSQLServers(Me.lstToSQLServer) End Sub 3. On the lstFromSQLServer and lstToSQLServer list boxes, add the code in Listing 7.19 to the SelectedIndexChanged event of each, as appropriate. These routines call
GetSQLDatabases, described in step 6 of How-To 7.1.
Listing 7.19 frmHowTo7_4.vb: Populating the lstDatabases and lstBackupDevices List Boxes
Private Sub lstFromSQLServer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstFromSQLServer.SelectedIndexChanged GetSQLDatabases(Me.lstFromSQLServer.SelectedItem, Me.lstFromDB) End Sub Private Sub lstToSQLServer_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles lstToSQLServer.SelectedIndexChanged GetSQLDatabases(Me.lstToSQLServer.SelectedItem, Me.lstToDB) End Sub 4. On the lstFromTables list box, add the code in Listing 7.20 to the SelectedIndexChanged event. This routine starts off by logging onto the server that is selected in the lstFromSQLServer list box, and then creates a reference to the database that is selected in the lstFromDB list box. After clearing the lstTables list box, the routine iterates through each of the tables in the database and adds the names of those that are user tables to the lstTables items. Listing 7.20 frmHowTo7_4.vb: Populating the lstDatabases and lstBackupDevices List Boxes
Private Sub lstFromDB_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstFromDB.SelectedIndexChanged '-- Create the connection and specify the stored procedure to use. Dim odb As SQLDMO.Database Dim otbl As SQLDMO.Table Dim oapp As New SQLDMO.Application() Dim osvr As New SQLDMO.SQLServer() Try osvr.LoginSecure = True osvr.Connect(Me.lstFromSQLServer.SelectedItem) odb = osvr.Databases.Item(Me.lstFromDB.SelectedItem) Me.lstTables.Items.Clear()
Page 255
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
For Each otbl In odb.Tables If otbl.TypeOf = _ SQLDMO.SQLDMO_OBJECT_TYPE.SQLDMOObj_UserTable Then Me.lstTables.Items.Add(otbl.Name) End If Next Catch excpData As Exception MessageBox.Show("Error Occurred: " & excpData.Message) End Try
End Sub Tip
You could really make this a flexible and powerful utility by including different objects to transfer other than just user tables. Some examples could be stored procedures or views.
5. On the lstTables list box, add the code in Listing 7.21 to the SelectedIndexChanged event. This routine enables the btnTransfer button. Listing 7.21 frmHowTo7_4.vb: Performing the Transfer of Tables
Private Sub lstTables_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstTables.SelectedIndexChanged Me.btnTransfer.Enabled = True End Sub 6. Add the code in Listing 7.22 to the Click event of btnTransfer. This routine begins by declaring all the objects to be used, and then creates new Step and Task objects, with the type of task being specified. In this case, the task is of type DTSTransferObjectsTask. Next, the various necessary properties are set on the Task object. For each of the tables to be transferred, the AddObjectForTransfer method is executed, with the name of the table being passed to the method. After the name of the task is added to the step, both objects are added to their collections in the Package object. The Execute method of the
Package object is then called.
Listing 7.22 frmHowTo7_4.vb: Performing the Transfer of Tables
Private Sub btnTransfer_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnTransfer.Click Dim oPackage As New DTS.Package() Dim oStep As DTS.Step Dim oTask As DTS.Task Dim oXferObj As DTS.TransferObjectsTask
Page 256
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim intCurrTable As Integer Try '-- Create step and task oStep = oPackage.Steps.New oTask = oPackage.Tasks.New("DTSTransferObjectsTask") oXferObj = oTask.CustomTask '-- Configure transfer objects task With oXferObj .Name = "XferObjTask" .SourceServer = Me.lstFromSQLServer.SelectedItem .SourceUseTrustedConnection = True .SourceDatabase = Me.lstFromDB.SelectedItem .DestinationServer = Me.lstToSQLServer.SelectedItem .DestinationUseTrustedConnection = True .DestinationDatabase = Me.lstToDB.SelectedItem .CopyAllObjects = False .IncludeDependencies = True .IncludeLogins = False .IncludeUsers = False .DropDestinationObjectsFirst = False .CopySchema = True .CopyData = DTS.DTSTransfer_CopyDataOption.DTSTransfer_AppendData For intCurrTable = 0 To Me.lstTables.SelectedItems.Count - 1 .AddObjectForTransfer( _ Me.lstTables.SelectedItems.Item(intCurrTable), "dbo", DTS.DTSSQLObjectType.DTSSQLObj_UserTable) Next End With '-- Link step to task oStep.TaskName = oXferObj.Name oStep.Name = "XferObjStep" oPackage.Steps.Add(oStep) oPackage.Tasks.Add(oTask) oPackage.Execute() Catch excp As Exception MessageBox.Show(excp.Message, "Error Occurred") Exit Sub
Page 257
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Try MessageBox.Show("Tables Transferred") End Sub 7. Add the code in Listing 7.23 to the Click event of btnClose. Listing 7.23 frmHowTo7_4.vb: Closing the Form
Private Sub btnClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnClose.Click Me.Close() End Sub
How It Works
Using the Data Transformation Services API requires a bit more work than just using SQL-DMO. To use SQL-DTS, you need to also have a concept of using workflow. Workflow allows you to specify steps in a package and assign tasks to those steps. Task objects that are not assigned to steps can be included in the package, but they will not be executed. You can see an example of multiple tasks being performed by the arrows in the package in Enterprise Manager (see Figure 7.10). Figure 7.10. This DTS package has multiple tasks that are being performed and shows workflow.
This example is simple in that it has only one step and task. For more information on using workflow and DTS packages, check out SQL Server's Books On-Line, and look up "workflow." As you create each of the tasks, you will have to set the various properties that are necessary to perform the tasks. The source and destination servers and databases are examples of this.
Comments
As mentioned, using DTS takes a bit more work to understand than DMO, but after you understand what needs to be done, there is little you can't perform using it.
Page 258
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
Page 259
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 7.5 Create a Detach/Attach SQL Server Database Dialog Box
Situations sometimes arise that require a database to be attached, detached, or both. Perhaps your client needs to move the database from one SQL Server to another. This How-To shows you the methods you can use to perform these tasks. Before diving into solving some of the tasks that can be accomplished in the How-Tos just listed, it's important to discuss the SQL-DMO object model, as well as create a reference to it. Many times, you've used the Enterprise Manager to move databases for users by attaching and detaching them. It would be nice to be able to perform this task without users calling you. At he very least, you'd like to be able to walk users through the details over the phone, without having to use the Enterprise Manager. How do you create a dialog box to perform this task?
Technique
This is probably the easiest of the How-Tos to create for this chapter, other than How-To 7.1. For this task, you will be using two methods of the SQLServer object: DetachDB and
AttachDBWithSingleFile.
Along with the two methods just mentioned, you will also be using a Tab control to choose which task to perform, as well as an OpenFile Dialog control to allow the user to choose the file to attach.
Steps
Open and run the VB.NET Chapter 7 solution. From the main Windows form, click on the command button with the caption How-To 7.5. You can select a database, such as the one displayed in Figure 7.11, and click the Detach button. You will see the database disappear from the list of databases to choose from. Figure 7.11. Ready to detach the chosen database.
After you have chosen the database, you can reattach the database by clicking on the tab labeled Attach Database. You can then type in the name you want to attach the database as, and click on the Locate File button to locate the database file to attach (see Figure 7.12.) Figure 7.12. Choosing the database file to attach.
Page 260
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Select the file and click Open. To attach the file, click the Attach Database button. The database file will then be attached, and you can see it in the list of databases. To check this, you can look at the list back on the Detach Database tab; that list was refreshed when you clicked the Attach Database button. 1. 2. Create a Windows Form. Add a Tab control from the Windows Form Controls list. Click the builder button in the Tab Pages property, and add two pages. Set the Text property for Page1 to Detach Database, and the Text property for Page2 to Attach Database. 3. Add an OpenFileDialog control from the Windows Form Controls list. Go ahead and leave the default name given to the control, but make a note of it. 4. Place the other controls shown in Figure 7.10 and 7.11, with the following properties set as in Table 7.9.
Table 7.9. Label, ListBox, and Command Button Controls Property Settings Object Location Property Setting
Label
Main Form
Name Text
Label1 SQL Servers lstSQLServers Label2 Databases lstDatabases btnDetach
ListBox Label
Main Form Main Form
Name Name Text
ListBox Button
Tab Page1 Tab Page1
Name Name
Page 261
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text Label Tab Page2 Name Text TextBox Label Tab Page2 Tab Page2 Name Name Text TextBox Button Tab Page2 Tab Page2 Name Name Text Button Tab Page2 Name Text
5.
&Detach Database Label3 File to Attach txtFileToAttach Label4 Name of Attached Database txtNameOfAttach btnLocate &Locate File btnAttach &Attach Database
On the form, add the code in Listing 7.24 to the Load event. This will look familiar from How-To 7.1. For an examination of the LoadSQLServers routine, check out step 4 in that How-To. Listing 7.24 frmHowTo7_5.vb: Calling the Routine That Loads Available SQL Servers into a List Box
Private Sub frmHowTo7_5_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load LoadSQLServers(Me.lstSQLServers) End Sub 6. On the lstSQLServers list box, add the code in Listing 7.25 to the SelectedIndexChanged event. This routine toggles the btnDetach button, depending on whether a SQL Server and database has been selected. It then calls GetSQLDatabases, described in step 6 of How-To 7.1. Listing 7.25 frmHowTo7_5.vb: Populating the lstDatabases List Boxes
Private Sub lstSQLServers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstSQLServers.SelectedIndexChanged If lstSQLServers.SelectedItems.Count > 0 And _ lstDatabases.SelectedItems.Count > 0 Then Me.btnDetach.Enabled = True Else Me.btnDetach.Enabled = False
Page 262
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End If GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) End Sub 7. On the lstDatabases list box, add the code in Listing 7.26 to the SelectedIndexChanged event. This routine toggles the btnDetach button, depending on whether a SQL Server and database have been selected. Listing 7.26 frmHowTo7_5.vb: Toggling the btnDetach Button Based on Whether a SQL Server and Database Have Been Chosen
Private Sub lstDatabases_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstDatabases.SelectedIndexChanged If lstSQLServers.SelectedItems.Count > 0 And _ lstDatabases.SelectedItems.Count > 0 Then Me.btnDetach.Enabled = True Else Me.btnDetach.Enabled = False End If End Sub 8. On the btnDetach button, add the code in Listing 7.27 to the Click event. After connecting to the server, the DetachDB method is called. Then the GetSQLDatabases routine is called to refresh the database list. Listing 7.27 frmHowTo7_5.vb: Detaching a SQL Server Database
Private Sub btnDetach_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDetach.Click Dim oSQLSvr As New SQLDMO.SQLServer() Dim strDetachMsg As String Try '-- Connect to the server oSQLSvr.LoginSecure = True oSQLSvr.Connect(Me.lstSQLServers.SelectedItem) '-- Perform the detach strDetachMsg = oSQLSvr.DetachDB(Me.lstDatabases.SelectedItem) '-- Refresh the databases GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) Catch excp As Exception
Page 263
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
MessageBox.Show(excp.Message) Exit Sub End Try MessageBox.Show("Database Detached") End Sub 9. Add the code in Listing 7.28 to the Click event of btnLocateFile. This routine uses the
OpenFileDialog control to retrieve the name of the file you want to attach.
Listing 7.28 frmHowTo7_5.vb: Locating the Database File to Attach
Private Sub btnLocateFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLocateFile.Click With OpenFileDialog1 .InitialDirectory = _ "E:\Program Files\Microsoft SQL Server\MSSQL\Data\" .Filter = "SQL Server Database files (*.mdf)|*.mdf" .ShowDialog() Me.txtFileToAttach.Text = .FileName End With End Sub 10. Add the code in Listing 7.29 to the TextChanged event of txtFileToAttach and
txtNameToAttach as appropriate.
Listing 7.29 frmHowTo7_5.vb: Closing the Form
Private Sub txtFileToAttach_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFileToAttach.TextChanged If Len(Me.txtFileToAttach.Text) > 0 And _ Len(Me.txtNameOfAttach.Text) > 0 Then Me.btnAttach.Enabled = True Else Me.btnAttach.Enabled = False End If End Sub Private Sub txtNameOfAttach_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNameOfAttach.TextChanged If Len(Me.txtFileToAttach.Text) > 0 And _ Len(Me.txtNameOfAttach.Text) > 0 Then Me.btnAttach.Enabled = True Else Me.btnAttach.Enabled = False
Page 264
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End If End Sub 11. Add the code in Listing 7.30 to the Click event of btnAttach. After connecting to the server, this code calls the AttachDBWithSingleFile method. Then it refreshes the database list using the routine GetSQLDatabases. Listing 7.30 frmHowTo7_5.vb: Attaching a SQL Server Database
Private Sub btnAttach_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAttach.Click Dim oSQLSvr As New SQLDMO.SQLServer() Dim strAttachMsg As String Try oSQLSvr.LoginSecure = True oSQLSvr.Connect(Me.lstSQLServers.SelectedItem) '-- Attach the database strAttachMsg = oSQLSvr.AttachDBWithSingleFile( _ Me.txtNameOfAttach.Text, Me.txtFileToAttach.Text) '-- Refresh the databases GetSQLDatabases(Me.lstSQLServers.SelectedItem, Me.lstDatabases) Catch excp As Exception MessageBox.Show(excp.Message) Exit Sub End Try MessageBox.Show("Database Attached") End Sub
How It Works
This How-To uses the DetachDB and AttachDBWithSingleFile methods to attach and detach a database.
Comments
You can enhance this routine by allowing for databases that have multiple files to be attached and detached. There is so much you can do with the APIs that SQL Server provides. Open the Enterprise Manager and look at some of the various utilities, including Data Transformation Services. Then open the Object Browser to the SQL-DMO and SQL-DTS libraries, and notice the correlation between tasks that are displayed using the Enterprise Manager and the APIs.
[ Team LiB ]
Page 265
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Page 266
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 8. Taking Advantage of Data-Driven Techniques
In this chapter you will
Work with data-bound multi-select list boxes using Windows Forms Use a single Windows Form to update multiple lookup tables Create a point-and-click query tool for users using a Windows Form Make a generic search form in a Visual Basic .NET desktop application Work with data-bound multi-select list boxes using Web Forms Use a single Web Form to update multiple lookup tables Create a point-and-click query tool for users using a Web Form Make a generic search form in an ASP.NET Web application
Whenever you are working with databases, whether with Visual Basic .NET or other languages, an efficient method of development is to use data-driven techniques. The term data driven can mean different things. Sometimes people have data-driven applications by having all the options stored in tables and the interface driven from those tables. You can also make an application, or portions of it, be data driven through other methods. Some of the ways are outlined here in this chapter, along with this first one, which discusses using multi-select list boxes in Visual Basic .NET. One of the benefits of using data-driven techniques is that you usually end up with the smaller code base, especially if you use the technique for more than one task. An example of this is the search form example in How-To 8.4 (for Windows Forms) and How-To 8.8 for the Web Form version. You can see the Windows Form version of this technique used with the Customers table in Northwind in Figure 8.1. Figure 8.1. This particular form can be called for searching different record sources.
Page 267
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
As with other data-driven techniques, although this form is shown being used with the Customers table, with just four lines of code-setting custom properties on this form, you can use it with just about any other tables, such as Suppliers. The more you use a specific technique in your application, such as this search form, the bigger benefit you receive in terms of number of lines of code and objects that are added to the application. Note Make a note that this is a techniques chapter. By now, you should be pretty familiar with all the objects and should be seeing new ways to use those objects.
Note The solution for this chapter has been broken up into two projects, a Visual Basic .NET project called VB.NET Chapter 8, which covers How-Tos 8.1 8.4. The rest of the How-Tos in this chapter are in an ASP.NET project called VBNetHowToChap8Web. As with the code, this chapter could be started in two different chapters, depending on whether you wanted to use the techniques for Visual Basic .NET or ASP.NET. If you want the desktop solutions, start with How-To 8.1; for the Web, you can start with How-To 8.5.
Note This chapter is split up to cover data-driven techniques using both Windows Forms and Web Forms. These techniques are useful in both
Page 268
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
areas. In addition, they are different enough in the way they are coded that they warranted separate How-Tos for each technique and environment.
[ Team LiB ]
Page 269
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.1 Work with Data-Bound Multi-Select List Boxes Using Windows Forms
It is common to have to assign products to categories, which is a one-to-many relationship. Sometimes you want to be able to do this in a somewhat bulk fashion. One of the methods that works well is using the ListBox control. Using the ListBox control for single selections is no big deal, but when it comes to using it in a multi-select method, it starts getting trickier. This How-To shows you how to create an intuitive interface for assigning products to categories using a couple of multi-select list boxes on a Windows Form. You can assign a category to each product, but you would like to have a method of maintaining all the products for a category at one time. How do you take advantage of a multi-select list box to perform this task?
Technique
Using the ListBox control in regular single selection mode is as straightforward in .NET as in prior versions of Visual Basic. The same can be said in the case of using the multi-select mode of list boxes. It is as confusing in .NET as it was in prior versions. Using the ListBox control in single entry mode is pretty straightforward. You just need to use the
SelectedItem property with the index of 0. However, if you want to use the ListBox control in
multi-select mode, then you must perform some more work and access some other properties (see Table 8.1). Table 8.1. Properties Having to Do with Multi-Selection on ListBox Controls (In Order of Use in This How-To's Steps) Property/Object Description Property of the ListBox control. The settings for this are None, One,
SelectionMode
MultiSimple, or MultiExtended. SelectedIndices (index A collection of the ListBox control, this returns the indices (location in )
the list) of all the selected items.
SelectedIndices.Count Property of the ListBox control. A count of the number of items
selected in the list box.
DataRowView Items (index)
Object type that the data provider provides. A collection of the ListBox control. Returns a DataRowView type object. If you have multiple columns, they are also returned in the DataRowView object.
Steps
Open and run the VB.NET Chapter 8 solution. From the main Windows Form, click on the command button with the caption How-To 8.1. You will then see the form displayed in Figure 8.2. Figure 8.2. This form uses controls bound at runtime and takes advantage of multi-select list boxes.
Page 270
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When the form loads, you will see the Beverages category chosen in the top combo box. The Selected and Unselected Products ListBox controls are filled in with the appropriate products. If you click on a product in the Unselected Products list box and then click on the arrow button pointing to the right (>), then the item is moved to the Selected Products list box. If you select items in the Selected Products list box and click on the arrow button pointing to the left (<), those items are moved to the Unselected Products list box. If you click on the Unassigned Products Only check box located at the bottom of the form, then the Unselected Products list box is filled with products that are not assigned to any category. Note If you check the Unassigned Products Only check box when you're first getting into Northwind and running this example, you probably won't see unassigned items. You will need to unselect products from a category.
1.
Create a Windows Form. Then place the controls shown in Figure 8.2 with the following properties set in Table 8.2.
Table 8.2. Label, ComboBox, ListBox, and Command Button Control Property Settings Object Property Setting
Label ComboBox Label ListBox
Text Name Text Name SelectionMode
Category cboCategories Unselected Products lstUnSelected MultiSimple
Page 271
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label ListBox
Text Name SelectionMode
Selected Products lstSelected MultiSimple btnSelect
Command Button
Name
Text Command Button Name
> btnUnSelect
Text CheckBox Name Text
2.
< chkUnAssignedOnly UnAssigned Products Only
As with some of the other chapters' projects, before creating the code that will be attached to the Load event of the form, you need to create a support routine to create the Connection string. Called BuildCnnStr, the function can been seen in Listing 8.1. This function takes a server and database names passed to it and creates a connection string. Listing 8.1 modGeneralRoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method would be to pass back a string. Some objects ask you for a Connection object, but others just ask for a string. You will see BuildCnnStr called in the next step. 3. On the form, add the code in Listing 8.2 to the Load event. In this code, you will start off by creating a data adapter called odaCategories and loading the category's SQL Statement into it. The dtCategories data table is then filled and set as the DataSource property of cboCategories. The DisplayMember and ValueMember of cboCategories are then set. Finally, two new subroutines called LoadUnSelectedProducts and
LoadSelectedProducts are called to populate the appropriate list boxes. These routines
are discussed in the next two steps. Listing 8.2 frmHowTo8_1.vb: Loading Categories into the List Box
Page 272
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private Sub frmHowTo8_1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim odaCategories As OleDb.OleDbDataAdapter Dim dtCategories As New data table() '-- Load the Categories combo box up first odaCategories = New _ OleDb.OleDbDataAdapter( _ "Select CategoryID, CategoryName From Categories", (BuildCnnStr("(local)", "Northwind"))) odaCategories.Fill(dtCategories) Me.cboCategories.DataSource = dtCategories Me.cboCategories.DisplayMember = "CategoryName" Me.cboCategories.ValueMember = "CategoryID" '-- Load each of the product list boxes based on the selected category. LoadUnSelectedProducts() LoadSelectedProducts() End Sub 4. Create the LoadUnSelectedProducts routine by entering the code shown in Listing 8.3 into the form you created for this example. This routine starts off by testing the check box called chkUnAssignedOnly. Based on that value, a SQL string is created that grabs the products that are not assigned to any product, if chkUnAssignedOnly = True. All products that are not assigned to the chosen category are retrieved. The SQL String is stored in the variable called strSQL. Next, the DataAdapter object called odaUnselected is set to strSQL and the SQL Server connection string. The DataTable object called
dtUnSelected is then filled and assigned to the list box called lstUnSelected. The DisplayMember and ValueMember properties are then set. Last, the ClearSelected
method is called to make sure no entries remain selected. Listing 8.3 frmHowTo8_1.vb: Populating the List Box Displaying Unselected Products
Sub LoadUnSelectedProducts() Dim odaUnSelected As OleDb.OleDbDataAdapter Dim dtUnSelected As New DataTable() Dim strSQL As String '-- If the check box for Unassigned Only is checked, then ' ' grab the product items where the category is null; otherwise, load it up with those products not assigned to the current category.
If chkUnAssignedOnly.Checked Then strSQL = "Select ProductID, ProductName From Products " & _ " Where CategoryID IS NULL Order By ProductName"
Page 273
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Else strSQL = "Select ProductID, ProductName From Products " & _ "Where CategoryID <> " & _ Me.cboCategories.SelectedItem(0) & " Or CategoryID IS NULL Order By ProductName" End If '-- Pretty well same old, same old here. Create a data adapter ' ' and fill the dataset. Next, bind it to the list box.
odaUnSelected = New OleDb.OleDbDataAdapter(strSQL, (BuildCnnStr("(local)", "Northwind"))) odaUnSelected.Fill(dtUnSelected) Me.lstUnSelected.DataSource = dtUnSelected Me.lstUnSelected.DisplayMember = "ProductName" Me.lstUnSelected.ValueMember = "ProductID" Me.lstUnSelected.ClearSelected() End Sub 5. Create the LoadSelectedProducts routine by entering the code in Listing 8.4 into the form you created for this tutorial. This routine performs basically the same tasks that the routine listed in the previous step does, except that it performs the tasks using the lstSelected ListBox control. It also doesn't need to test the CheckBox control. Listing 8.4 frmHowTo8_1.vb: Populating the List Box Displaying Selected Products
Sub LoadSelectedProducts() Dim odaSelected As OleDb.OleDbDataAdapter Dim dtSelected As New DataTable() Dim strSQL As String '-- Load the products assigned to this category. strSQL = _ "Select ProductID, ProductName From Products Where CategoryID = " & Me.cboCategories.SelectedItem(0) & " Order By ProductName" odaSelected = New _ OleDb.OleDbDataAdapter(strSQL, (BuildCnnStr("(local)", "Northwind"))) odaSelected.Fill(dtSelected) Me.lstSelected.DataSource = dtSelected Me.lstSelected.DisplayMember = "ProductName" Me.lstSelected.ValueMember = "ProductID"
Page 274
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.lstSelected.ClearSelected() End Sub 6. Add the code in Listing 8.5 to the SelectedIndexChanged event of the cboCategories combo box. Listing 8.5 frmHowTo8_1.vb: Repopulating the List Boxes Based on the Current Category That Is Selected
Private Sub cboCategories_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCategories.SelectedIndexChanged '-- Load each of the product list boxes based on the selected category. LoadUnSelectedProducts() LoadSelectedProducts() End Sub 7. Add the code in Listing 8.6 to the CheckChanged event of the chkUnAssignedOnly check box. Listing 8.6 frmHowTo8_1.vb: Call the Routine to Reload the lstUnSelected List Box If This Check Box Is Changed
Private Sub chkUnAssignedOnly_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkUnAssignedOnly.CheckedChanged LoadUnSelectedProducts() End Sub 8. Add the code in Listing 8.7 to the Click event of the btnSelect command button. This and the next step contain the most code as well as some new objects and properties. The first thing that happens is that the number of highlighted items (SelectedIndices.Count) is stored to an Integer variable called intItemsNum. One is subtracted from the figure because the collections in .NET are zero based. Next, the code iterates through the SelectedItems collection of the lstUnSelected list box, and using the indices in that collection, the code accesses selected items. The type of object derived from the Items collection is the DataRowView object, mentioned in the "Techniques" section of this example. These items are then added to a string variable called strItems, which is then used to create the criteria for an IN clause of a SQL Update statement. This statement is passed to the Command object called ocmdSelect. This Command object is then executed, and the selected products are updated to reflect the category chosen. Last, the list boxes are reloaded to reflect the changes. Listing 8.7 frmHowTo8_1.vb: Updating the Server with Products Selected for the Given Category
Private Sub btnSelect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelect.Click
Page 275
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim intItemsNum As Integer Dim intCurr As Integer Dim strItems As String Dim drv As DataRowView '-- Grab the number of selected items for the products ' unselected list box. intItemsNum = Me.lstUnSelected.SelectedIndices.Count - 1 '-- Iterate through each of the items and create a string. For intCurr = 0 To intItemsNum If Len(strItems) > 0 Then strItems = strItems & ", " End If drv = Me.lstUnSelected.Items(Me.lstUnSelected. _ SelectedIndices(intCurr)) strItems = strItems & CType(drv(0), String) Next '-- Run an update query to assign the category to the desired products '-- using an IN clause in the SQL statement Try Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) Dim ocmdSelect As New _ OleDb.OleDbCommand("Update Products Set CategoryID = " & Me.cboCategories.SelectedItem(0) & _ " Where ProductID IN (" & strItems & ")", ocnn) ocmdSelect.CommandType = CommandType.Text ocnn.Open() ocmdSelect.ExecuteNonQuery() Catch excpCommand As Exception MessageBox.Show(excpCommand.Message) End Try LoadUnSelectedProducts() LoadSelectedProducts() End Sub 9. Add the code in Listing 8.8 to the Click event of the btnUnSelect command button. Again, this code is similar to the previous step, but it is used to set the CategoryID column to null if
Page 276
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
the product was highlighted in the lstSelected list box and btnUnSelect was clicked. Listing 8.8 frmHowTo8_1.vb: Updating the Server with Products That Are Unselected for the Given Category
Private Sub btnUnSelect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUnSelect.Click Dim intItemsNum As Integer Dim intCurr As Integer Dim strItems As String Dim drv As DataRowView '-- Grab the number of selected items for the products ' selected list box. intItemsNum = Me.lstSelected.SelectedIndices.Count - 1 '-- Iterate through each of the items and create a string. For intCurr = 0 To intItemsNum If Len(strItems) > 0 Then strItems = strItems & ", " End If drv = Me.lstSelected.Items(Me.lstSelected.SelectedIndices(intCurr)) strItems = strItems & CType(drv(0), String) Next Try Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmdUnSelect As New OleDb.OleDbCommand( "Update Products Set CategoryID = Null Where ProductID IN (" & strItems & ")", ocnn) ocmdUnSelect.CommandType = CommandType.Text ocnn.Open() ocmdUnSelect.ExecuteNonQuery() Catch excpCommand As Exception MessageBox.Show(excpCommand.Message) End Try LoadUnSelectedProducts() LoadSelectedProducts() End Sub
How It Works
When the user chooses a category, the appropriate items are loaded into the two list boxes;
Page 277
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
unselected items are placed in the list box on the left, and selected items are placed in the list box on the right. If the check box is selected, then only those items that are not currently assigned to a category are displayed in the list box on the left, which is titled Unselected Products. When the btnSelect button is clicked, any items highlighted in the lstUnSelected list box are used in a query that updates the server with the new category they now belong to. Similarly, when the btnUnSelect is clicked, items in the lstSelected list box are used in a query that updates the CategoryID of the products to null.
Comments
This example is not the smartest to create in real life because you want products to be assigned to a category. However, this example does a good job of showing the properties and methods you can use to work with the multi-select features of the ListBox control. For examples of using this same basic technique in a Web Form, check out example 8.5.
[ Team LiB ]
Page 278
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.2 Use a Single Windows Form to Update Multiple Lookup Tables
Just about every database application uses lookup tables of some sort or another, such as categories, regions, and territories in the Northwind database. Normally, each of these lookup tables would get its own form for viewing or updating the information in the tables. This example will provide the means for you to create a single form to maintain any of your simple lookup tables, again using a Windows Form. You have a number of simple lookup tables in your application, and it is a pain to have to create a form for each table. How do you create a Windows Form that can be used to update most if not all of your lookup tables that are contained in your database?
Technique
Using two main controls, the ListBox control and DataGrid control, you can create a form that will take care of most of your simple lookup tables. When you get into those tables that contain lookups or graphics, you will have to come up with a more complete method to modify the data. For this example, you will be using some familiar friends: DataAdapter, CommandBuilder, and
DataTable objects. Steps
Open and run the VB.NET Chapter 8 solution. From the main Windows Form, click on the command button with the caption How-To 8.2. You will then see the form displayed in Figure 8.3. Figure 8.3. The DataGrid control is filled with different data every time a new item is chosen in the ListBox control.
When you choose a new item from the list of tables on the left, the data grid on the right becomes filled with the data from the chosen table. You can then modify the data in the data grid and click on the Update button to update the data back to the server. This includes modifying existing records, as well as adding and deleting records in the DataGrid control. 1. Create a Windows Form. Then place the controls shown in Figure 8.3 with the properties set forth in Table 8.3.
Table 8.3. Label, ListBox, DataGrid, and Command Button Controls Property Settings
Page 279
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Object
Property
Setting
Label
Name Text
Label1 Lookup Table to Edit Label2 Lookup Table Data lstLookupTables dgTableData btnUpdate
Label
Name Text
ListBox DataGrid Button
2.
Name Name Name
Add data to the Items collection of lstLookupTables. To do this, click on the builder button beside the Items property in the property sheet for lstLookupTables. You will then see the String Collection Editor as shown in Figure 8.4. The Items you will add include Categories, Region, and Territories. Figure 8.4. Adding hard-coded items at design is pretty straightforward using this dialog box.
Note
To make this example truly "data driven," you would want to either keep these table names in a table by themselves and set the data source of lstLookupTables to that table, or generate the list at runtime by naming
Page 280
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
your lookup tables a specific way. These values are hard coded for the sake of expediency and so that no more tables are added to Northwind.
3. In the class module for the form, add the following Private declarations just below the line of code that reads Windows Form Designer generated code.
4. 5. 6. Dim mcnn As New OleDb.OleDbConnection() Dim modaLookupData As OleDb.OleDbDataAdapter These lines of code declare Connection and DataAdapter objects that will be used throughout the form. 7. On the form, add the code in Listing 8.9 to the Load event. Listing 8.9 frmHowTo8_2.vb: Establishing the Connection String and Pointing to the First Item in lstLookupTables
Private Sub frmHowTo8_2_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Initialize the connection string. mcnn.ConnectionString = BuildCnnStr("(local)", "Northwind") '-- Point to the first lookup table; this fires ' the SelectedIndexChanged event off the list box.
Me.lstLookupTables.SelectedIndex = 0 End Sub 8. On the lstLookupTables list box, add the code in Listing 8.10 to the
SelectedIndexChanged event. This routine assigns the new table chosen in lstLookupTables as the Select command for the modaLookupData data adapter. The data
table called dtData is then filled and set as the data source for dgTableData. Listing 8.10 frmHowTo8_2.vb: Populating the DataGrid Control
Private Sub lstLookupTables_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstLookupTables.SelectedIndexChanged Dim dtData As New DataTable() Try '-- Update the data adapter and data table to reflect the new data, ' and reassign the data source of the data grid.
modaLookupData = New OleDb.OleDbDataAdapter("Select * From " & Me.lstLookupTables.Text, mcnn)
Page 281
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
modaLookupData.Fill(dtData) Me.dgTableData.DataSource = dtData Catch excData As Exception MessageBox.Show(excData.Message) End Try End Sub 9. On the btnUpdate button, add the code in Listing 8.11 to the Click event. This routine performs a task you have seen in one form or another throughout this book. A CommandBuilder object is created off the modaLookupData data adapter, and it is used to update the data table. The Update method of modaLookupData is executed, followed by the AcceptChanges method of the dtFromGrid data table. Listing 8.11 frmHowTo8_2.vb: Populating the DataGrid Control
Private Sub btnUpdate_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnUpdate.Click Dim dtFromGrid As DataTable '-- Create the command builder to update (post) the data in the data grid ' back to the server.
Dim custCB As OleDb.OleDbCommandBuilder = _ New OleDb.OleDbCommandBuilder(modaLookupData) Try '-- Have to open the connection. mcnn.Open() '-- Grabbing the data table from the DataSource property of the data grid ' saves a bunch of hassles trying to track the data table
' directly.
dtFromGrid = CType(dgTableData.DataSource, DataTable) '-- Commands necessary to actually post back to server. modaLookupData.Update(dtFromGrid) dtFromGrid.AcceptChanges() '-- Don't forget to close the connection. mcnn.Close() Catch excp As Exception MessageBox.Show("Couldn't update server") End Try
Page 282
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub
Tip One interesting thing of note is the way that the DataTable object is derived in this routine. Instead of creating it from a DataSet or
DataAdapter object, we get it from the DataGrid object, with the line
of code that reads like this:
dtFromGrid = CType(dgTableData.DataSource, DataTable) How It Works
When the form opens, the initial table's data in the list box is loaded into the DataGrid control by setting the SelectedIndex of the lstLookupTables to 0. When this occurs and when a user selects a new item in the list, a Select statement is generated and loaded into a data adapter, which fills a data table. This, in turn, is used for the data source of the data grid, and the data is displayed. When the user clicks the button with the caption Update, a CommandBuilder object is generated off the DataAdapter object. The Update command for the data adapter is then invoked, with the
Update method called. The data table is then referenced from the data source of the DataGrid control, and the AcceptChanges method is called. Comments
Creating this kind of utility will save hundreds of hours in some cases, especially if you use it across applications. When starting with something this simple, you can add features to it every time you use it for a new and expanded purpose.
[ Team LiB ]
Page 283
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.3 Create a Point-and-Click SQL Server Query Tool for Users Using a Windows Form
Clients usually want a means of querying the tables, but they do not necessarily know how to create SQL statements. This example describes how to create a point-and-click query interface using a Windows Form and display fields from individual tables as they are chosen. In just about every application you create, your clients need a means to view the data and want to be able to create their own lists. However, most don't want to have to learn how to create SQL statements. In this How-To, you will see a method for not only creating a point-and-click query tool that will allow the users to examine all tables in the database, but also for using the Windows Form in an application without modification.
Technique
To accomplish the task just presented, you will be using the OleDbCommand and DataReader object. Along with these objects, you will be using some stored procedures that SQL Server supplies. These stored procedures list the various objects within a SQL Server database in this case, Northwind's tables and columns. You will take the elements returned in the DataReader object and load the Add method of the
ListBox object. Steps
Open and run the VB.NET Chapter 8 solution. From the main Windows Form, click on the command button with the caption How-To 8.3. The first list box you see to the left is populated with the tables from Northwind. Click on the Customer table, and you will see the columns in the next list box labeled Columns. Click on the CompanyName and ContactName, and you will see the SQL String text box filled in. After clicking on the View button, the form will look like the one displayed in Figure 8.5. 1. Create a Windows Form. Then place the controls shown in Figure 8.5 with the properties set forth in Table 8.4.
Table 8.4. Labels, ListBoxes, DataGrid, TextBox, and Command Button Controls Property Settings Object Property Setting
Label
Name Text
Label1 Tables Label2 Columns Label3 SQL String Label4
Label
Name Text
Label
Name Text
Label
Name
Page 284
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text ListBox ListBox Name Name SelectionMode TextBox Name MultiLine Button DataGrid
2. Tip
Data Display lstTables lstColumns MultiSimple txtSQLString True btnView dgDisplay
Name Name
Notice that the lstTables list box only allows the user to pick one table at a time, whereas lstColumns allows you to choose multiple columns. A great enhancement to this tool would be to allow the user to select multiple tables and have the application figure out the relation between tables.
3. In the class module for the form, add the following Private declaration just below the line of code that reads Windows Form Designer generated code: 4. 5. Dim mcnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", "Northwind")) This line of code declares and assigns an OleDBConnection object that will be used throughout the form. 6. On the form, add the code in Listing 8.12 to the Load event. The first thing this code routine does is create a new OleDbCommand called ocmdTables and assign the built-in SQL Server stored procedure called sp_Tables. After establishing the CommandType as being CommandType.StoredProcedure and then opening the connection, the data reader called
odrTables is created by calling the ExecuteReader method off ocmdTables.
Listing 8.12 frmHowTo8_3.vb: Executing a SQL Server-Supplied Stored Procedure That Lists the Tables in the Database
Private Sub frmHowTo3_8_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load '-- Create the connection and specify the stored procedure to use. Dim ocmdTables As New OleDb.OleDbCommand("sp_Tables", mcnn) Dim odrTables As OleDb.OleDbDataReader Try
Page 285
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Specify the type of command being performed ocmdTables.CommandType = CommandType.StoredProcedure mcnn.Open() '-- Create the DataReader object odrTables = ocmdTables.ExecuteReader() '-- Loop through and add table-type object names ' to the lstTables list box. If odrTables.GetString(3) = "TABLE" Then Me.lstTables.Items.Add(odrTables.GetString(2)) End If Loop mcnn.Close() Catch excpData As Exception MessageBox.Show("Error Occurred: " & excpData.Message) End Try End Sub Next, the code loops though each of the items returned by the command. Those of type TABLE are added to the lstTables items. Then the connection is closed. As mentioned, you will see a comparison to the literal "TABLE." The reason for this is that the fourth column returned is the same table type as the current table. The other two types are SYSTEMTABLE and VIEW. To see the data returned by the sp_tables stored procedure, open the Query Analyzer, located on the Start menu, in Programs, Microsoft SQL Server. After opening up the Query Analyzer, highlight the Northwind database, and then type execute sp_tables into the Query Edit window and press F5 to execute the query. The results will be shown in the bottom of the window. Page down through the data until you see some of the type "TABLE" (see Figure 8.6). Figure 8.6. Testing the built-in stored procedure called sp_tables. Do While odrTables.Read
Page 286
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
7.
On lstTables, add the code in Listing 8.13 to the SelectedIndexChanged event. This routine performs a similar feat to the previous routine in that it calls a built-in stored procedure in this case, sp_Columns. However, the next task in this step is to pass a parameter, TableName, which is the table chosen in lstTables. After the connection is opened, the data reader called odrColumns is loaded with the ExecuteReader command. After the lstColumns.Items.Clear() method is called to clear the list, the new columns are added to lstColumns Items collection. Last, the connection is closed. Listing 8.13 frmHowTo8_3.vb: Executing a SQL Server Built-In Stored Procedure That Lists the Columns of a Supplied Table in the Database
Private Sub lstTables_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstTables.SelectedIndexChanged '-- Create the connection and specify the stored procedure to use. Dim ocmdColumns As New OleDb.OleDbCommand("sp_Columns", mcnn) Dim odrColumns As OleDb.OleDbDataReader Try '-- Specify the type of command being performed ocmdColumns.CommandType = CommandType.StoredProcedure ocmdColumns.Parameters.Add("@TableName", Me.lstTables.Text) mcnn.Open() '-- Create the DataReader object odrColumns = ocmdColumns.ExecuteReader() '-- Clear the current items in the list Me.lstColumns.Items.Clear()
Page 287
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Loop through and add table type object names ' to the lstTables list box. Me.lstColumns.Items.Add(odrColumns.GetString(3)) Loop mcnn.Close() Catch excpData As Exception MessageBox.Show("Error Occurred: " & excpData.Message) End Try End Sub 8. On lstColumns, add the code in Listing 8.14 to the SelectedIndexChanged event. This routine iterates through the SelectedItems collection of the lstColumns ListBox control, adding the chosen column names to a string variable called strTemp. The length of the string is checked; if the length is greater than 0, the Text property of txtSQLString is set to the following expression: "Select " & strTemp & " From " & Do While odrColumns.Read
Me.lstTables.Text.
Listing 8.14 frmHowTo8_3.vb: Creating the SQL String
Private Sub lstColumns_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstColumns.SelectedIndexChanged Dim strTemp As String Dim intNumColumns As Integer Dim oCurr As Object '-- Cycle through each of the selected columns of the table chosen ' and combine them into a string.
For Each oCurr In Me.lstColumns.SelectedItems() If Len(strTemp) > 0 Then strTemp &= ", " End If strTemp &= oCurr Next '-- Take the string created and add it to the table ' ' name for a SQL String if columns are chosen.
If Len(strTemp) = 0 Then Me.txtSQLString.Text = "" Else
Page 288
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.txtSQLString.Text = "Select " & strTemp & " From " & _ Me.lstTables.Text End If End Sub 9. On btnView, add the code in Listing 8.15 to the Click event. This routine creates the new data adapter called odaDisplay passes the Text property of txtSQLString, and then fills the dtDisplay data table. dtDisplay is then set to the DataSource property of the data grid called dgDisplay. Listing 8.15 frmHowTo8_3.vb: Loading the DataGrid Control with the Specified Data
Private Sub btnView_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnView.Click
Dim odaDisplay As OleDb.OleDbDataAdapter Dim dtDisplay As New DataTable() Try '-- Take the txtSQLString text and create a data table; then set the ' data source of the data grid.
odaDisplay = New OleDb.OleDbDataAdapter(Me.txtSQLString.Text, mcnn) odaDisplay.Fill(dtDisplay) Me.dgDisplay.DataSource = dtDisplay Catch excData As Exception MessageBox.Show(excData.Message) End Try End Sub Figure 8.5. You can set the sorting of the data grid displayed here by clicking on the desired column.
Page 289
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
How It Works
When the form is opened, the lstTables ListBox control is loaded with the tables from the Northwind database. When the user selects a table from the list, that table name is passed to the stored procedure that lists the columns in a table located in the database specified in the connection in this case, Northwind. These columns are loaded into lstColumns. The user can then click on multiple columns in lstColumns. The columns are then added to the SQL Select string that is created and stored in txtSQLString. When the btnView button is clicked, the string is passed to a DataAdapter control, filling a data table. The data is then displayed when the data source of the DataGrid control is set to the data table.
Comments
You can enhance this tool in a number of ways:
Allow users to click on multiple tables and automatically create the join. Add a list of columns for the user to choose to use for criteria, and allow the user to input the criteria.
Tip
Use this tool as a base for editing or reporting the records that are returned. Let the users specify the sorting order using a combo box.
This last enhancement isn't necessary using the DataGrid control because you can click on the column heading and have it sort the columns for you.
The goal of this technique, as with others in this book, is to push you into thinking about the
Page 290
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
possibilities of what you can accomplish with Visual Studio .NET and your databases.
[ Team LiB ]
Page 291
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.4 Make a Generic Search Form in a Visual Basic .NET Desktop Application
Another useful utility that takes advantage of being data driven is a standard search form that you can use for any number of tables, such as customers, employees, or products. This How-To shows you how to create such a Windows Form so that all you need to use it with different tables is to set four custom properties of the form in code. You like to be able to provide a usable search form for my users, without having the hassle of creating a custom form for every topic that the users are maintaining. In this How-To, you will see how to create a form that provides a quick lookup for records and can be used with various topics, such as Customers and Employees, by setting up only a few custom properties on the search form.
Technique
The forms package of Visual Basic has a class module behind it where you can add your own properties and methods. The .NET version of it is no exception. In this How-To, you will see a simple use for custom properties that are being added to a form. Properties can be specified on a form by adding the following syntax to your form:
Public Property PropertyName() As DataType Get PropertyName = ModuleLevelMemoryVariable End Get Set(ByVal Value As DataType) ModuleLevelMemoryVariable = Value End Set End Property
With the ModuleLevelMemoryVariable being declared in the module declaration area of the form's class module, you can see the properties created for the search form, called frmHowTo8_b.vb, in Listing 8.16. Listing 8.16 frmHowTo8_4b.vb: Creating Custom Properties for the Search Form
Private Private Private Private Private
mstrDisplayName As String mstrRecordSource As String mstrSearchField As String moResultValue As Object mstrKeyField As String
Public Property DisplayName() As String Get DisplayName = mstrDisplayName End Get Set(ByVal Value As String) mstrDisplayName = Value End Set End Property Public Property SearchRecordSource() As String Get SearchRecordSource = mstrRecordSource End Get Set(ByVal Value As String) mstrRecordSource = Value
Page 292
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html End Set End Property Public Property SearchField() As String Get SearchField = mstrSearchField End Get Set(ByVal Value As String) mstrSearchField = Value End Set End Property Public Property KeyField() As String Get KeyField = mstrKeyField End Get Set(ByVal Value As String) mstrKeyField = Value End Set End Property Public Property ResultValue() As Object Get ResultValue = moResultValue End Get Set(ByVal Value As Object) moResultValue = Value End Set End Property
By assigning values to these properties after initiating an instance of the form, you can utilize the properties and the data stored in those properties from within the forms properties and methods, as well as the procedures assigned to the events within the form. For more information on creating custom classes, properties, and methods for use with your database application, see Chapter 9, "Using Classes with Databases to Make Life Easier."
Steps
Open and run the VB.NET Chapter 8 solution. From the main Windows Form, click on the command button with the caption How-To 8.4a. This form is a simple one that contains text boxes for the Customer table in Northwind. Click on the Search button to open the search form. Click on the button labeled B. You will see the data grid displayed in the bottom of the form filled with the CompanyName column of the Customer table, beginning with the letter B (see Figure 8.7). Figure 8.7. This form can be used for searching within any of the tables in your databases.
Page 293
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Place the cursor in one of the customers displayed in the grid, and then click Accept. The search form will be hidden, and the fields in the first form will be filled in with the data from the chosen record. 1. Create a Windows Form. Then place the controls on the form shown in Figure 8.7, with the properties set forth in Table 8.5.
Table 8.5. Label, TextBox, and Command Button Controls Property Settings for the Calling Form Object Property Setting
Label Label Label Label Label Label Label Label Label
Caption Caption Caption Caption Caption Caption Caption Caption Caption
Customer ID Company Name Contact Contact Title Address City Region Country Phone
Page 294
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox Button
Caption Name Name Name Name Name Name Name Name Name Name Name Name Caption
Fax txtCustomerID txtCompanyName txtContact txtContactTitle txtAddress txtCity txtRegion txtPostalCode txtCountry txtPhone txtFax btnSearch &Search
2.
On btnSearch, add the code in Listing 8.17 to the Click event. This routine shows the power of creating custom properties. After instantiating an instance of the Search form in this case, frmHowTo8_4b.vb the four custom properties shown in Listing 8.17 are set before the form is displayed. This is powerful in letting you get the form set up exactly the way you want to before the user even sees it. After setting up the custom properties, the ShowDialog method is called off of frmSearch. By calling this method, code execution is halted until the form is closed or hidden. This same line of code compares the DialogResult property of the form to the value; if it matches, the code calls the LoadIndividual routine, passing the ResultValue custom property of frmSearch. Both the DialogResult and
ResultValue properties are set in frmSearch and will be shown later in these steps.
Listing 8.17 frmHowTo8_4a.vb: Executing a SQL Server-Supplied Stored Procedure That Lists the Tables in the Database
Private Sub btnSearch_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSearch.Click '-- Instantiate the search forms. Dim frmSearch As frmHowTo8_4b frmSearch = New frmHowTo8_4b() '-- Set the custom data properties on the search form. ' This is what makes it so data driven.
Page 295
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmSearch.DisplayName = "Customers" frmSearch.SearchRecordSource = "Customers" frmSearch.SearchField = "CompanyName" frmSearch.KeyField = "CustomerID" '-- Open the search form as dialog. ' ' ' Based on the DialogResult property, use the custom property ResultValue property and load the requested record.
If frmSearch.ShowDialog() = DialogResult.OK Then LoadIndividual(frmSearch.ResultValue) End If End Sub 3. Create the LoadIndividual routine by entering the code shown in Listing 8.18 into the form. Taking the strKeyValue passed from the results of the search, a data adapter is created and a DataSet is filled. Next, the individual data row is created. Last, each of the TextBox controls is loaded with the value from the column with the corresponding name. Notice the use of the Try…Catch…End Try to ignore controls that don't have a like column in the data row. Listing 8.18 frmHowTo8_4a.vb: Loading an Individual Record into Text Boxes on the Form
Private Sub LoadIndividual(ByVal strKeyValue As String) Dim strSQL As String Dim strName As String Dim oCtl As Object Dim dsCustIndiv As New DataSet() Dim odaCustIndiv As OleDb.OleDbDataAdapter Dim drCustIndiv As DataRow Try '-- Load the individual record into the dataset strSQL = "Select * from Customers Where CustomerID = '" & strKeyValue & "'" odaCustIndiv = New OleDb.OleDbDataAdapter(strSQL, _ BuildCnnStr("(local)", "Northwind")) '-- Fill the dataset odaCustIndiv.Fill(dsCustIndiv, "Customers") '-- Grab the individual data row drCustIndiv = dsCustIndiv.Tables("Customers").Rows(0)
Page 296
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Catch oexpData As OleDb.OleDbException MessageBox.Show("Error loading individual data: " & _ oexpData.Message) Exit Sub End Try '-- Run through the text boxes on the form. '-- If they match up with a field from the record, load them. For Each oCtl In Me.Controls If TypeOf oCtl Is TextBox Then strName = Mid(oCtl.Name, 4) '-- By trapping the exception this way, errors are ignored. Try oCtl.text = drCustIndiv(strName).ToString Catch oexp As Exception End Try End If Next End Sub 4. Create the next Windows Form and call it whatever name you referred to in the search form in step 2. Then place the controls shown in Figure 8.7 of the search form, with the properties set as in Table 8.6.
Table 8.6. Label, TextBox, DataGrid, and Command Button Controls Property Settings for the Calling Form Object Property Setting
GroupBox
Name Text
GroupBox1 Click on a Letter btnA A btnB B btnC
Button
Name Caption
Button
Name Caption
Button
Name
Page 297
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Caption ... Button Name Caption Button Name Caption DataGrid Button Name Name Caption Button Name Caption
5.
C
btnZ Z btnAll All dgSearch btnAccept &Accept btnCancel &Cancel
Create the custom properties discussed in the "Technique" section of this How-To and found in Listing 8.19. Each of the properties is self-explanatory. Listing 8.19 frmHowTo8_4b.vb: Creating Custom Properties for the Search Form
Private mstrDisplayName As String Private mstrRecordSource As String Private mstrSearchField As String Private moResultValue As Object Private mstrKeyField As String Public Property DisplayName() As String Get DisplayName = mstrDisplayName End Get Set(ByVal Value As String) mstrDisplayName = Value End Set End Property Public Property SearchRecordSource() As String Get SearchRecordSource = mstrRecordSource End Get Set(ByVal Value As String) mstrRecordSource = Value End Set End Property
Page 298
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Public Property SearchField() As String Get SearchField = mstrSearchField End Get Set(ByVal Value As String) mstrSearchField = Value End Set End Property Public Property KeyField() As String Get KeyField = mstrKeyField End Get Set(ByVal Value As String) mstrKeyField = Value End Set End Property Public Property ResultValue() As Object Get ResultValue = moResultValue End Get Set(ByVal Value As Object) moResultValue = Value End Set End Property 6. On the form, add the code in Listing 8.20 to the Load event. This routine ensures that the calling form set the DisplayName custom property; thus, this routine can assume that the others were set as well. If not, a message box is displayed. If so, the Text property of the form, which is displayed in the Title bar, is set to DisplayName. Listing 8.20 frmHowTo8_4b.vb: Executing a SQL Server-Supplied Stored Procedure That Lists the Tables in the Database
Private Sub frmHowTo8_4b_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If Len(Me.DisplayName) = 0 Then MessageBox.Show("Form specific properties not set.") Me.Close() Else Me.Text = Me.Text & " " & Me.DisplayName End If End Sub
Page 299
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
7. For each of the command buttons that has a single letter, add the first subroutine displayed in Listing 8.21 to each of the Click events. For the btnAll Button control, add the second subroutine to the Click event. Each Button control will pass the letter it represents to the subroutine called SetData, discussed in the next step. The btnAll code simply passes the empty string. Listing 8.21 frmHowTo8_4b.vb: Click Events for Each of the Letter Button Controls
Private Sub btnA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnA.Click SetData("A") End Sub Private Sub btnAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAll.Click SetData("") End Sub 8. Add the subroutine in Listing 8.22 to the class module of the form. This routine takes the letter value passed in strFilterLetter as a parameter. A SQL Select string is created that takes the literal values Select, From, and Where and uses the custom properties KeyField,
SearchField, and SearchRecordSource. The SearchField property is used with the Like clause, also using the strFilterLetter and the % (wildcard). Note that if "" is passed to strFilterLetter, all the records will be listed. Finally, odtSearch is filled and set as the data source for dgSearch, which is the DataGrid control.
Listing 8.22 frmHowTo8_4a.vb: Filling the Results Set Based on the Letter Button That Was Pressed
Sub SetData(ByVal strFilterLetter As String) Dim odaSearch As OleDb.OleDbDataAdapter Dim dtSearch As DataTable = New DataTable() odaSearch = New _ OleDb.OleDbDataAdapter("Select " & Me.KeyField & ", " & Me.SearchField & " From " & Me.SearchRecordSource & " Where " & Me.SearchField & " Like '" & strFilterLetter & "%'", (BuildCnnStr("(local)", "Northwind"))) odaSearch.Fill(dtSearch) dgSearch.DataSource = dtSearch End Sub Note
This routine more than any in this How-To shows the flexibility of this technique. You can use any table values for these properties. Just think of how many places you can use this form without changing a line of
Page 300
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
code in the form.
9.
On the buttons called btnAccept and btnCancel, add the code in Listing 8.23 to the appropriate Click event of each. The btnAccept_Click routine creates a DataTable object from the data grid's DataSource property. Then it derives the data row that is currently selected from that data table. The KeyField property is used to store the individual column value of drCurr into the ResultValue custom property. The
DialogResult property is set to OK, and the form is hidden with the Hide method. By
hiding the form, you can still read the properties of the form without the user seeing it. In the btnCancel_Click routine, the DialogResult is set to No, and the form is closed. This action tells the calling form that the search was canceled. Listing 8.23 frmHowTo8_4b.vb: Storing the Resulting Key Value to the ResultValue Custom Property and Setting the DialogResult
Private Sub btnAccept_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAccept.Click Dim dtFromGrid As DataTable Dim drCurr As DataRow Try '-- Using the DataRow and DataTable objects of the DataGrid control, ' ' ' ' get the selected result and assign it to the custom property ResultValue. Then set the DialogResult property to DialogResult.OK, and hide the form so that the calling form can still access it.
dtFromGrid = CType(dgSearch.DataSource, DataTable) drCurr = dtFromGrid.Rows(Me.dgSearch.CurrentRowIndex()) Me.ResultValue = drCurr(Me.KeyField).ToString Me.DialogResult = DialogResult.OK Me.Hide() Catch exp As Exception Me.DialogResult = DialogResult.No Me.Close() End Try End Sub Private Sub btnCancel_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCancel.Click
Page 301
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.DialogResult = DialogResult.Cancel Me.Close() End Sub
How It Works
When the user clicks on the search button, the calling form sets the custom properties of the search form, telling it what record source to use, as well as other information used for searching for the specific record and domain desired in this case:
Customers for the property DisplayName Customers for the property SearchRecordSource CustomerID for the property KeyField CompanyName for the property SearchField
After the search form is loaded, the user presses one of the letters to narrow down the records to look for, a data adapter is passed a SQL String made up of the properties just mentioned, a data table is filled, and the data grid's DataSource property sets the data table. When the user clicks Accept, the data table is retrieved from the data grid, which then produces the data row that contains the key field. This is stored into the ResultValue property of the search form, the DialogResult property is set to DialogResult.OK, and the form is hidden. Back on the calling form, the LoadIndividual routine is called and passed the ResultValue property from the search form. The text boxes are then loaded with the data row results.
Comments
This technique shows a number of ways that the various ADO.NET objects can be used. Take a close look at the use of the dialog style form, forcing code execution to halt until you hide or close the form. This is a technique that you will use throughout your applications after you get used to it. Again, you can enhance this tool in a number of ways. One way is to allow the user to enter a string value to type in, narrowing down the choices even more, and another is to add a property that could be used to specify multiple columns to be displayed.
[ Team LiB ]
Page 302
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.5 Work with Data-Bound Multi-Select List Boxes Using Web Forms
As with How-to 8.1, this example will show you how to take advantage of multi-select list boxes, only with a Web Form instead of a Windows Form. You need to be able to manipulate multi-select list boxes in your Web applications using ASP.NET as well as in your Visual Basic .NET desktop applications. This How-To shows you how to use just about the same coding techniques as in How-To 8.1, but with the change of using the Web Form.
Technique
When you are performing a task in a Web Form that you have created in a Windows Form, you would think it would take the same effort if not more to accomplish the task. However, this is not the case for this How-To. The commands available to the Windows Form ListBox control will give better performance because you have a SelectedIndexes collection to work with, and in the Web Form you iterate through all the items in the ListBox control and check the Selected property. Nonetheless, coding on the Web Form is simpler. Unlike the Windows Form version of the ListBox Control, which has four different settings for the
SelectionMode property, the Web Form version has two: Single or Multiple.
Another thing to keep in mind when developing with data and the Web Form is that you will need to use the DataBind method off the ListBox control to bind the data at runtime. In the Load event of the page, you will want to use the IsPostBack method of the page to ensure that you perform certain tasks only when the page is initially loaded, and not on a round trip that pages take back to the server.
Steps
Open and run the VB.NET Chapter 8 solution. From the main Web Form, click on the hyperlink with the caption How-To 8.5: Work with Data-Bound Multi-Select List Boxes Using a Web Form. You will then see the page displayed in Figure 8.8. Figure 8.8. This Web Form uses controls bound at runtime and takes advantage of multi-select list boxes.
Page 303
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When the page loads, you will see the Beverages category chosen in the top combo box. The Selected and Unselected Products ListBox controls are filled in with the appropriate products. If you click on a product in the Unselected Products list box and then click on the arrow button pointing to the right (>), the item is moved to the Selected Products list box. If you select items in the Selected Products list box and click on the arrow button pointing to the left (<), those items are moved to the Unselected Products list box. If you click on the Unassigned Products Only check box at the bottom of the form, the Unselected Products list box is filled with products that are not assigned to any category. Note If you check the Unassigned Products Only check box when you are first getting into Northwind and running this example, you probably won't see unassigned items. You will need to unselect products from a category.
1.
Create a Web Form. Then place the controls shown in Figure 8.8 with the properties set as seen in Table 8.7.
Table 8.7. Label, ComboBox, ListBox, and Command Button Control Property Settings Object Property Setting
DOCUMENT Label
bgColor Name
buttonface Label1
Page 304
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text DropDown Label Name Name Text ListBox Name SelectionMode Label Name Text ListBox Name SelectionMode Command Button Name Text Command Button Name Text CheckBox Label Name Name Text HyperLink Name Text NavigateURL wfrmMain.aspx
2. Note
Category: ddCategories Label2 Unselected Products lstUnSelected Multiple Label3 Selected Products lstSelected Multiple btnSelect > btnUnSelect < chkUnAssignedOnly Label4 UnAssigned Products Only hplReturnToMain Return To Main
HyperLink is optional. It is just used to get back to
the main sample page for this chapter.
3.
As with some of the other chapters' projects, before creating the code that will be attached to the Load event of the form, you need to build a support routine to create the Connection string. Called BuildCnnStr, the function can be seen in Listing 8.24. This function takes a server and database names that are passed to it and creates a Connection string.
Page 305
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 8.24 modGeneralRoutines.vb: Creating a Connection String
Function BuildCnnStr(ByVal strServer As String, _ ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Provider=SQLOleDB; Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function Although you could create a routine that would pass back a Connection object, a more versatile method would be to pass back a string. Some objects ask you for a Connection object, but others just want a string. You will see BuildCnnStr called in the next step. 4. On the form, add the code in Listing 8.25 to the Load event. In this code, the first task is to make sure the code is run only once in the page, when it is first loading. The Not
IsPostBack check performs this task. Next, you will create a data adapter called odaCategories and load the categories SQL Statement into it. The dtCategories data table is filled and set as the DataSource property of ddCategories. The DataTextField and DataValueField of ddCategories are then set. After that, the DataBind method of the DropDown is called. This is necessary for binding data to the server controls on Web Forms. Finally, two new subroutines called LoadUnSelectedProducts and LoadSelectedProducts are called to populate the appropriate list boxes. These routines
are discussed in the next two steps. Listing 8.25 wfrmHowTo8_5.aspx: Loading Categories into a List Box
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here Dim odaCategories As OleDb.OleDbDataAdapter Dim dtCategories As New DataTable() '-- Make sure this code is only executed when the page is first loaded. If Not Page.IsPostBack Then '-- Load up the Categories DropDown control odaCategories = New _ OleDb.OleDbDataAdapter("Select CategoryID, CategoryName " & _ " From Categories", BuildCnnStr("(local)", "Northwind")) odaCategories.Fill(dtCategories) Me.ddCategories.DataSource = dtCategories
Page 306
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.ddCategories.DataTextField = "CategoryName" Me.ddCategories.DataValueField = "CategoryID" '-- This is necessary for Web Forms, but not used on Windows Forms. Me.ddCategories.DataBind() LoadUnSelectedProducts() LoadSelectedProducts() End If End Sub 5. Create the LoadUnSelectedProducts routine, shown in Listing 8.26, by entering the following code in the Web Form that you created for this How-To. This routine starts off by testing the check box called chkUnAssignedOnly. Based on that value, a SQL string is created that grabs the products that are either not assigned to any product, if chkUnAssignedOnly = True, or all products that are not assigned to the chosen category are retrieved. The SQL String is stored in the variable called strSQL. Next, the DataAdapter object called odaUnselected is set to strSQL and the SQL Server connection string. The
DataTable object called dtUnSelected is then filled.
The Dispose method of the ListBox control is called to remove current items, and dtUnSelected is assigned to the DataSource property of lstUnSelected. Then the DataTextField and DataValueField properties are set. Last, the DataBind and
ClearSelected methods are called to bind the lstUnSelected and ensure that no entries
are left selected. Listing 8.26 wfrmHowTo8_5.aspx: Populating the List Box That Displays Unselected Products
Sub LoadUnSelectedProducts() Dim odaUnSelected As OleDb.OleDbDataAdapter Dim dtUnSelected As New DataTable() Dim strSQL As String '-- If the check box for unassigned only is checked, then ' ' grab the product items where the category is null; otherwise, load it up with those products not assigned to the current category.
If chkUnAssignedOnly.Checked Then strSQL = "Select ProductID, ProductName From Products " & "Where CategoryID IS NULL Order By ProductName" Else strSQL = "Select ProductID, ProductName From Products " & _ Where CategoryID <> " & End If '-- Load up the lstUnselected based off the SQL string. ddCategories.SelectedItem.Value & _ " Or CategoryID IS NULL Order By ProductName"
Page 307
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
odaUnSelected = New OleDb.OleDbDataAdapter(strSQL, BuildCnnStr("(local)", "Northwind")) odaUnSelected.Fill(dtUnSelected) Me.lstUnSelected.Dispose() Me.lstUnSelected.DataSource = dtUnSelected Me.lstUnSelected.DataTextField = "ProductName" Me.lstUnSelected.DataValueField = "ProductID" '-- Needed on Web Forms. Me.lstUnSelected.DataBind() Me.lstUnSelected.ClearSelection() End Sub 6. Create the LoadSelectedProducts routine by entering the code in Listing 8.27 into the form you created for this How-To. This routine basically performs the same tasks that the routine listed in the previous step does, except that it performs the tasks using the lstSelected ListBox control. This routine also doesn't need to test the CheckBox control. Listing 8.27 wfrmHowTo8_5.aspx: Populating the List Box That Displays Selected Products
Sub LoadSelectedProducts() Dim odaSelected As OleDb.OleDbDataAdapter Dim dtSelected As New DataTable() Dim strSQL As String '-- Create the SQL string for the category chosen in the ' ddCategories dropdown. Then load the data table with the data ' and bind the lstSelected list box.
strSQL = "Select ProductID, ProductName From Products " & _ "Where CategoryID = " & _ ddCategories.SelectedItem.Value & " Order By ProductName" odaSelected = New _ OleDb.OleDbDataAdapter(strSQL, _ BuildCnnStr("(local)", "Northwind")) odaSelected.Fill(dtSelected) Me.lstSelected.Dispose() Me.lstSelected.DataSource = dtSelected Me.lstSelected.DataTextField = "ProductName" Me.lstSelected.DataValueField = "ProductID"
Page 308
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.lstSelected.DataBind() Me.lstSelected.ClearSelection() End Sub 7. Add the code in Listing 8.28 to the SelectedIndexChanged event of the ddCategories drop-down. Listing 8.28 wfrmHowTo8_5.aspx: Repopulating the List Boxes Based on the Current Category That Is Selected
Private Sub ddCategories_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles ddCategories.SelectedIndexChanged LoadUnSelectedProducts() LoadSelectedProducts() End Sub 8. Add the code in Listing 8.29 to the CheckChanged event of the chkUnAssignedOnly check box. Listing 8.29 wfrmHowTo8_5.aspx: Calling the Routine to Reload the lstUnSelected List Box If This Check box Is Changed
Private Sub chkUnAssignedOnly_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkUnAssignedOnly.CheckedChanged LoadUnSelectedProducts() End Sub 9. Add the code in Listing 8.30 to the Click event of the btnSelect command button. This and the next step contain the most code as well as some new objects and properties. First, the number of highlighted items (SelectedIndices.Count) is stored to an Integer variable called intItemsNum. A 1 is subtracted off the figure because the collections in .NET are zero based. Next, the code iterates through the Items collection of the lstUnSelected list box, testing the Selected property for selected items. The Value property of the item is converted to a string and added to a string variable called strItems. strItems is then used to create the criteria for an IN clause of a SQL Update statement, which is passed to the Command object called ocmdSelect. This Command object is executed, and the selected products are updated to reflect the category chosen. Last, both the list boxes are reloaded to reflect the changes. Listing 8.30 wfrmHowTo8_5.aspx: Updating the Server with Products That Are Selected for the Given Category
Private Sub btnSelect_Click(ByVal sender As System.Object,
Page 309
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ByVal e As System.EventArgs) Handles btnSelect.Click Dim intItemsNum As Integer Dim strItems As String Dim oCurr As Object '-- Iterate through each of the items in lstUnSelected ' ' and check the Selected property. If selected, store into a string with other selected product IDs.
For Each oCurr In Me.lstUnSelected.Items If oCurr.Selected() = True Then If Len(strItems) > 0 Then strItems = strItems & ", " End If strItems = strItems & CType(oCurr.Value, String) End If Next '-- Run an update query to assign the category to the desired products, ' Try Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmdSelect As New _ OleDb.OleDbCommand("Update Products Set CategoryID = " & Me.ddCategories.SelectedItem.Value & _ " Where ProductID IN (" & strItems & ")", ocnn) ocmdSelect.CommandType = CommandType.Text ocnn.Open() ocmdSelect.ExecuteNonQuery() Catch excpCommand As Exception End Try LoadUnSelectedProducts() LoadSelectedProducts() End Sub 10. Add the code in Listing 8.31 to the Click event of the btnUnSelect command button. Again, this code is similar to the previous step, but it is used to set the CategoryID column to null if the product was highlighted in the lstSelected list box and btnUnSelect was clicked. using an IN clause in the SQL statement.
Page 310
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 8.31 frmHowTo8_5.aspx: Updating the Server with Products That Are Unselected for the Given Category
Private Sub btnUnSelect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUnSelect.Click Dim intItemsNum As Integer Dim strItems As String Dim oCurr As Object '-- Iterate through each of the items in lstSelected ' ' and check the Selected property. If selected, store into a string with other selected product IDs.
For Each oCurr In Me.lstSelected.Items If oCurr.Selected() = True Then If Len(strItems) > 0 Then strItems = strItems & ", " End If strItems = strItems & CType(oCurr.Value, String) End If Next Try Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmdUnSelect As New _ OleDb.OleDbCommand("Update Products Set CategoryID = Null " & _\\ "Where ProductID IN (" & _ strItems & ")", ocnn) ocmdUnSelect.CommandType = CommandType.Text ocnn.Open() ocmdUnSelect.ExecuteNonQuery() Catch excpCommand As Exception End Try LoadUnSelectedProducts() LoadSelectedProducts() End Sub
How It Works
Page 311
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When the user chooses a category, the appropriate items are loaded into the two list boxes. Unselected items are in the list box on the left, and the selected items are in the list box on the right. If the check box is selected, then those only those items that are not currently assigned to categories are displayed in the list box on the left, which is titled Unselected Products. When the btnSelect button is clicked, any items that are highlighted in the lstUnSelected list box are used in a query that updates the server with the new category they now belong to. Similarly, when the btnUnSelect is clicked, items that are listed in the lstSelected list box are used in a query that updates the CategoryID of the products to null.
Comments
As mentioned in How-To 8.1, this example is not the smartest to create in real life because you want products to be assigned to a category. However, this example does a good job of showing the properties and methods you can use to work with the multi-select features of the ListBox control.
[ Team LiB ]
Page 312
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.6 Use a Single Web Form to Update Multiple Lookup Tables
As with the second tutorial(8.2), this example will show you how to update multiple lookup tables this time using a Web Form. Creating a Web Form for viewing multiple lookup tables would take about the same if not less code than performing the same task using the Windows Form. Updating, adding, and deleting data takes a bit more work, though. This How-To will show you how to accomplish this task by using the DataGrid control and show you how to take advantage of Session variables and paging within the data grid when you're manipulating data.
Technique
The DataGrid control is a powerful control, as you saw in Chapter 5, "Working with Data on Web Forms," but when programming in Web Forms, it takes some getting used to. Because the Web Forms are stateless, you need to keep reminding the data grid what it is bound to. Also, even though you declare a variable at the module level behind the form, you will notice that whenever the form goes back to the server for information, you lose the values of your variables. The workaround for this is the use of the Session object. Note A full discussion of State management in .NET and the various options is presented in Chapter 5. This also includes how to use the options for the data grid manipulation portion of this How-To.
The other major issue with this How-To is managing the paging of the DataGrid control, covered in Chapter 4. You will quickly learn the steps of creating the Web Form that allows users to update Lookup tables.
Steps
Open and run the VB.NET Chapter 8 solution. From the main Web Form, click on the hyperlink with the caption How-To 8.6: Use a Single Web Form for Updating Multiple Lookup Tables. Click on the first choice, Categories, in the list box labeled Lookup Table to Edit. The data grid will then appear. The grid will be filled in with the data of the table you chose. Your page will then look like the page displayed in Figure 8.9. Figure 8.9. On this page, you can add, edit, and delete information for all your simple lookup tables.
Page 313
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You can now add data into the data grid by clicking on the Add New button, located under the Error box. When you click on the Add New button, an entry is added to the data grid, and you are placed in Edit mode, shown in Figure 8.10. Figure 8.10. Adding new data to your lookup tables using the DataGrid control.
After entering the data into the fields, you will click Update. The values are then saved back to the server. If you don't want to save the new entry, click the Cancel button, and the data grid makes the entry disappear.
Page 314
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Tip
You will notice that the look of the columns is a little congested and changes when you go to edit the data. You can avoid this by creating and using templates with the data grid. Of course, if you are using templates with the data grid, you have to change the template based on the lookup table you were using.
Tip You will also notice that the CategoryID field has been disabled and can't be edited. This is through the use of a method, FillSchema, which fills data table with schema information from the record source. In this case, FillSchema passed on the information that the CategoryID was an AutoIncrement field, and the data grid was smart enough to handle it.
When you click on the Edit button, the page will look similar to Figure 8.10, except that data already will be present in the fields. When you click Delete, the entry is deleted. Any errors that might occur, such as from data integrity errors, will appear in the text box labeled Errors. If you try to delete a current category and Products uses that category, for example, then SQL Server causes an error to occur, and the page reports the error because of code created. 1. Create a Web Form. Then place the controls shown in Figure 8.9 with the properties shown in Table 8.8.
Table 8.8. Label, TextBox, ListBox, and Command Button Control Property Settings Object Property Setting
DOCUMENT Label
bgColor Name Text
buttonface Label1 Lookup Table to Edit: lstLookupTables True Label2 Lookup Table Data: dgLookupData
ListBox
Name AutoPostback
Label
Name Text
DataGrid
Name
Page 315
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
AllowPaging PageSize Label Name Text TextBox Name ForeColor ReadOnly TextMode Button Name Text HyperLink Name NavigateURL
2.
True 5 Label3 Errors: txtError Red True MultiLine btnAdd Add New hplReturnToMain wfrmMain.aspx
On the newly created lstLookupTables ListBox control, click the Build button next to the
Items property, which is a collection of names of the lookup tables to edit. After you have
clicked the Build button, the ListItem Collection Editor opens. Enter the values Categories, Regions, and Territories, as shown in Figure 8.11. Click OK to accept the entries. Figure 8.11. These values allow you to update multiple lookup tables from a single Web Form.
Page 316
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Tip
To make this truly data driven, you could have these entries in a table in your database. Then you could point the DataSource property of the list box to the table. You could also have the table contain the names of the templates you wanted to use. A different approach was taken here so that you would not have to modify your copy of the Northwind database.
3. On the dgLookupData DataGrid control, click the Build button next to the Columns property. You will then be brought into the Columns tab of the dgLookupData Properties dialog box. Click on the plus sign by the Button column in the Available Columns list. You will then see the list of available button types you can use. Select the Edit, Update, Cancel, and Delete buttons. Set each of these buttons to have the PushButton button type. After you have made these selections, the dialog box will look like Figure 8.12. Click OK to accept the entries. Figure 8.12. Add some buttons to your DataGrid control.
Page 317
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Now that you have added some buttons to the DataGrid control, you still have to tell the control how to react to the buttons. You will do that using events in code, but we need to add some tags to the HTML. The tags you will add are as follows:
5. 6. 7. 8. 9. OnUpdateCommand="dgLookupData_Update" OnCancelCommand="dgLookupData_Cancel" OnEditCommand="dgLookupData_Edit" OnDeleteCommand="dgLookupData_Delete" Click on the HTML tab of the Web Form in Visual Studio. Then you can see the HTML and insert the tags. By looking at the HTML shown in Figure 8.13, you can see where to put the tags. Of course, your HTML won't be as nicely laid out as this figure because Visual Studio scrunches it up. Figure 8.13. Add the tags in this step to tie in the events to the buttons in the DataGrid control.
Page 318
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
10. Now it's time for the code. The first items to add are the code for the module level
DataTable object variable declaration and the code that you want to add for the Load event of the page. Both are shown in Listing 8.32. The load event tests for the Session variable MyLookupData; if the variable exists, the event creates a reference to the data table using the mdtLookupData DataTable object.
Listing 8.32 frmHowTo8_6.aspx: Tracking the DataTable Object Between Trips to the Server
Private mdtLookupData As New DataTable() Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not (Session("MyLookupData") Is Nothing) Then mdtLookupData = CType(Session("MyLookupData"), DataTable) End If End Sub 11. Add the code in Listing 8.33 to the SelectedIndexChanged event of lstLookupTables. This code starts off by clearing the txtError TextBox control that is used to store the Exception object's Message property that is caught later in the routine. Next, the odaLookupData DataAdapter object is built by creating a SQL Select statement from the currently selected table in lstLookupTables. Now it's time to fill in the dtNew DataTable object, which is done using FillSchema and Fill.
Page 319
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You have seen the Fill method before. FillSchema tells .NET to do just that return the Schema to the data table, thus having your DataTable object use properties such as AutoIncrement, DataTypes, and even Constraints. Next, the code reassigns the mdtLookupTable reference to point to dtNew. This works well for using the DataTable and DataGrid objects with different tables, which not only clears the data, but also resets what columns are being used in the data table object. You can see that mdtLookupData is being stored to a Session object entry called
MyDataTable, and a Boolean variable called IsAdding is set to False. This last variable will be set to True when the btnAdd is clicked and used for special handling when updating
and canceling the editing of the data grid. Tip
You really need to watch where you are storing values to the Session object and other state management objects. Make sure you do store these objects before calling methods or accessing properties of server controls such as the DataGrid control.
Next, the EditItemIndex property is set to 1 to unselect any item that is being edited.
Then the CurrentPageIndex property is reset to 0 to reflect the first page in the data grid. The data grid is then filled and the subroutine BindTheGrid() is called. You can find this subroutine at the bottom of the listing. This routine sets the DataSource property of the
DataGrid control to mdtLookupData and calls the DataBind method of the DataGrid
control. Listing 8.33 frmHowTo8_6.aspx: Tracking the DataTable Object Between Trips to the Server
Private Sub lstLookupTables_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstLookupTables.SelectedIndexChanged Dim odaLookupData As OleDb.OleDbDataAdapter Dim dtNew As New DataTable() Me.txtError.Text = "" Try '-- Take the txtSQLString text and create a data table; then set the ' data source of the data grid.
odaLookupData = New OleDb.OleDbDataAdapter("Select * From " & _ Me.lstLookupTables.SelectedItem.ToString, BuildCnnStr("(local)", "Northwind"))
Page 320
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Test for identity and display any other notes. odaLookupData.FillSchema(dtNew, SchemaType.Source) '-- Get the data and put it in the data table. odaLookupData.Fill(dtNew)
'-- Save the data table to a session variable so that ' ' you don't lose it on a trip back to the server. Set the flag for adding new records to False.
Session("IsAdding") = False Session("MyLookupData") = dtNew mdtLookupData = dtNew Me.dgLookupData.EditItemIndex = -1 Me.dgLookupData.CurrentPageIndex = 0 '-- Bind the data grid to the data table BindTheGrid() Catch excp As Exception '-- If an error occurs, stash the error message to a text box. Me.txtError.Text = excp.Message End Try End Sub Sub BindTheGrid() '-- Bind the data grid Me.dgLookupData.DataSource = mdtLookupData Me.dgLookupData.DataBind() End Sub 12. Add the code in Listing 8.34 to the Edit command of dgLookupData. This is one of the events specified in step 4. This code sets the EditItemIndex of the DataGrid object to the selected item and then binds the data. Listing 8.34 frmHowTo8_6.aspx: Telling the DataGrid Object to Use the Selected Item and Go into Edit Mode (Display Wise)
Sub dgLookupData_Edit(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) '-- The data grid does most of the work; just set the EditItemIndex ' to the ItemIndex and bind the grid again.
Page 321
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.txtError.Text = "" dgLookupData.EditItemIndex = e.Item.ItemIndex BindTheGrid() End Sub 13. Add the code in Listing 8.35 to the Click event of btnAdd. Notice that the first task invokes the BeginLoadData method for mdtLookupData. This turns off the schema checking that will occur when adding the new row to the DataTable object. You need to turn this off because you don't want to have it check for required fields until you actually edit the record. The editing of the record is started by the line of code setting the EditItemIndex property of the DataGrid object. The GetPageNum() routine helps to synchronize the DataGrid page with the position the pointer is in the DataTable object. If you add a record, you have to know whether to have it be on the current page or on a new page in the data grid. You can see GetPageNum after
btnAdd_Click in Listing 8.35. GetPageRows(), found at the bottom of Listing 8.35, returns the number of actual rows
based on the page in the data grid. Note
GetPageRows() returns the current page number ( dgLookupData.CurrentPageIndex) times the page size (dgLookupData.PageSize). In this case, GetPageRows() returns 5, as set in step 1. If EditItemIndex were used alone, it would return only
the position of the item that was being edited for the current page.
Last, the EditItemIndex of dgLookupData is set. The data grid is bound to the data table using the BindTheGrid routine. Listing 8.35 frmHowTo8_6.aspx: Adding a Record to the Data Table and Having the Data Grid Reflect It
Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click Dim intColCnt As Integer Dim drCurr As data row Me.txtError.Text = "" mdtLookupData.BeginLoadData() '-- Add the row to the data table via the data row drCurr = mdtLookupData.NewRow
Page 322
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
mdtLookupData.Rows.Add(drCurr) '-- Set the Adding flag. Session("MyLookupData") = mdtLookupData Session("IsAdding") = True '-- Set the current page based on the new number of rows dgLookupData.CurrentPageIndex = GetPageNum(mdtLookupData) '-- Set the item index based on the rows on this page only. dgLookupData.EditItemIndex = mdtLookupData.Rows.Count - _ GetPageRows() - 1 BindTheGrid() End Sub Function GetPageRows() As Integer '-- This helps synchronize the data table rows ' with the DataGrid page and row.
GetPageRows = dgLookupData.PageSize * dgLookupData.CurrentPageIndex End Function Function GetPageNum(ByVal dt As data table) As Decimal Dim decTemp As Decimal '-- Calculate the number of pages decTemp = ((dt.Rows.Count - 1) / dgLookupData.PageSize) GetPageNum = decTemp.Truncate(decTemp) End Function 14. Add the code shown in Listing 8.36 to the Cancel command of dgLookupData. This is one of the events specified in step 4. If the code is in the middle of adding an entry, it uses the EditItemIndex of the DataGrid object to the selected item and adds this to the value returned by GetPageRows(), shown just after the dgLookupData_Cancel subroutine. The value that EditItemIndex and GetPagerows() returns is used to position the pointer in mdtLookupData so that the Delete method can be called. After accepting the changes, the session variables are resaved. Then the page index for the DataGrid object is cleaned up by comparing the current page number relative to the pointer of the data table position to the CurrentPageIndex property. Regardless of whether the item is being added or edited, the EditItemIndex is cleared by setting it to 1. The data grid is bound again by calling BindTheData().
Page 323
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 8.36 frmHowTo8_6.aspx: Canceling Editing/Adding a Record in the DataGrid Object
Sub dgLookupData_Cancel(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) Dim blnAdding As Boolean '-- If you're canceling while adding a record, you need to back the ' ' ' row out of the data table and data grid. You don't have to send it to the server because it really was never added to it.
Me.txtError.Text = "" If CType(Session("IsAdding"), Boolean) Then mdtLookupData.Rows(dgLookupData.EditItemIndex + _ GetPageRows()).Delete() mdtLookupData.AcceptChanges() Session("IsAdding") = False Session("MyLookupData") = mdtLookupData '-- Reset the paging if it has been affected If GetPageNum(mdtLookupData) < dgLookupData.CurrentPageIndex Then dgLookupData.CurrentPageIndex -= 1 End If End If dgLookupData.EditItemIndex = -1 BindTheGrid() End Sub 15. Add the code in Listing 8.37 for the Delete command of dgLookupData. This is one of the events specified in step 4. This code is a lot like the code in the previous step when the record was added. The big difference in this step's code listing is that the deletion is posted back to the server, and in the previous step, it wasn't. It wasn't posted back to the server in the previous step because the server never knew anything about the record. The record had only been added to the data table and was not sent back to the server. You can see that in the next step. Another item to note is the RejectChanges method called in the Catch of the exception handling code. If an error occurs, the change is undone, the message is noted, and life goes on. The rest of this code pretty closely follows what was done in the previous step. Listing 8.37 frmHowTo8_6.aspx: Deleting a Record from the Data Grid and Posting It Back to the Server
Page 324
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Sub dgLookupData_Delete(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) Dim intColCnt As Integer Dim cnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) '-- Create the command builder to update (post) the data ' ' in the data grid back to the server.
Dim odaTableData As OleDb.OleDbDataAdapter Me.txtError.Text = "" Try '-- Take the txtSQLString text and create a data table. Then set the ' data source of the data grid.
odaTableData = New OleDb.OleDbDataAdapter("Select * From " & _ Me.lstLookupTables.SelectedItem.ToString, cnn) Dim ocbTableData As OleDb.OleDbCommandBuilder = _ New OleDb.OleDbCommandBuilder(odaTableData) '-- Delete the row from the data table. mdtLookupData.Rows(e.Item.ItemIndex + GetPageRows()).Delete() '-- Commands are necessary to actually post back to the server. cnn.Open() odaTableData.Update(mdtLookupData) mdtLookupData.AcceptChanges() cnn.Close() Session("MyLookupData") = mdtLookupData Session("IsAdding") = False '-- This is just in case they were editing and press Delete, Clear. dgLookupData.EditItemIndex = -1 '-- Adjust the page according to the number of rows. If GetPageNum(mdtLookupData) < dgLookupData.CurrentPageIndex Then dgLookupData.CurrentPageIndex -= 1 End If Catch excp As Exception
Page 325
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.txtError.Text = excp.Message mdtLookupData.RejectChanges() End Try BindTheGrid() End Sub 16. Add the code in Listing 8.38 for the Update command of dgLookupData. This is one of the events specified in step 4. This routine starts off by declaring DataAdapter and
CommandBuilder objects to update your data back to the server. Before the actual update, however, the current row that is being edited in the data grid is assigned to a DataRow
object. Then each of the items in the row is saved from the data grid cells to the column in the data row. Thanks to using the FillSchema method when filling the data table, the AutoIncrement property will reflect whether a column was an Identity column. If the FillSchema method were not used, you would have to handle the exception that would occur when you tried to write the value to the column. When writing the cells into the columns in the data row, the Trim function is used; because of using the FillSchema method, the values are padded out as SQL Server columns generally are. The rest of the code pretty well runs like it does in step 9. The changes are accepted, written back to the server, and so forth. Listing 8.38 frmHowTo8_6.aspx: Deleting a Record from the Data Grid and Posting It Back to the Server
Sub dgLookupData_Update(ByVal sender As Object, _ ByVal e As DataGridCommandEventArgs) Dim intColCnt As Integer Dim intColCurr As Integer Dim drCurr As DataRow Dim cnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim blnAdding As Boolean Dim strCurrValue As String '-- Create the command builder to update (post) the data ' ' in the data grid back to the server.
Dim odaTableData As OleDb.OleDbDataAdapter Me.txtError.Text = "" Try
Page 326
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Take the txtSQLString text and create a data table. Then set the ' data source of the data grid. Me.lstLookupTables.SelectedItem.ToString, cnn) Dim ocbTableData As OleDb.OleDbCommandBuilder = _ New OleDb.OleDbCommandBuilder(odaTableData) drCurr = mdtLookupData.Rows(dgLookupData.EditItemIndex + _ GetPageRows()) '-- Update the fields in the rows. intColCnt = e.Item.Cells.Count For intColCurr = 2 To intColCnt - 1 If mdtLookupData.Columns(intColCurr - 2).AutoIncrement = _ False Then drCurr.Item(intColCurr - 2) = _ Trim(CType(e.Item.Cells(intColCurr).Controls(0), _ TextBox).Text) End If Next '-- Commands are necessary to actually post back to the server. cnn.Open() odaTableData.Update(mdtLookupData) mdtLookupData.AcceptChanges() cnn.Close() Session("MyLookupData") = mdtLookupData Session("IsAdding") = False dgLookupData.EditItemIndex = -1 BindTheGrid() Catch excp As Exception Me.txtError.Text = excp.Message End Try End Sub 17. Add the code in Listing 8.39 for the PageIndexChanged command of dgLookupData. This code simply sets the CurrentPageIndex property of the data grid to the page that is odaTableData = New OleDb.OleDbDataAdapter("Select * From " & _
Page 327
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
chosen. The code then calls BindTheGrid(). Listing 8.39 frmHowTo8_6.aspx: Updating the Data Grid Page Index
Private Sub dgLookupData_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgLookupData.PageIndexChanged '-- Set the current page in the data grid. Me.dgLookupData.CurrentPageIndex = e.NewPageIndex BindTheGrid() End Sub How It Works
When the form opens, the user clicks on an entry in the Lookup Table to Edit list box. When this occurs and when a user selects a new item in the list, a Select statement is generated and loaded into a data adapter, which fills a data table. This, in turn, is used for the data source of the data grid, and the DataBind method is called. The data is then displayed. If the user clicks on the Edit button, the controls in the data grid are put into Edit mode. If the user clicks the Add button, a data row is added to the data table, and the data grid reflects this, including handling the paging of row locations. When the user clicks the button with the caption Update, a CommandBuilder object is generated off the DataAdapter object. The Update command for the data adapter is then invoked, with the
Update method called. The data table is then referenced from the data source of the data grid control, and the AcceptChanges method is called. If the user clicks Cancel, then the changes are
ignored if a record is being edited, but the data row is deleted if the record was in the middle of being added. When the user clicks Delete, the DataAdapter and CommandBuilder objects are created to remove the data row from the data table and reflect the changes back to the server. The data grid is also re-bound to the data table, and the paging is adjusted.
Comments
Whew, this was a long one. The good news is that the code is already created for you with the book. Remember, though, as with other techniques and examples, this is a starting point for you to run with and expand on. This example doesn't provide all the error trapping that is necessary, but it definitely gives a good start. Before spending too much time enhancing this example, make sure you get the performance out of it, just as you should when trying different data-driven techniques.
[ Team LiB ]
Page 328
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.7 Create a Point-and-Click Query Tool for Users Using a Web Form
As useful if not more so than the example shown in the 8.3 How-to, this exercise will show you how to add a data-driven query tool to your ASP.NET application. When creating database applications, even on the Web, one of your clients inevitably wants to be able to examine the data in his database, and not necessarily in edit pages. The client wants to be able to list his data out and examine the data at his leisure. Giving the user the flexibility to do this via the Web is not as big of a hassle as it sounds. This How-To will show you how to create a page to view the tables in your database, using a nice point-and-click interface.
Technique
To accomplish the task just presented, you will be using the OleDbCommand and DataReader objects. Along with these objects, you will be using some stored procedures that SQL Server supplies. Those stored procedures list the various objects within a SQL Server database in this case, Northwind's tables and columns. You will take the elements returned in the DataReader object and load the Add method of the
ListBox object.
You will also use the Session object as you did in the previous How-To to save a DataTable object for use over trips to the server. Finally, the ViewState object will be used to store a string variable when going to the server and back. The ViewState object is a good .NET state object to use for small pieces of data, such as strings.
Steps
Open and run the VB.NET Chapter 8 solution. From the main Web Form, click on the hyperlink with the caption How-To 8.7: Create a Point-and-Click SQL Server Query Tool for Users Using a Web Form. When the new page opens, the first list box you see to the left is populated with the tables from Northwind. Click on the Customer table, and you will see the columns listed in the list box labeled Columns. Click on the CompanyName and ContactName, and you will see the SQL String text box filled in. After clicking on the View button, the Web page will look like the one displayed in Figure 8.14. 1. Create a Web Form. Then place the controls shown in Figure 8.14 with the properties set forth in Table 8.9.
Table 8.9. Property Settings for Controls on the Point-and-Click Web Form Object Property Setting
DOCUMENT Label
bgColor Name Text
buttonface Label1 Tables
Page 329
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label
Name Text
Label2 Columns Label3 SQL String Label4 Data Display lstTables True lstColumns Multiple True ddSortBy True txtSQLString True btnView dgDisplay True hplBackToMain Return To Main wfrmMain.aspx
Label
Name Text
Label
Name Text
ListBox
Name AutoPostback
ListBox
Name SelectionMode AutoPostback
DropDown
Name AutoPostback
TextBox
Name MultiLine
Button DataGrid
Name Name AllowPaging
Hyperlink
Name Text NavigateURL
2.
Tip
Notice that the lstTables list box allows the user to choose only one table at a time, whereas lstColumns allows the user to choose multiple columns. A great enhancement to this tool would be to allow the user to choose multiple tables and have the application figure out the relationship between tables and create
Page 330
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
joins automatically.
3. In the class module for the form, add the following Private declaration just below the line of code that reads Web Form Designer Generated Code: 4. 5. 6. Private mdtDisplay As DataTable On the Web Form, add the code in Listing 8.40 to the Load event. The first task is to load the tables list box, performed by the subroutine LoadTables(), which is also in this listing. The form only calls this routine if it is the first time into the page, by checking for Not
Me.IsPostBack. The form then tests to see whether the Session object has an entry called MyDisplayDataTable. If the entry exists, then mdtDisplay is referenced to it, meaning that this time through the Load event is probably occurring on a trip back from the
server. The entry exists, and the code needs to set a reference to it. In LoadTables, the routine first creates a new OleDbConnection object called ocnn, an
OleDbCommand object called ocmdTables. It then assigns the built-in SQL Server stored procedure called sp_Tables when instantiating ocmdTables. After establishing the CommandType as being CommandType.StoredProcedure and then opening the connection,
the data reader called odrTables is created by calling the ExecuteReader method off
ocmdTables.
Listing 8.40 frmHowTo8_7.vb: Executing a SQL Server-Supplied Stored Procedure That Lists the Tables in the Database
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If Not Me.IsPostBack Then LoadTables() End If If Not (Session("MyDisplayDataTable") Is Nothing) Then mdtDisplay = CType(Session("MyDisplayDataTable"), DataTable) End If End Sub Sub LoadTables() '-- Create the connection and specify the stored procedure to use. Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmdTables As New OleDb.OleDbCommand("sp_Tables", ocnn) Dim odrTables As OleDb.OleDbDataReader '-- Specify the type of command being performed.
Page 331
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ocmdTables.CommandType = CommandType.StoredProcedure ocnn.Open() '-- Create the DataReader object. odrTables = ocmdTables.ExecuteReader() '-- Loop through and add table type object names ' to the lstTables list box. If odrTables.GetString(3) = "TABLE" Then Me.lstTables.Items.Add(odrTables.GetString(2)) End If Loop End Sub Next, the code loops through each of the items returned by the command. Those of type TABLE are added to the lstTables items. Then the connection is closed. As mentioned, you will see a comparison to the literal TABLE. This is because the fourth column returned matches the current table type. The other two types are SYSTEMTABLE and VIEW. To see the data returned by the sp_tables stored procedure, open the Query Analyzer, as described in How-To 8.3. 7. On lstTables, add the code in Listing 8.41 to the SelectedIndexChanged event. This routine performs a similar feat as the previous routine; it will call a built-in stored procedure in this case, sp_Columns. However, the next task in this step is to pass a parameter, Do While odrTables.Read
TableName, which is the table chosen in lstTables.SelectedItem.Text. After the connection is opened, the DataReader called odrColumns is loaded with the ExecuteReader command. After the lstColumns.Items.Clear() method is called to
clear the list, the new columns are added to the lstColumns Items collection. Then the connection is closed. Listing 8.41 frmHowTo8_7.vb: Executing a SQL Server Built-In Stored Procedure That Lists the Columns of a Supplied Table in the Database
Private Sub lstTables_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstTables.SelectedIndexChanged '-- Create the connection and specify the stored procedure to use. Dim ocnn As New OleDb.OleDbConnection(BuildCnnStr("(local)", _ "Northwind")) Dim ocmdColumns As New OleDb.OleDbCommand("sp_Columns", ocnn) Dim odrColumns As OleDb.OleDbDataReader '-- Specify the type of command being performed ocmdColumns.CommandType = CommandType.StoredProcedure ocmdColumns.Parameters.Add("@TableName", Me.lstTables.SelectedItem.Text) ocnn.Open()
Page 332
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'-- Create the DataReader object odrColumns = ocmdColumns.ExecuteReader() '-- Clear the current items in the list Me.lstColumns.Items.Clear() '-- Loop through and add table type object names ' to the lstTables list box. Do While odrColumns.Read Me.lstColumns.Items.Add(odrColumns.GetString(3)) Loop End Sub 8. On lstColumns, add the code in Listing 8.42 to the SelectedIndexChanged event. After clearing the items from ddSortBy, this routine iterates through the Items collection of the lstColumns ListBox control, adding the chosen column names (those items with the Selected property set to True) to a string variable called strTemp. The DropDown control called
ddSoryBy adds the column name to its Items collection.
After the string is finished iterating through the lstColumns Items, it is stored to a ViewState entry called SQLFields. The LoadSQLString routine is then called, which is also in this listing. In the routine LoadSQLString, the length of the string is checked. If the length is greater than 0, the Text property of txtSQLString is set to the following expression: "Select "
& strTemp & " From " & Me.lstTables.Text & " Order By " & Me.ddSortBy.SelectedItem.ToString. If the length is 0, then the Text property of
txtSQLString is set to the empty string. Listing 8.42 frmHowTo8_7.vb: Creating the SQL String
Private Sub lstColumns_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstColumns.SelectedIndexChanged Dim intNumColumns As Integer Dim oCurr As Object Dim blnIsSelected As Boolean Dim strTemp As String Me.ddSortBy.Items.Clear() '-- Cycle through each of the selected columns of the table chosen ' and combine them into a string.
For Each oCurr In Me.lstColumns.Items If oCurr.Selected() = True Then If Len(strTemp) > 0 Then strTemp &= ", "
Page 333
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End If strTemp &= oCurr.ToString Me.ddSortBy.Items.Add(oCurr.ToString) End If Next ViewState("SQLFields") = strTemp LoadSQLString() End Sub Sub LoadSQLString() '-- Take the string created and add it to the ' table name for a SQL String, if columns are chosen.
If Len(ViewState("SQLFields")) = 0 Then Me.txtSQLString.Text = "" Else Me.txtSQLString.Text = "Select " & ViewState("SQLFields") & _ " From " & Me.lstTables.SelectedItem.ToString & _ " Order By " & Me.ddSortBy.SelectedItem.ToString End If End Sub 9. On btnView, add the code in Listing 8.43 to the Click event. This routine creates the new data adapter called odaDisplay, passes the Text property of txtSQLString, and then fills the dtDisplay DataTable. The public variable, called mdtDisplay, references dtDisplay so that it will be seen in other routines. The code then stores a new entry in the Session object called MyDisplayDataTable, which is loaded back into mdtDisplay upon reloading of the page. Last, the routine BindTheGrid is called to set to the DataSource property of the data grid called dgDisplay. Listing 8.43 frmHowTo8_7.vb: Loading the DataGrid Control with the Specified Data
Private Sub btnView_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnView.Click Dim odaDisplay As OleDb.OleDbDataAdapter Dim dtDisplay As New DataTable() Try '-- Take the txtSQLString text and create a data table. Then set the ' data source of the data grid.
odaDisplay = New OleDb.OleDbDataAdapter(Me.txtSQLString.Text, _
Page 334
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BuildCnnStr("(local)", "Northwind")) odaDisplay.Fill(dtDisplay) mdtDisplay = dtDisplay Session("MyDisplayDataTable") = mdtDisplay BindTheGrid() Catch excData As Exception End Try End Sub Sub BindTheGrid() Me.dgDisplay.DataSource = mdtDisplay '-- Must databind for ASP.NET Me.dgDisplay.DataBind() End Sub 10. On the ddSortby control, attach the first routine in Listing 8.44 to the
SelectedIndexChanged event. Then add the second routine to the PageIndexChanged event of dgDisplay.
Figure 8.14. You can set the sorting of the data grid that is displayed here by choosing from the drop-down list.
Page 335
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 8.44 frmHowTo8_7.vb: Loading the DataGrid Control with the Specified Data
Private Sub ddSortBy_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddSortBy.SelectedIndexChanged LoadSQLString() End Sub Private Sub dgDisplay_PageIndexChanged(ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgDisplay.PageIndexChanged '-- Set the current page in the data grid Me.dgDisplay.CurrentPageIndex = e.NewPageIndex BindTheGrid() End Sub How It Works
When the form is opened, the lstTables ListBox control is loaded with the tables from the Northwind database. When the user selects a table from the list, that table name is passed to the stored procedure. That procedure lists the columns in a database table that is specified in the connection in this case, Northwind. These columns are loaded into lstColumns. The user can click on multiple columns in lstColumns. Those columns then are added to the SQL Select string that is created and stored in txtSQLString. When the btnView button is clicked, the string is passed to a DataAdapter control, filling a data table. From there, the data is displayed when the data source of the DataGrid control is set to the data table. Users can change the sort order by changing the value in the DropDown object.
Comments
You can enhance this tool in several ways:
Let users click on multiple tables and automatically create the join. Add a list of columns for the user to choose to use for criteria, and allow the user to input the criteria.
Use this tool as a base for editing or reporting the records that are returned.
This technique's goal, as with others in this book, is to push you into thinking about the possibilities of what you can accomplish with Visual Studio .NET and your databases.
[ Team LiB ]
Page 336
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 8.8 Make a Generic Search Form in an ASP.NET Web Application
This tutorial will show you how to add a unique search Web Form to your Web application that can be set up using session variables and used for various tables. Creating search forms for Web applications is pretty common. You would like to be able to use the same Web Form for different tables in the same application. This How-To will demonstrate using the same Web Form for searching various tables, taking advantage of the Session object.
Technique
This How-To will use the Session object with a Web Form, something that has been done throughout the book. You will see a good example of using the Session object to pass values in this case, the record source, the key search field, and the display search field to the search form. Finally, the return value will be passed back to the calling Web Form using the Session object. One new control that is used in this How-To is the Panel control. It will be used to group the controls on the search Web Form. The Panel control will be used simply by throwing controls into it and letting it control the layout. You will see the paging used with the DataGrid control as well.
Steps
Open and run the VB.NET Chapter 8 solution. From the main Web Form, click on the hyperlink with the caption How-To 8.8: Make a Generic Search Form Using a Web Form. This page is a simple one that contains text boxes for the Customer table in Northwind (see Figure 8.15). Figure 8.15. This Customers page is a common one used to demonstrate calling the search form.
Page 337
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Click on the Search button to open the search page, and then click on the button labeled B. You will see the DataGrid object displayed in the bottom of the form filled with the CompanyID and CompanyName fields of the Customer table, which begin with B (see Figure 8.16). Figure 8.16. This form can be used for searching within any of the tables in your databases.
Click the Select button for one of the customers who is displayed in the grid, and then click Accept. The customer page will be displayed, and the fields will be filled in with the data from the chosen record. 1. Create a Web Form. Then place the controls shown in Figure 8.16 of the form calling the search form, with the properties set forth in Table 8.10.
Table 8.10. Label, TextBox, and Command Button Controls Property Settings for the Calling Form Object Property Setting
DOCUMENT Label Label Label Label Label Label
bgColor Caption Caption Caption Caption Caption Caption
buttonface Customer ID Company Name Contact Contact Title Address City
Page 338
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label Label Label Label TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox TextBox Button
Caption Caption Caption Caption Name Name Name Name Name Name Name Name Name Name Name Name Caption
Region Country Phone Fax txtCustomerID txtCompanyName txtContactName txtContactTitle txtAddress txtCity txtRegion txtPostalCode txtCountry txtPhone txtFax btnSearch &Search
2.
On btnSearch, add the code in Listing 8.45 to the Click event. This sets up the search Web Form as far as telling it what it needs to know, including how to get back to this page, which is the calling page. The search page, in this case "wfrmHowTo8_8b.aspx," is then opened. Listing 8.45 frmHowTo8_8a.vb: Storing Values to the Session Object for Use on Another Page
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click Session.Item("SearchRecordSource") = "Customers" Session.Item("SearchField") = "CompanyName" Session.Item("KeyField") = "CustomerID" Session.Item("CallingPage") = "wfrmHowTo8_8a.aspx" Server.Transfer("wfrmHowTo8_8b.aspx") End Sub
Page 339
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. Add the code in Listing 8.46 to the Load event of the Web Form. If the Session object has an entry for ResultValue, then the LoadIndividual routine is executed and the
ResultValue is passed. The LoadIndividual routine is described in the next step. This
routine is coded so that when the page is reloaded after the search form has been used, the Session object entry will exist. When you first come into the page, the entry doesn't exist. Listing 8.46 frmHowTo8_8a.vb: Loading an Individual Record into Text Boxes on the Form
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not (Session("ResultValue") Is Nothing) Then LoadIndividual(Session("ResultValue")) End If End Sub 4. Create the LoadIndividual routine by entering the code shown in Listing 8.47 in the form. Taking the strCustID passed from the results of the search, a data adapter is created, and a data table is filled. Last, each of the TextBox controls is loaded with the value from the column with the corresponding name. Listing 8.47 frmHowTo8_8a.vb: Loading an Individual Record into Text Boxes on the Form
Private Sub LoadIndividual(ByVal strCustID As String) Dim odaCustIndiv As New _ OleDb.OleDbDataAdapter("Select * From Customers Where CustomerID = '" & strCustID & "'", BuildCnnStr("(local)", "Northwind")) Dim dtCustIndiv As New DataTable() odaCustIndiv.Fill(dtCustIndiv) With dtCustIndiv.Rows(0) Me.txtCustomerID.Text = .Item("CustomerID").ToString Me.txtCompanyName.Text = .Item("CompanyName").ToString Me.txtContactName.Text = .Item("ContactName").ToString Me.txtContactTitle.Text = .Item("ContactTitle").ToString Me.txtAddress.Text = .Item("Address").ToString Me.txtCity.Text = .Item("City").ToString Me.txtRegion.Text = .Item("Region").ToString Me.txtCountry.Text = .Item("Country").ToString Me.txtPostalCode.Text = .Item("PostalCode").ToString Me.txtPhone.Text = .Item("Phone").ToString Me.txtFax.Text = .Item("Fax").ToString End With
Page 340
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 5. Create the next Web Form, and call it whatever name you referred to in the search Web Form in step 2. Then place the controls shown in Figure 8.16 of the search page, with the properties set forth in Table 8.11.
Table 8.11. Label, TextBox, DataGrid, and Command Button Controls Property Settings for the Calling Form Object Property Setting
DOCUMENT TextBox
bgColor Name Text
buttonface Label1 Click on a Letter Panel1 btnA A btnB B btnC C
Panel Button
Name Name Caption
Button
Name Caption
Button
Name Caption
... Button Name Caption Button Name Caption DataGrid Name AllowPaging Button Name Caption Button Name Caption btnZ Z btnAll All dgSearch True btnAccept &Accept btnCancel &Cancel
Page 341
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6. In the class module for the Web Form, add the following Private declaration just below the line of code that reads Web Form Designer Generated Code: 7. 8. 9. Private mdtSearch As New DataTable() On the Web Form, add the code in Listing 8.48 to the Load event. This routine loads the data table stored in the Session object if it exists. Listing 8.48 frmHowTo8_8b.vb: Executing a SQL Server-Supplied Stored Procedure That Lists the Tables in the Database
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If Not (Session("SearchDataTable") Is Nothing) Then mdtSearch = CType(Session("SearchDataTable"), DataTable) End If End Sub 10. For each of the command buttons that has a single letter, add the first subroutine displayed in Listing 8.49 to each of the Click events. For the btnAll Button control, add the second subroutine to the Click event. Each Button control will pass the letter it represents to the subroutine called SetData, discussed in the next step. The btnAll code simply passes the empty string. Listing 8.49 frmHowTo8_8b.vb: Click Events for Each of the Letter Button Controls
Private Sub btnA_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnA.Click SetData("A") End Sub Private Sub btnAll_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAll.Click SetData("") End Sub 11. Add the subroutine in Listing 8.50 to the class module of the form. This routine takes the letter value passed in strFilterLetter as a parameter. A SQL Select string is created that takes the literal values Select, From, and Where and uses the Session object entries KeyField, SearchField, and SearchRecordSource. The SearchField property is used with the Like clause, also using the strFilterLetter and the % (wildcard). Note that if " is passed to strFilterLetter, all the records will be listed. Finally, mdtSearch is filled in the routine BindTheGrid set as the data source for dgSearch, which is the DataGrid control. The routine called BindTheGrid is located at the end of the listing. Listing 8.50 frmHowTo8_8a.vb: Filling the Results Set Based on the Letter Button
Page 342
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Pressed
Sub SetData(ByVal strFilterLetter As String) Dim odaSearch As OleDb.OleDbDataAdapter odaSearch = New _ OleDb.OleDbDataAdapter("Select " & Session.Item("KeyField") & ", " & Session.Item("SearchField") & " From " & _ Session.Item("SearchRecordSource") & " Where " & _ Session.Item("SearchField") & " Like '" & _ strFilterLetter & "%'", (BuildCnnStr("(local)", "Northwind"))) mdtSearch.Clear() odaSearch.Fill(mdtSearch) Session("SearchDataTable") = mdtSearch BindTheGrid() End Sub Private Sub BindTheGrid() dgSearch.DataSource = mdtSearch dgSearch.DataBind() End Sub Note
This routine, more than any in this How-To, shows the flexibility of this technique. You can use any table values for these properties. This is a major benefit when you think of how many places you can use this form without changing a line of code in the form.
12. Right-click on the data grid and choose Property Builder. Go to the Columns tab and add a Select button. Set the Button Type to be PushButton (see Figure 8.17) and click OK. Figure 8.17. There is no code required for this button.
Page 343
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
13. On the buttons called btnAccept and btnCancel, add the code in Listing 8.51 to the appropriate Click event of each. The btnAccept_Click routine derives the data row that is currently selected from mdtSearch using the data grid's SelectedIndex property and adding the paging that has to occur using GetPageRows(), which returns the actual rows given the current page that the user is on in the DataGrid object. You can see the GetPageRows() routine at the bottom of the listing. The KeyField Session object entry is then used to store the individual column value of drCurr in the ResultValue Session object entry. The calling page is reloaded. The ResultValue is not set in the btnCancel_Click routine. The calling page is simply reloaded. Listing 8.51 frmHowTo8_8b.vb: Storing the Resulting Key Value to the ResultValue
Session Object Entry and Returning to the Calling Page
Private Sub btnAccept_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAccept.Click Dim drCurr As DataRow Try drCurr = mdtSearch.Rows(dgSearch.SelectedIndex + GetPageRows()) Session("ResultValue") = drCurr.Item(Session("KeyField")).ToString Catch exc As Exception
Page 344
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Try
Server.Transfer(Session("CallingPage"))
End Sub Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click Server.Transfer(Session("CallingPage")) End Sub Function GetPageRows() As Integer '-- This helps synchronize the data table rows ' with the data grid page and row. GetPageRows = dgSearch.PageSize * dgSearch.CurrentPageIndex End Function 14. The last step is to add the code in Listing 8.52 for synching up pages in the data grid when the user switches pages. Listing 8.52 frmHowTo8_8b.vb: Updating the Data Grid with the New Page Number
Private Sub dgSearch_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgSearch.PageIndexChanged '-- Set the current page in the data grid. Me.dgSearch.CurrentPageIndex = e.NewPageIndex BindTheGrid() End Sub How It Works
When the user clicks on the Search button, the calling page stores values in the Session object for use in the search page, telling it what record source to use, as well as other information used for searching for the specific record and table desired:
"Customers" for the Session object entry SearchRecordSource "CustomerID" for the Session object entry KeyField "CompanyName" for the Session object entry SearchField "wfrmHowTo8_8a" for the Session object entry CallingPage
After the search page is loaded, the user clicks one of the letters to narrow down the records to look for. A data adapter is passed a SQL String made up of the Session object entries just
Page 345
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
mentioned, a data table is filled, and the data grid's DataSource property sets the data table. When the user clicks Accept, the DataTable is retrieved from the data grid, which then produces the data row that contains the key field. The key field is then stored in the ResultValue Session object entry of the search form, and the calling page is reloaded. Back on the calling form, the LoadIndividual routine is called. Then the routine is passed the
ResultValue Session object entry from the search form. The text boxes are loaded with the data
row results.
Comments
This technique shows a number of ways that the various ADO.NET objects can be used. Using the Session object and other State management methods is handy for creating pages that you want to use for more than one table. You will find use for this technique throughout your applications after you become accustomed to it. Again, you can enhance this tool in several ways. One way is to allow the user to enter a string value to type in, and narrow down the choices even more. Another way is to add a property that could be used to specify multiple columns to be displayed.
[ Team LiB ]
Page 346
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 9. Using Classes With Databases to Make Life Easier
In this chapter you will
Define a class in Visual Basic .NET Create a class that implements the interface you defined Use Visual Studio .NET tools to speed up writing ADO.NET code Control the creation and behavior of classes Implement the methods that update the database Validate data passed to properties and communicate errors to developers Write data validation code that can be reused in other classes
Writing database-access code is never a simple task, whether you use ADO.NET, DAO, RDO, db-lib, ct-lib, or OCI. Although ADO.NET makes life much easier, data still needs to be validated for size, type, or range; referential integrity must be maintained; business rules must be obeyed; exceptions must be handled; and so on. Moreover, writing the code can be tedious. Think of how many lines of code are needed to set up a DbCommand object with ten parameters and maintaining different code bases that access the same database objects can turn into weeks of busywork. The solution for any complex programming problem is to place all the related code into a flexible, reusable code component, or class. This chapter shows you how easy it is to create a class that handles all the common tasks you need to access data in the table, and more important, how this will simplify writing code for the rest of your application. This chapter also touches on several of Visual Basic .NET's objects-oriented features. Because Microsoft has made every .NET language including Visual Basic a fully object-oriented language, no book on .NET programming is complete without some discussion of object-oriented programming. This book, however, is all about database access using .NET technologies, so we shouldn't get bogged down with discussions filled with words like polymorphism, encapsulation, and inheritance. In fact, this chapter will do its best to avoid using these terms (at least until the concept is already explained) because, frankly, if you're new to object-oriented programming (OO), these terms can be confusing and intimidating. This chapter uses three terms frequently that need definition. A class is a software component that combines related data, function, and type definitions into a new type. In other words, it is a description of some properties and methods, but nothing more. The properties, methods, types, data, and so on of a class are referred to jointly as members. To use a class, you need to instantiate it with a specific set of data. An instance of a class is called an object. This chapter takes for granted that you understand how DataAdapter, DataSet, and Command objects interact to assist client applications and databases communicate. Instead, it focuses on the tools that Microsoft has provided for you to automatically generate code that creates these objects for use with specific database tables, as well as the basic principles for creating data access classes.
[ Team LiB ]
Page 347
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Page 348
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 9.1 Define a Class in Visual Basic .NET
Before writing code, you should take a moment to decide what data the class needs to contain and what actions a developer (whether it is you or a teammate) would want to perform on that data. For the moment, we'll keep it fairly simple by limiting the class to properties representing the columns in the Customers table and to methods that insert, delete, and update data.
Technique
Visual Basic .NET has a specific kind of code file that you can use to describe the public members of a class: an interface. An interface simply lists all the public variables, methods, and properties that any class implementing that interface must expose. Interfaces are an enormously powerful and flexible feature of object-oriented programs, and this chapter just scratches the surface. Because of the fact that an interface has no code, you can focus on the design of your application without the clutter of hundreds of lines of source code.
Steps
1. 2. First, create a new Windows Application project and name it CustomerClasses. To create a new interface, add a new class to your project by right-clicking on the Solution Explorer window and selecting Add Class. Name the new file CustomerInterface9_1.vb. 3. Change the class block declaration so that it reads interface instead of class, and name the class ICustomer. You should have a code file like that shown in Listing 9.1. Listing 9.1 CustomerInterface9_1.vb: An Empty Interface
Public Interface ICustomer End Interface
Add Properties to the Interface
The first items you need to add to your interface are properties to represent the columns in the Customers table. 1. Using the Server Explorer, drill down to the Customers table in the Northwind database so that you have an easy reference to the Customers table. 2. To make your code more readable, add a #Region/#End Region block with the name
Properties so that you can expand and collapse your property declarations as needed.
3. For each column in the table, add a property declaration to your interface that matches the datatype of the column and its name(see Listing 9.2). Listing 9.2 CustomerInterface.vb: The ICustomer Interface with Properties
Public Interface ICustomer #Region "Properties" 'Define properties for this interface 'that match the table structure in name and data type
Page 349
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Property CustomerID() As String Property CompanyName() As String Property ContactName() As String Property ContactTitle() As String Property Address() As String Property City() As String Property Region() As String Property PostalCode() As String Property Country() As String Property Phone() As String Property Fax() As String #End Region End Interface
More About Properties
ICustomer is a simple interface. It has only one kind of datatype a string and all of the properties are read/write. When you begin to write more complex classes, you might need more than just read/write properties. Visual Basic .NET also has read-only and write-only properties, parameterized properties, and default properties.
Read-Only and Write-Only Properties
If you have written classes in Visual Basic 6, you might be scratching your head, wondering how the code sample in Listing 9.2 declares your properties read/write. In Visual Basic 6, all that mattered was whether you wrote the appropriate Property Get and Property Let/Set blocks in your class. If you did not have a Public or Friend Property Let/Set, the property was read-only. If you did not have a Public or Friend Property Get, the property was write-only. In Visual Basic .NET, you must explicitly declare a property as read-only or write-only using the ReadOnly and WriteOnly keywords (see Table 9.1). Table 9.1. Visual Basic .NET Property Modifiers Object Purpose
ReadOnly The property cannot be modified outside of the class. WriteOnly The property can only be modified, but only methods that are internal to the class can
read the property. In our example, a developer who is using this class could change the CustomerID. Without the original CustomerID, the class won't be able to find that record in the database when updating the table, so perhaps you should make the CustomerID property read-only. To do this, simply add the ReadOnly keyword to the beginning of the property declaration as in Listing 9.3. Listing 9.3 CustomerInterface9_1.vb: Using the ReadOnly Keyword
'Adding the ReadOnly keyword before the property 'declaration makes the property read-only. ReadOnly Property CustomerID() As String Parameterized Properties
You can also create properties that accept a parameter. For example, in the Northwind database, a
Page 350
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
customer might have many orders. A parameterized property would be a perfect way to access Orders information from the Customer class. A parameterized property (see Listing 9.4) takes one or more parameters that can be used to qualify the data that the property returns. Listing 9.4 A Parameterized Property
'The nIndex parameter would be used to determine which 'item from a collection of orders should be returned. Property CustomerOrders(ByVal nIndex As Integer) As COrder
Tip One of the advantages to interfaces is the ability to rapidly define all of the classes you plan to use in your application. For the previous code example, you could create an interface called IOrder that was similar to the ICustomer interface in Listing 9.2. Instead of returning an actual class from the CustomerOrders property, you could return the IOrder interface. The interface would act as a placeholder for any object that implemented the interface. This way, you could program the Customer class and put off writing code for the Order class until later.
Default Properties
In Visual Basic 6, any property in a class could be defined as the default property for that class. For example, if the CustomerID property were declared the default property, both of the examples in Listing 9.5 would return the customer ID. Listing 9.5 Default Properties in Visual Basic 6
Dim oCustomer As CustomerData Dim strCustomerID As String 'Example 1: This code places the value of the customer ID property 'into a variable. strCustomerID = oCustomer.CustomerID 'Example 2:This code does the same thing. strCustomerID = oCustomer
In Visual Basic .NET, the only kind of property that you can declare as the default property for a class is a parameterized property. To declare a property as the default property, simply add the Default keyword prior to the property declaration, as shown in Listing 9.6. Listing 9.6 Declaring a Default Property
'Adding the Default keyword before the property declaration 'makes this parameterized property the default property for 'the class. Default Property CustomerOrders(ByVal nIndex As Integer) As COrder Add Methods to the Interface
Now that you have added all the properties you need, you need to add the various methods that a developer uses to retrieve, insert, update, and delete data from the Customers table.
Page 351
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
1. To make your code more readable, add a #Region/#End Region block with the name
Methods so that you can expand and collapse your method declarations as needed.
2. The point in wrapping a table in a class is to make access to this table as simple as possible. You could have one method to insert new rows to the database and one to update existing rows, leaving the task of determining the state of the object to the code that instantiates it. The actions of the class, however, should be as transparent to other developers as possible. To this end, the interface should only define two methods: save and delete. (The retrieve method will be defined in a subsequent section.) Add the save and delete methods to your interface, as in Listing 9.7. Listing 9.7 CustomerInterface9_1.vb: Declaring the Delete and Save Methods
#Region "Methods" 'To update or delete a record, a user would have needed to 'retrieve data before modifying any of the properties. Function Save() As Boolean Function Delete() As Boolean #End Region As I mentioned in the introduction to this chapter, one of the great advantages to wrapping up all access to a database table within a class is that you only have to write complex error-handling code once. To keep things simple, we are returning a Boolean value from each of these methods, letting other developers know whether the action failed without requiring them to write complex error-handling code. 3. Finally, add a ToString method to output all the data of the class in a string. This is extraordinarily useful for debugging. Your finished interface should look like Listing 9.8. Listing 9.8 CustomerInterface9_1.vb: The Final ICustomer Interface
Public Interface ICustomer #Region "Properties" 'Define properties for this interface 'that match the table structure in name and data type ReadOnly Property CustomerID() As String Property CompanyName() As String Property ContactName() As String Property ContactTitle() As String Property Address() As String Property City() As String Property Region() As String Property PostalCode() As String Property Country() As String Property Phone() As String Property Fax() As String #End Region #Region "Methods" 'To update record, a user would have needed to
Page 352
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'retrieve data before modifying any of the properties. Function Save() As Boolean Function Delete() As Boolean Function ToString() As String #End Region End Interface
How It Works
You might have noticed that an interface has no actual code. An interface is designed for one purpose: to define a set of public methods and interfaces that are related to a specific entity. To put this in object-oriented terminology, an interface represents an abstraction of an entity in this case, a customer. Interfaces can't function by themselves; a class must implement all of its properties and methods, which is what you will do in the next sections.
Comments
Of course, you don't really need to write an interface before writing the class, and in our current example, it might be overkill. The power of an interface really comes into play when you have multiple classes that might implement the same interface in different ways. An interface cannot exist as an object: It has no code and no place to store object data. A class that implements an interface has an explicit contract with the interface: The class must implement all the properties and methods of the interface. If you declare a variable typed to an interface, that variable could represent any object of any class that implements the interface. You've already seen several examples of interfaces in this book, such as the DataAdapter,
DataReader, Connection, Command, and other ADO.NET objects. Take, for example, the Command interface. At present, two types of Command classes exist: the OleDbCommand and the SqlCommand. Both of these classes implement the IDbCommand interface. The OleDbCommand is responsible for handling data access to any database provider with an OleDB driver, and the SqlCommand connects
directly to SQL Server. If you wrote a function that processed Command objects such as a debugging function that wrote all the properties of a Command to an error log you might need to handle both kinds. Instead of writing two functions, one for each Command type,
Public Sub WriteCommandErrorToLog(ByVal pCommand as SqlCommand) Public Sub WriteCommandErrorToLog(ByVal pCommand as OleDbCommand)
you could simply declare a function that takes a variable of type IDbCommand, which would accept an instance of either command type:
Public Sub WriteCommandErrorToLog(ByVal pCommand as IDbCommand)
The second solution is far more elegant because, before long, you could end up with Commands for Oracle, Sybase, MySql, SqlAnywhere, DB2, and so on, all of which would implement the IDbCommand interface. It might look like you're missing a few items in ICustomer. What method do you call to add new records or retrieve data from the database? If you're working with a new customer row, how does a developer set the CustomerID? A new type of method called a constructor is executed when a class is instantiated. Because constructors can't be declared in an interface, we will cover this subject in section 9.4.
[ Tea
Page 353
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html m LiB ]
Page 354
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 9.2 Create a Class That Implements the Interface You Defined
Now that you have defined the public interface of your class, you need to create a class that will implement that interface, along with all of its methods and properties. The place to start is with the properties of your class. You'll also need to create some code to test your class, so you'll need to create a form that interacts with the instances of the class.
Technique
This section uses a form with text boxes that mirror the properties of the CCustomer class. Visual Basic .NET allows you to have classes and forms within the same .vb file, so this section will have both in one file to make editing and debugging easier. After setting up the form, you need to implement the class properties. If you have worked with Property statements before, this technique will be old hat (although the syntax will be new). If you have not worked with properties and classes, you will need the following:
Steps
1.
A private variable for each property to store class data Code to modify and return that data
Create a Windows Form and name it frmHowTo9_2. Then place text boxes for each of the properties of the class, naming the text boxes with the property name, prefaced by txt. For example, the postal code text box should be named txtPostalCode. Next add command buttons called cmdDelete, cmdSave, cmdRetrieve, and cmdNew. Finally, add a RichTextBox control called rtbToString to contain the output of the ToString method. (This enables you to see how the Form maps to the data of the class. See Figure 9.1) Figure 9.1. Arrange the controls on the form you created to look like this form.
2.
Add a class declaration block to frmHowTo9_2 and name the class CCustomer. After the line
Public Class CCustomer, type Implements ICustomer. This tells Visual Basic that the CCustomer class includes all of the properties and methods of the ICustomer interface as
shown in Listing 9.9.
Page 355
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Listing 9.9 frmHowTo9_2.vb: The Empty Customer Class
Public Class CCustomer Implements ICustomer End Class 3. Copy all of the property and method declarations in the ICustomer interface, and paste them within the CCustomer class block. 4. Visual Basic .NET requires that you specify which property or method in your class implements which public member of your interface. After each property or method declaration that you just pasted into the CCustomer class block, you must add Implements
ICustomer.[Property/Method Name].
Note
Visual Basic .NET allows you to have property and method names in your class that differ from the public member names listed in your interface. This feature exists because one class can implement many interfaces, and those interfaces can have public members of the same name. Although typing
Implements ICustomer.[Property/Method Name]
after a property and method with the same name as in our example might seem frustrating, it will come in handy when you write more complex code.
5. By default, all methods, properties, and module-level variables are Public unless an access modifier, such as Private or Protected, is used (see Table 9.2). It is, however, good programming practice to use the Public access modifier, so be explicit and add Public before each member.
Table 9.2. Visual Basic .NET Access Modifiers Object Purpose You can only access the member within the class. You can only access the member from classes that are derived from (inherit from) the member's class. You can only access the member by objects within the same project. You can only access the member by derived classes within the same project. You can access the member by any object.
Private Protected Friend Protected Friend Public
Page 356
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Public ReadOnly Property CustomerID() As String _ Implements ICustomerData.CustomerID Public Property CompanyName() As String Implements ICustomerData.CompanyName Public Property ContactName() As String Implements ICustomerData.ContactName Public Property ContactTitle() As String _ Implements ICustomerData.ContactTitle Public Function Delete() As Boolean Implements ICustomerData.Delete Public Class Customer Implements ICustomer When you are finished, your code should look like Listing 9.10. Listing 9.10 frmHowTo9_2.vb: The Empty CCustomer Class
19. Note
Copying and pasting the code from the interface will result in code with an invalid syntax because of the lack of End Property and End Function/Sub lines. Although this doesn't matter for the moment, it does disable Intellisense, which normally appears after typing both Implements and the period after the Interface name. If you want to enable Intellisense, press Enter at the end of each property and method declaration. Doing so inserts the appropriate End tag. When all the tags are in the class, Intellisense is reenabled.
20. Add private variables directly below the class declaration to store class data, as shown in Listing 9.11. You should have one variable for each property. As mentioned in Chapter 3, "Viewing Data with ADO.NET," prefacing class-level variables with "m" is a Visual Basic programming convention. Listing 9.11 frmHowTo9_2.vb: Class Variable Declarations
Public Class CCustomer Implements ICustomer #Region "Class Variables" Private mstrCustomerID As String Private mstrCompanyName As String Private mstrContactName As String Private mstrContactTitle As String Private mstrAddress As String Private mstrCity As String Private mstrRegion As String Private mstrCountry As String Private mstrPostalCode As String Private mstrPhone As String
Page 357
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Private mstrFax As String #End Region 21. Write code to set and return data for the properties. Place your cursor at the end of a property declaration line, and press Enter. Visual Studio .NET automatically inserts code blocks for setting and getting your property. If you have worked with properties before, you might notice that Microsoft has changed the syntax. Listing 9.12 shows Visual Basic 6 property get and let declarations, each with its own separate block. Listing 9.12 Property Declarations in Visual Basic 6
Public Property Get PropertyName() As String PropertyName = mstrClassVariable End Property Public Property Let PropertyName(ByVal strValue As String) mstrClassVariable = strValue End Property In Visual Basic .NET, the property declaration has been combined in the format shown in Listing 9.13. Listing 9.13 Property Declarations in Visual Basic .NET
Public Property PropertyName() As String Get Return mstrClassVariable End Get Set(ByVal Value As String) mstrClassVariable = Value End Set End Property For each of your properties, add Return and the variable you declared in step 1 in the Get block. In the Set block, type the name of a variable from step 1 and = Value. All of your property declarations should now look like Listing 9.14. Listing 9.14 frmHowTo9_2.vb: Some Property Declarations for the CCustomer Class
Public ReadOnly Property CustomerID() As Customers.CCustomerID Implements ICustomer.CustomerID Get Return mCustomerID End Get End Property Public Property CompanyName() As String Implements ICustomer.CompanyName Get Return mstrCompanyName End Get Set(ByVal Value As String) mstrCompanyName = Value End Set
Page 358
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Property 22. To test your properties, you need to write a bit more code. First, you might want to implement the ToString method that returns all the object's properties as a string. Also, you will want a method that clears the form for use with a new object. Listing 9.15 shows one way to implement ToString, with each property printing on a separate line, as well as a ClearAllTextBoxes method. Listing 9.15 frmHowTo9_2.vb: The ToString Method Outputting Property Information
Public Overrides Function toString() As String Implements ICustomer.ToString Dim strReturn As String strReturn = Me.CustomerID & vbCrLf strReturn = strReturn & "Company: strReturn = strReturn & "Contact: strReturn = strReturn & "Title: strReturn = strReturn & "Address: strReturn = strReturn & "City: strReturn = strReturn & "Country: strReturn = strReturn & "Phone: strReturn = strReturn & "Fax: strReturn = strReturn & "Region Return strReturn End Function Protected Sub ClearAllTextBoxes() Me.txtAddress.Text = "" Me.txtCity.Text = "" Me.txtCompanyName.Text = "" Me.txtContactName.Text = "" Me.txtContactTitle.Text = "" Me.txtCountry.Text = "" Me.txtCustomerID.Text = "" Me.txtFax.Text = "" Me.txtPhone.Text = "" Me.txtRegion.Text = "" Me.txtPostalCode.Text = "" Me.rtbToString.Text = "" End Sub The Overrides keyword is necessary because your class already has a ToString method. You didn't write that method, but it's there. This is because every class inherits from the Object class, which defines a ToString method. Don't worry about this: You'll learn about inheritance and overriding methods later in this chapter. Now you need to add three pieces of code to the form that will instantiate the CCustomer class, and you need to allow its properties to be modified through the text boxes. 23. First, add a form-level variable called mCustomer of type CCustomer to the form. Use the new keyword in the declaration to create a new instance of CCustomer. " & Me.CompanyName & vbCrLf " & Me.ContactName & vbCrLf " & Me.ContactTitle & vbCrLf " & Me.Address & vbCrLf " & Me.City & vbCrLf " & Me.Country & vbCrLf " & Me.Phone & vbCrLf " & Me.Fax & vbCrLf " & Me.Region & vbCrLf
strReturn = strReturn & "Postal Code: " & Me.PostalCode & vbCrLf
Page 359
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
24. Next, add code to each TextBox control's TextChanged event that updates property values in mCustomer. Note that Listing 9.16 does not actually refer to mCustomer. Instead, Listing 9.16 calls an as-yet-undefined method called TextBoxChange that handles changes to mCustomer. This method is defined and explained in step 11. Listing 9.16 frmHowTo9_2.vb: The TextChanged Event of the txtPostalCode Text Box That Calls the TextBoxChange Method
Protected Sub txtPostalCode_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPostalCode.TextChanged TextBoxChange("PostalCode", txtPostalCode.Text) End Sub 25. Finally, add the TextBoxChange method that takes the value passed from each text box's
TextChanged event and writes it to the appropriate property of the mCustomer object.
Listing 9.17 shows a sample of this code, although it does not list a case for each text box. Centralizing all access to the mCustomer object in one method allows you to have one exception-handling area. Listing 9.17 frmHowTo9_2.vb: An Excerpt of the TextBoxChange Method That Writes Values in Text Boxes to Object Properties
Protected Sub TextBoxChange(ByVal pstrProperty As String, _ ByVal pstrValue As String) Try Select Case pstrProperty Case "Address" mCustomer.Address = pstrValue Case "CompanyName" mCustomer.CompanyName = pstrValue Case "PostalCode" mCustomer.PostalCode = pstrValue End Select ' Write the class' properties to the RichTextBox ' to aid debugging. Me.rtbToString.Text = mCustomer.ToString() Catch ex As Exception MsgBox(ex.Message) End Try End Sub
How It Works
Page 360
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
An instance of the CCustomer class is created when frmHowTo9_2 is created. When the user types in a text box, the TextChanged event fires, calling the TextBoxChange method. The
TextBoxChange method sets the corresponding property of the class handles any exceptions, and then writes the output of the CCustomer.ToString method to the RichTextBox.
Note In the samples for this chapter, I want to use the same form for each section's code samples without having to re-create the form each time. To this end, I have used frmHowTo9xBase as a base form class, and all the frmHowTo9_x forms inherit from this class. Some common methods, including the TextChanged events, are defined in frmHowTo9xBase rather than in each child form.
Comments
Microsoft has made several changes to property declarations, and it's worth enumerating them here. First, the Get and Set code blocks are wrapped up in one Property declaration, making neater and easier-to-read code. Second, the Return keyword is now used instead of the Property name in the Get block. Remember that no code is executed after the Return keyword. Third, there is no longer a distinction between Set and Let. In Visual Basic 6, Set was used for Object properties, and Let was used for base datatypes, such as Strings and Integers. Microsoft has eliminated this confusing distinction, and now Set is used in all cases. Just like Visual Basic 6, however, read-only properties will have only a Get block, whereas write-only properties will have only a Set block.
[ Team LiB ]
Page 361
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 9.3 Use Visual Studio .NET Tools to Speed Up Writing ADO.NET Code
The code you've written up to this point doesn't do that much. It doesn't even access the database. The next task is to write code that populates the class with data from the database, and the first step in doing this is setting up database access objects.
Technique
In Chapter 3, you learned how to fill a dataset to store data in a disconnected fashion. In this chapter, you will use a strongly typed dataset that is, a dataset with data rows that match the name and datatypes of the columns. You will learn how to use the DataAdapter Configuration Wizard to autogenerate code that initializes Command and DataAdapter objects for use with a specific table.
Steps
1. Right-click on your project and select Add New Item from the Add menu. Choose DataSet and name it dsCustomers.xsd. 2. Visual Studio .NET opens dsCustomers.xsd in Design mode. Expand the Server explorer and drill down to Data Connections, Northwind, Tables. Drag the Customers table onto the Design view. 3. Visual Studio might process for a few seconds, but afterward, you'll have a strongly typed dataset. The result? Instead of writing dataset code like this:
strCustomerID = CType(ds.Tables("Customers").Rows(0).Item("CustomerID"), String) you'll have code that looks like this:
strCustomerID = ds2.Customers(0).CustomerID A strongly typed dataset is a combination of two documents. One is a .vb file with the same name as the dataset. Visual Studio .NET will not show you the contents of this file (unless you step into it while debugging), and the contents don't appear in the Solution Explorer. The other file is an .xsd file, or a XML Schema Definition (XSD), which defines a data structure. The .vb file reads the XSD to properly instantiate a strongly typed dataset. You should always take a look at any code that is generated automatically by a tool because the tool might generate code that doesn't do precisely what you want it to do. If you have never seen an XSD, this is also a good time to learn something new. Listing 9.18 shows the XSD for the dsCustomers dataset. You can view the XSD you created by opening dsCustomers.xsd from the Solution Explorer and then clicking the XML button at the bottom of left corner of the screen. Listing 9.18 dsCustomers.xsd: The Customers XSD
It is beyond the scope of this chapter and this book to fully explain an XSD. The subject requires an entire book of its own. But it's important to point out a few areas of this XSD. The element tags are really nothing more than the properties you have already declared. Each element has a name that corresponds to a column in the Customers table, as well as a type that loosely corresponds to the datatype of the column. The element tag also has a minOccurs attribute. This attribute actually defines whether a value is required for that element. The default for the minOccurs attribute is 1, which means that the element does not allow Null values. Also, take a close look at the lines at the end of the XSD that begin with 0 Then If txtCompanyName.Text.Length > 0 Then mCustomer = New CCustomer(txtCustomerID.Text, txtCompanyName.Text) Else MsgBox("A company name is required for a new Customer.") End If Else MsgBox("A CustomerID is required for a new Customer.")
Page 387
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Exit Sub End If GetProperties() Me.rtbToString.Text = mCustomer.ToString Catch ex As Exception MsgBox(ex.Message) End Try End Sub
Private Sub btnSave_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSave.Click Try If mCustomer.Save() Then MsgBox("Save succeeded.") Else MsgBox("Save failed.") End If Catch ex As Exception MsgBox(ex.Message) End Try End Sub
Private Sub btnDelete_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDelete.Click Try If mCustomer.Delete() Then MsgBox("Delete succeeded.") mCustomer = Nothing ClearAllTextBoxes() Else MsgBox("Delete failed.") End If Catch ex As Exception MsgBox(ex.Message) End Try End Sub
How It Works
Page 388
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
When a consumer of the CCustomer class instantiates an object using the new constructor, the required properties of the object (the CustomerID and CompanyName) are set using the parameters of the constructor, whereas the optional properties are all set to zero-length strings. This constructor also sets an internal flag saying that the current instance is a new record. When the Save method is called, the internal flag tells the class that a new data row should be added to the dsCustomer dataset. Finally, the WriteChangesToDB is called and a new row is inserted into the Customers table. If the Save method is called with an existing record, the internal flag lets the class know that the data row already exists in the dsCustomer dataset, so the WriteChangesToDB method is called to update that row in the Customers table. The behavior of the Delete method also changes based on the value of the internal new-record flag. If the object instance is a new record, you don't need to delete the row from the database; therefore, the only necessary action is to dispose of the class-level variables. If the object instance is an existing record, the delete method of the data row is called. Finally, the WriteChangesToDB method is called to physically delete the row from the Customers table. Both the Save and Delete methods use the AcceptChanges and RejectChanges methods of the data row to react to exceptions thrown when making changes to the database.
Comments
One thing to note is that the Delete and WriteChangesToDB methods only return Boolean values and do not throw exceptions. The data validation code that you will see in the next section should prevent most of the exceptions that could be thrown when updating the database, so a Boolean return value is sufficient. Depending on your needs, however, this might to be too simple of an implementation. In the next section, you will learn how to create custom exceptions that will provide more error detail to consumers of your classes.
[ Tea m LiB ]
Page 389
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 9.6 Validate Data Passed to Properties and Communicate Errors to Developers
To make a class that wraps up access to a table, it is critical that the class and not the developer who is using the class makes sure that all data is valid before writing it to the database. For example, in the Customers table, the CustomerID field must be five characters in length more, no less and, of course, it must be unique. no
Phone numbers and fax numbers must also be validated. Although we don't necessarily know how many digits are in a phone number (France has eight-digit numbers, Spain has nine, and the U.S. has ten), we do know that only numbers and characters such as periods, parentheses, and hyphens are allowed. You also need to communicate with other developers when their data is not valid. It is the data class's job to make sure that invalid data doesn't make it to the database. This section presents three tasks: adding code to make sure that data passed to an object matches the column properties in the database, adding code that validates complex data types and business rules, and communicating errors to the class's consumers.
Technique
First, you need to pass errors back up the call stack. In Visual Basic 6, the accepted method was to use Err.Raise, which propagates an error number and an error message. This technique is still available to Visual Basic developers, but it retains all the old problems. If you aren't careful, programmers who are working on different components can raise the same error numbers, making error handling a potential nightmare. (If you aren't careful, you can end up raising the same error number in your own code.) You learned how to use structured exception handling in earlier chapters, but the beauty is that you can define your own exceptions as needed, with almost no code. Also, because exceptions have a name as opposed to a number, it is far easier for developers to work with your code. Finally, because exceptions are defined with a Namespace, even if two projects define an InvalidCustomerIDException, each exception will be unique. Second, you need to write code to check whether a value is valid. For the CustomerID, you simply need to check the length of the string. (Later on, you'll need to add code to check whether the ID already exists.) For phone numbers, you'll need to examine the string for invalid characters.
Steps
Because validating the maximum allowable length for all of our properties is simplest, tackle this task first. 1. Define a new exception class by inheriting from System.ApplicationException. As mentioned before, Microsoft recommends that all custom exceptions inherit from ApplicationException rather than Exception. System.ApplicationException has most of the methods and properties that you will need to communicate an exception to consumers of this class. The only property that a consumer might find useful is one that exposes what the maximum length of the property is. This would allow the consumer to communicate the error back to the user or truncate the string without having to hard-code the maximum length into his code. Adding the name of the property and the value is also a good idea. Some developers who are using your class might write one long Try...Catch block, so this information will help debug going forward. Paste the code in Listing 9.33
Page 390
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
defining the MaximumStringLengthExceededException into your code. Listing 9.33 frmHowTo9_6.vb: Class Declaration for the
MaximumStringLengthExceededException
Public Class MaximumStringLengthExceededException Inherits System.ApplicationException Private nMaxLen As Integer Public Sub New(ByVal pMaxLen As Integer, ByVal pPropertyName As String, ByVal pValue As String) ' You need to initialize the base class of this exception. ' If you do not specifically call a constructor of the base ' class, the default constructor (the one without parameters) ' will be called, if it exists. MyBase must precede the call to ' the base class's constructor so that the .NET runtime knows not ' to call a constructor in the derived class. MyBase.new("The value specified, " & pValue & _ ", exceeds the maximum " & "length of " & pMaxLen & " allowable by the " & _ pPropertyName & " property.") End Sub Public ReadOnly Property MaxLength() As Integer Get Return nMaxLen End Get End Property End Class 2. Next, modify the set block of each property in the class to check the length of the new value to see if it exceeds the maximum length of the column in the Customers table. If the length of the new value does exceed the maximum length, throw a new instance of the MaximumStringLengthExceededException. To do this, simply create an If...Then block that checks the maximum length into your class. When you have modified all of your properties, they should look like the ContactName property in Listing 9.34. Listing 9.34 frmHowTo9_6.vb: The ContactName Property Validates for the Maximum Length of the Column and Throws an Exception if the Value Passed to the Property Exceeds That Maximum Value
Public Property ContactName() As String Implements ICustomer9_6.ContactName Get Return mstrContactName End Get Set(ByVal Value As String) If Value.Length <= 30 Then mstrContactName = Value
Page 391
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Else Throw New MaximumStringLengthExceededException(30, "ContactName", Value) End If End Set End Property 3. Validating a phone number or fax number requires more than just checking the maximum length of the column. You need to make sure that only numbers and other allowable characters are in the value. First, create a new exception for invalid phone numbers by adding the code from Listing 9.35 to frmHowTo9_6.vb. Listing 9.35 frmHowTo9_6.vb: The InvalidPhoneNumberException
Public Class InvalidPhoneNumberException Inherits System.ApplicationException Public Sub New(ByVal pstrPhone As String) MyBase.New("The phone number specified, " & pstrPhone & ", is not valid.") End Sub End Class 4. Next, add a private method called ValidatePhoneNumber to check a phone number string for invalid characters, such as letters or punctuation marks, as shown in Listing 9.36. Listing 9.36 frmHowTo9_6.vb: A Function That Validates Phone Numbers
Private Function ValidatePhoneNumber(ByVal pstrPhone As String) As Boolean ' Create a string array that contains the numbers 0 to 9, as well as ' a hyphen, period, space, and parentheses. Dim cValidChars() As String cValidChars = New String(14) {"1", "2", "3", "4", "5", _ "6", "7", "8", "9", "0", "(", ")", "-", " ", "."} Dim i As Integer = 0 Dim nUBound As Integer = cValidChars.GetUpperBound(0) Dim nLBound As Integer = cValidChars.GetLowerBound(0) ' Loop through the array of valid characters and remove them ' from a phone number string. If characters are left ' in the string, the phone number is invalid. For i = nLBound To nUBound Step 1 pstrPhone = pstrPhone.Replace(cValidChars(i), "") Next pstrPhone = pstrPhone.Trim() If pstrPhone.Length > 0 Then Return False Else Return True End If
Page 392
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Function 5. Modify the set blocks of the Fax and Phone properties to call the ValidatePhoneNumber method and throw an InvalidPhoneNumberException if the phone number is not valid. Your code should look like Listing 9.37. Listing 9.37 frmHowTo9_6.vb: The Phone Property That Validates Phone Numbers
Public Property Phone() As String Implements ICustomer.Phone Get Return mstrPhone End Get Set(ByVal Value As String) If Value.Length <= 24 Then If ValidatePhoneNumber(Value) Then mstrPhone = Value Else Throw New InvalidPhoneNumberException(Value) End If Else Throw New MaximumStringLengthExceededException(24, "Phone", Value) End If End Set End Property 6. The last piece of data that you need to validate is the CustomerID. You need to validate for the string length, and for new customers, you need to validate for the uniqueness of the proposed CustomerID. Validating for the proper length of a CustomerID is simple. First, add a new exception called InvalidCustomerIDException, as shown in Listing 9.38. Listing 9.38 frmHowTo9_6.vb: Declaration of the InvalidCustomerIDException
Public Class InvalidCustomerIDException Inherits System.ApplicationException Public Sub New(ByVal pstrID As String) MyBase.New("The customer ID specified, " & pstrID & ", is not valid") End Sub End Class 7. Then add the method from Listing 9.39, which checks the length of a CustomerID string and ensures that the string has no whitespace. Listing 9.39 frmHowTo9_6.vb: The ValidateCustomerID Method
Private Function ValidateCustomerID(ByVal pstrID As String) As Boolean ' Strip out any leading or trailing spaces. pstrID = pstrID.Trim
Page 393
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
' A CustomerID must have five characters. If pstrID.Length = 5 Then Return True Else Return False End If End Function 8. Now add code like that in Listing 9.40 to your constructor that validates the CustomerID, and, if that value is invalid, throws an InvalidCustomerIDException. Listing 9.40 frmHowTo9_6.vb: An If...Then Block to Wrap Around Your Constructor Code
If ValidateCustomerID(pCustomerIDToRetrieve) Then ' Your original constructor code goes here. Else Throw New InvalidCustomerIDException(pCustomerIDToRetrieve) End If 9. The final piece of validation code you need to add is a function that checks for the existence of a CustomerID before a new Customer object is instantiated. You could use the data access objects you defined in CCustomerData, but for performance purposes, you should create a new command object and use the ExecuteScalar method as shown in Listing 9.41; this method requires less interaction with the database. Listing 9.41 frmHowTo9_6.vb: The DoesCustomerIDExist Function
Private Function DoesCustomerIDExist(ByVal pstrID As String) As Boolean Dim strSQL As String = "SELECT COUNT(*) FROM Customers " & _ "WHERE CustomerID = '" & pstrID & "'" Dim cmd As New System.Data.OleDb.OleDbCommand(strSQL, oleCnn) Dim fExists As Boolean oleCnn.Open() fExists = CBool(cmd.ExecuteScalar()) oleCnn.Close() Return fExists End Function Add an extra If...Then block in the constructor used to create a new Customer row and you're ready to start testing your new code. Your existing code for frmHowTo9_6 should suffice for testing. You made sure to handle exceptions thrown from properties in section 9.2.
How It Works
Page 394
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Much of the code in this section qualifies and extends the properties you have already defined and implemented. This section has two key concepts. Validating data is a critical part of any application, although the examples in this section use validation techniques you should already be familiar with. The next section will take data validation to a new level. The most important concept is declaring your own exceptions. Communicating errors to other parts of the application is, perhaps, more important than the business logic you implement. When it works, it works, but when something goes wrong, providing enough information about the error is far more important. Creating new exceptions is an elegant and readable way to communicate and handle errors.
Comments
Hardcoding the maximum column length into the property set block as recommended in this section isn't necessarily the best solution to this problem. If you decide to increase or decrease the length of the column in the database, you must search through all of your source code to find every place that value was hard coded. Using constants is one way around this, but your options still are fairly limited. The strongly typed dataset you created earlier has the potential to provide an elegant solution to this problem. The XSD that underlies the dataset could define many of the data rules in your tables, including the maximum length of columns. Also, the actual dataset exposes this information in its properties and methods. The problem is that Visual Studio .NET does not generate XSDs with such strict definitions.
[ Tea m LiB ]
Page 395
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 9.7 Write Data Validation Code That Can Be Reused in Other Classes
As you were writing the PhoneNumber and CustomerID validation code in the previous section, you might have thought that this code would be extraordinarily useful in other parts of the Northwind application. For example, the Suppliers and Employees tables also have Phone and Fax fields, and the CustomerID column is also defined in the Orders table.
Technique
In this section, you will pull the data validation code you wrote for both the PhoneNumber and CustomerID columns and create independent objects that encapsulate your existing validation logic. Then you will update the CCustomer class to make use of these new classes. The CCustomerID class will be a simple class that performs two functions: checking the length of the ID and looking in the database to see if the CustomerID exists. For the PhoneNumber data validation, you will learn how to create an entire object model that will provide you with data validation for different types of phone numbers with a bare minimum of code. And, just for the fun of it, you will learn how to use the same base class you use to validate phone numbers to validate Social Security numbers.
Steps
1. Add a new class file to your project by right-clicking on the project in the Solution Explorer window and selecting Add Class from the Add submenu. Name the new class CCustomerID.vb. 2. Copy the DoesCustomerIDExist and ValidateCustomerID methods from the CCustomer class into the CCustomerID class. Rename them Exists and Validate, respectively. 3. Copy the InvalidCustomerIDException from CustomerClass.vb and paste it inside the
CCustomerID class. This makes your exceptions directly related to the CCustomerID.
4. One gap in splitting off the CustomerID property into its own class is that some parts of your application might want a read/write CustomerID property, whereas others, such as the CCustomer class, need a ReadOnly property. Instead of having a Boolean set to lock the property, a more flexible way is to add an event to your class that is called before setting the property, allowing a containing class to cancel the change. 5. 6. Public Event BeforeUpdate(ByVal pstrCustomerID As String, ByRef pfCancel As Boolean) 7. Now add a new property called CustomerID to the CCustomerID class, as shown in Listing 9.42. This property should raise the BeforeUpdate event, and if the changes are not cancelled, call the Validate method and throw an InvalidCustomerIDException if the
CustomerID is invalid.
Listing 9.42 CCustomerID.vb: The CustomerID Property of the CCustomerID Class
Property CustomerID() As String Get Return mstrCustomerID
Page 396
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Get Set(ByVal Value As String) Dim fCanceled As Boolean RaiseEvent BeforeUpdate(Value, fCanceled) If Not fCanceled Then mfValid = Validate(Value) If mfValid Then mstrCustomerID = Value Else Throw New InvalidCustomerIDException(Value) End If End If End Set End Property 8. Then add a new constructor that accepts a CustomerID as a parameter. That constructor, shown in Listing 9.43, should call the property statement, which will handle validation. Listing 9.43 CCustomerID.vb: The Constructor for the CCustomerID
ClassPublic Sub New(ByVal pID As String) Me.CustomerID = pID End Sub 9. You're almost finished with the CCustomerID class, except for one subtle issue: pointers. Everything you've written in this chapter so far has used base datatypes, so you haven't had to worry about copying values between function calls. But objects work differently than base datatypes do. The issue is with ByVal and ByRef. With base datatypes, the distinction is fairly straightforward: ByVal passes a copy of the value of the variable to the function. The called function could do whatever it pleased to the passed value without impacting the value of the variable in the calling function. ByRef passes the called function a pointer instead of the value, so any change made to the variable in the called function is made to the variable in the calling function. With objects such as CCustomerID, it's completely different. Whether you use ByVal or
ByRef, you're still working with a pointer. The called function will always modify the object
that the calling function passes. The difference is in reassigning the pointer. ByVal passes a pointer to an object. If the called function changes the pointer to a new object, the calling function will still point at the original object. ByRef passes a pointer to a pointer to an object. If the called function changes the pointer to a new object, the calling function will now point at the new object instead of the original object. The point(er) here is in the constructors. You want to provide a way for other developers to create copies of the class easily, or you might end up with the same CCustomerID object being used simultaneously in a potentially conflicting fashion. The solution? Add a
Page 397
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
constructor to the CCustomerID class that accepts a CCustomerID object as a parameter, as shown in Listing 9.44. Listing 9.44 CCustomerID.vb: An Object-Based Constructor for the CCustomerID Class
Public Sub New(ByVal pID As CCustomerID) ' Both ByVal and ByRef pass object pointers, so if you ' want to create a new CustomerID instance based on an ' existing instance, you need to copy the values of the ' base datatypes to a new instance. Me.CustomerID = pID.CustomerID End Sub 10. Updating the CCustomer class is not difficult, but it does require many small, similar changes, including the following:
o o o
Retyping variables Removing code validating CustomerIDs and related exception throwing Calling CCustomerID's object-based constructor from Listing 9.43 each time a
CCustomerID object is passed into a CCustomer object o
Adding .CustomerID after every CCustomerID variable where the string value is needed The constructor in Listing 9.45 that you use to create new customers in the database is a good example of all of these changes. Listing 9.45 CCustomerID.vb: An Excerpt of a CCustomer Constructor as Modified to Use the CCustomerID Class
Public Sub New(ByVal pCustomerID As CCustomerID, ByVal pCompanyName As String) ' Change A: retyping variables ' Instead of accepting a string that has to be validated, ' this constructor accepts a CCustomerID object that by ' definition is valid. If pCustomerID.Exists Then ' Change B: removing code validating CustomerIDs ' If you recall, there used to be an additional condition ' in this If... Then that checked the length of the CustomerID. ' Now, the CCustomerID guarantees a valid CustomerID. mdsCust = New dsCustomers() mfNew = True ' Change C: using the object-based constructor ' Just to make sure, create a new CCustomerID object. If you ' don't, consumers of this class will retain a pointer to this ' object instance, allowing that consumer to change the value ' of the shared CCustomerID object unbeknownst to the CCustomer object.
Page 398
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
mCustomerID = New CCustomerID(pCustomerID) Me.CompanyName = pCompanyName Else ' Change D: calling the CustomerID property when you need a string. ' When you throw an InvalidCustomerIDEException, you won't necessarily ' have a valid CustomerID, so this exception has to accept a string ' instead of an object. This InvalidCustomerIDException is used to express ' that the CustomerID for the new customer already exists in the database. Throw New CCustomerID.InvalidCustomerIDException(pCustomerID.CustomerID) End If End Sub Tip
One way to identify all these changes is to change the type of the CustomerID property in the ICustomer interface, as well as the name of the class-level variable in the CCustomer class that holds CustomerID values. Because this will invalidate much of the code utilizing CustomerIDs, Visual Studio .NET will put a wavy blue line under the code you need to modify.
11. You will also need to redeclare the mCustomerID variable using the WithEvents keyword and add an event handler that cancels the change, as shown in Listing 9.46. Listing 9.46 frmHowTo9_7.vb: Adding Event Handlers to CCustomer to Handle the
CCustomerID BeforeUpdate Event
Private WithEvents mCustomerID As CCustomerID Private Sub mCustomerID_BeforeUpdate(ByVal pstrCustomerID As String, ByRef fCancel As Boolean) Handles mCustomerID.BeforeUpdate fCancel = True End Sub The next task in this section is to provide similar validation functionality for phone numbers that can be used throughout your application. At the end of this task, you will have four separate classes, all of which extend the functionality of a fifth base class. Before you begin coding so many classes, it is always a good idea to plan precisely what you want to write. Figure 9.8 is a class diagram that describes the classes you're going to write and their relationship to each other. The class at the top of the diagram is our base class. The base class has only one purpose: It contains a method that checks a string of numbers to see whether the string has invalid characters. All of the other classes will inherit this validation method, but each class will change the definition of valid characters in the string. Figure 9.8. A class diagram describing the classes to be developed in section 9.7.
Page 399
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
According to the class diagram, this class has only seven members: two variables ( cValidChars and mstrValue), one property (StringValue), three methods (IsValid,
ThrowException, and DefineValidChars), and one member class ( InvalidNumberStringException).
You might have noticed a symbol before each member declaration. This symbol refers to the accessibility of the member. A minus sign ( ) means the member is Private, a number sign (#) means Protected, and a plus sign (+) means Public. If this doesn't make sense at the moment, don't worry. It will be much clearer when you see the code. 12. Because all of the classes rely on code in the base class, you should start by defining the
CNumberString class. This class will be the most complex in this hierarchy, so you will walk
through it step-by-step. First, right-click on your project in the Solution Explorer and select Add Class from the Add submenu. Name the class PhoneDatatypes.vb. 13. Declare the CNumberString class block, as well as the InvalidNumberStringException member class, using the MustInherit keyword, as shown in Listing 9.47. The
MustInherit keyword means that the CNumberString class cannot be instantiated
directly. Instead, the class must be inherited by another class for its members to be accessed. Listing 9.47 PhoneDatatypes.vb: Declaration of the CNumberString Abstract Class
Public MustInherit Class CNumberString
Page 400
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Public MustInherit Class InvalidNumberStringException Inherits System.ApplicationException Protected Sub New(ByVal pstrMessage As String) MyBase.New(pstrMessage) End Sub End Class End Class A class that is declared with the MustInherit keyword is known as an abstract class, and it is best described as a hybrid between an interface and a class(see Table 9.3). Like an interface, instances of an abstract class cannot be created directly, and its methods and properties need not have code. Like a regular class, an abstract class does contain some implemented methods and properties, and even though it cannot be instantiated, it can have constructors.
Table 9.3. Visual Basic .NET Class Inheritance Permission Keywords Keyword Definition Instances of the class cannot be created directly, and the class must be inherited to be used.
MustInherit
NotInheritable The class is in a finalized state and cannot be
used as a base class.
14. Declare the two class-level variables: cValidChars and mstrValue. Note that both variables are declared as protected. This means that the variables will only be accessible to derived classes because those classes will need to modify the list of valid characters and might need to access the string value. 15. Declare the DefineValidChars, IsValid, and ThrowException methods as shown in Listing 9.48. You might also want to add an Event declaration that fires before updating the StringValue property. (If you do not, you won't be able to catch changes made to properties in CCustomer; thus, you won't be able to check for the maximum length of the Phone and Fax properties.) Listing 9.48 PhoneDatatypes.vb: Declaration of the IsValid, DefineValidChars, and
ThrowException Methods
Public Sub New() DefineValidChars() End Sub Public Event StringValueBeforeUpdate(ByVal pstrValue As String, _ ByRef pCancel As Boolean)
Page 401
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Protected Overridable Sub DefineValidChars() cValidChars = New String(9) {"1", "2", "3", "4", "5", _ "6", "7", "8", "9", "0"} End Sub Public Overridable Function IsValid(ByVal pstrNumber As String) As Boolean Dim i As Integer = 0 Dim nUBound As Integer = cValidChars.GetUpperBound(0) Dim nLBound As Integer = cValidChars.GetLowerBound(0) For i = nLBound To nUBound Step 1 pstrNumber = pstrNumber.Replace(cValidChars(i), "") Next pstrNumber = pstrNumber.Trim() If pstrNumber.Length > 0 Then Return False Else Return True End If End Function Public MustOverride Function ThrowException() As InvalidNumberStringException The IsValid method is the key to the whole thing, and is really just the
ValidatePhoneNumber method from the previous section. The DefineValidChars method populates the list of valid characters. It has been separated from the IsValid method so
that derived classes can easily redefine the list of valid characters without having to rewrite the IsValid method. Both of these methods have been declared as Overrideable. This means that a derived class has the option of redefining either of these methods. In previous sections, you regularly overrode constructors when you created custom exceptions based on the ApplicationException. (Actually, constructors of a base class are never exposed as constructors of a derived class, so they are overridden by default). If you recall, you can still access the overridden constructor within your class by using the MyBase keyword. The same goes for methods: You can call the overridden method within your class by using the MyBase keyword. The ThrowException method is declared using the MustOverride keyword (see Table 9.4 ), and it is an abstract method. Any class that inherits from the CNumberString class must implement this method. This works just like a method that is declared in an interface, except that you do not need to use the Implements keyword in the method declaration.
Table 9.4. Visual Basic .NET Member Override Keywords Keyword Definition The method overrides the member of the base class with the same signature.
Overrides
Page 402
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Overrideable MustOverride
The method can be overridden in a derived class. The method must be overridden in every derived class.
NotOverrideable The method can never be overridden by a
derived class.
16. The last member to implement is the StringValue property defined in Listing 9.49. Note that properties cannot be overridden. Listing 9.49 PhoneDatatypes.vb: The StringValue Property
Public Property StringValue() As String Get Return mstrValue End Get Set(ByVal Value As String) Dim fCancelChange As Boolean If isValid(Value) Then RaiseEvent StringValueBeforeUpdate(Value, fCancelChange) If Not fCancelChange Then mstrValue = Value End If Else Throw ThrowException(Value) End If End Set End Property It doesn't look like much is going on here, but this is the most interesting member in the class. Why? This member is responsible for all data validation, including validation kicked that constructors kick off. All of the methods called in this member are overrideable, though. In other words, the IsValid method that it looks like you're calling could be any IsValid method from any derived class. And the ThrowException method isn't even defined in this class. The actual method called always will be defined in a derived class. 17. The simplest derivation of the CNumberString class is a class that handles phone number extensions. (You will use this as part of a BusinessPhone number class later.) A phone extension contains only numbers, so you don't need to modify the IsValid method or the
DefineValidChars method. As you can see in Listing 9.50, all you need is to define an
exception, a method to throw it, and a constructor that calls the constructor of the CNumberString class and the StringValue property. Listing 9.50 PhoneDatatypes.vb: A Simple Class for Phone Number Extensions Derived from the CNumberString Class
Page 403
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Public Class CExtension Inherits CNumberString Public Class InvalidPhoneExtensionException Inherits CNumberString.InvalidNumberStringException Public Sub New(ByVal pstrPhoneNumber As String) MyBase.New("The phone extension specified, " & pstrPhoneNumber & ", contains invalid characters.") End Sub End Class Sub New(ByVal pstrExtension As String) MyBase.New() Me.StringValue = pstrExtension End Sub Public Overrides Function ThrowException(ByVal pstrInvalidExt As String) As InvalidNumberStringException Throw New InvalidPhoneExtensionException(pstrInvalidExt) End Function End Class So what's going on? The CExtension constructor calls the constructor of the CNumberString class, which calls CNumberString.DefineValidChars. Then, the string value is passed to the CNumberString.StringValue property, where its validity is checked. (If that doesn't make sense, create an instance of the class and step through it line by line.) 18. To take the example a step further, create a phone number class that inherits from the
CNumberString class. As in the CExtension class from Listing 9.50, , you will need to
declare an exception, a method to throw it, and a constructor to create the class. The only substantive change in Listing 9.51 is the addition of several new valid characters including parentheses, periods, and hyphens to the list of valid characters. Listing 9.51 PhoneDatatypes.vb: An International Phone Number Extension of the
CNumberString Class
Public Class CPhoneNo Inherits CNumberString Public Class InvalidPhoneNumberException Inherits CNumberString.InvalidNumberStringException Public Sub New(ByVal pstrPhoneNumber As String) MyBase.New("The phone number specified, " & pstrPhoneNumber & _ ", contains invalid characters.") End Sub End Class
Page 404
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Sub New(ByVal pstrPhoneNo As String) MyBase.new() Me.StringValue = pstrPhoneNo End Sub Sub New(ByVal pPhoneNo As CPhoneNo) Me.New(pPhoneNo.StringValue) End Sub Public Overrides Function ThrowException(ByVal pstrInvalidPhone As String) _ As InvalidNumberStringException Throw New InvalidPhoneNumberException(pstrInvalidPhone) End Function
' This is the only substantive change. This sub redefines the DefineValidChars ' method so that when this method is called in the base class's constructor, it will ' call this method instead of the original method. Protected Overrides Sub DefineValidChars() cValidChars = New String(14) {"1", "2", "3", "4", "5", _ "6", "7", "8", "9", "0", _ "(", ")", " ", ".", "-"} End Sub End Class What's going on? The CPhoneNo constructor calls the constructor of the CNumberString class, but because you overrode DefineValidChars, CNumberString.New actually calls
CPhoneNo.DefineValidChars instead of CNumberString.DefineValidChars.
Tip
You can combine the CExtension and CPhoneNo classes to create a CBusinessPhone class that would be far more useful in an application of this sort. A sample of this code is included in PhoneDatatypes.vb.
19. Utilizing the phone number class in your existing code is a process similar to what you did to integrate the CCustomerID class in earlier in this section. Again, you will need to do the following:
o o o
Retype variables. Remove code validating phone numbers and related exception throwing. Add .StringValue after every CPhoneNo variable where the string value is needed.
o
Calling CPhoneNo's object-based constructor from Listing 9.51 each time a
Page 405
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html CCustomerID object is passed into a CCustomer object.
20. More important, you will need to move the maximum length validation to event handlers, as shown in Listing 9.52. The value of the phone number contained in the CphoneNo class can be changed without changing the phone number property, which is just a pointer. Listing 9.52 PhoneDatatypes.vb: An Event Handler for the mFax Variable in the
CCustomer Class
Private Sub mFax_StringValueBeforeUpdate(ByVal pstrValue As String, ByRef pCancel As Boolean) Handles mFax.StringValueBeforeUpdate If pstrValue.Length <= 24 Then pCancel = False Else pCancel = True Throw New MaximumStringLengthExceededException(24, "Fax", pstrValue) End If End Sub 21. The final code example of this chapter will take another look at the CNumberString base class and suggest another potential use for it: Social Security numbers. A Social Security number is similar to a phone number in that it is a string of numbers formatted with a limited set of characters. In the Northwind database, you did not have the option of strictly validating a phone number because you could not be sure of the specific format that the customer's country might use. A Social Security number is a different story: Two hyphens must be present at specific locations in the string. The complete CsocialSecurityNo class is defined under Listing 9.53. Listing 9.53 PhoneDatatypes.vb: Another Extension of the CNumberString Class, This Time for SSNs
Public Class CSocialSecurityNo Inherits CNumberString Public Class InvalidSSNException Inherits CNumberString.InvalidNumberStringException Sub New(ByVal pstrSSN As String) MyBase.New("The SSN specified, " & pstrSSN & ", is not valid.") End Sub End Class Sub New(ByVal pstrSSN As String) MyBase.new() StringValue = pstrSSN End Sub Sub New(ByVal ssn as CSocialSecurityNo)
Page 406
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
MyBase.New(ssn.StringValue) End Sub Public Overrides Function IsValid(ByVal pstrSSN As String) As Boolean If MyBase.IsValid(pstrSSN) Then Dim nFirstHyphen As Integer = pstrSSN.IndexOf("-") ' An SSN must have a hyphen at index 3 and 6. If nFirstHyphen = 3 Then If pstrSSN.IndexOf("-", nFirstHyphen + 1) = 6 Then If pstrSSN.Chars(0) = "0" Then Return False Else Return True End If Else Return False End If Else Return False End If End If End Function Public Overrides Function _ ThrowException(ByVal pstrInvalidSSN As String) As InvalidNumberStringException Throw New InvalidSSNException(pstrInvalidSSN) End Function Protected Overrides Sub DefineValidChars() cValidChars = New String(10) {"1", "2", "3", _ "4", "5", "6", "7", "8", "9", "0", _ "-"} End Sub End Class Just like the CPhoneNo example, the DefineValidChars is overridden to allow a hyphen to be valid character. The real change is in the overridden IsValid method. First, the IsValid method for the base class (CNumberString.IsValid) is called to verify that the string only contains numbers and hyphens. Then, the string is checked to verify that the hyphens are in the proper location. When the StringValue property is set, the overridden IsValid method in
CSocialSecurityNo is called, which in turn calls the IsValid method in CNumberString.
Page 407
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html How It Works
The CCustomerID example in the beginning of this section is a perfect example of encapsulation and a simple example of the goal of object-oriented code. One piece of business logic the definition of a CustomerID and a way to determine its uniqueness and/or existence is wrapped up in one piece of small, reusable code. Any other class that represents a table containing a CustomerID can utilize the CCustomerID class and is guaranteed to always have a valid value whose existence in the database can be verified painlessly. The CNumberString class, in combination with its derived classes, extends the reusability concepts exhibited in the CCustomerID class. Inheritance might be a new concept and a new way of thinking about code, but the implementation of inheritance is simple. Any time that you inherit from another class, all the code in that base class is immediately available to you.
Comments
Inheritance is a powerful, flexible way to write code, not only quickly, but in a way that is much easier for other developers to understand. If the earlier samples make sense, you might be tempted to design extraordinarily complex object models utilizing a substantial amount of inheritance, polymorphism, and abstraction. Two notes of caution:
There is slightly more runtime overhead with derived classes because the CLR must resolve which members of the object must actually be called. This cannot be done at compile time, because in many cases, the specific type of the object is ambiguous in static source code.
The clarity and readability of object-oriented code can be countered by an overly complex object model. Always keep it simple. If that means a bit of "editor inheritance" here and there, so be it. It's better than object-oriented spaghetti code.
[ Team LiB ]
Page 408
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 10. Creating Reports Using Crystal Reports
In this chapter you will
Create a report using Crystal Reports report expert Display a report that was created Add calculated fields to the Crystal Reports report Select whether the report will be displayed, printed, or exported using Visual Basic .NET code
Determine which records will be printed at runtime Print labels and control the order in which records will be printed Create an onscreen report that contains hyperlinks
Crystal Reports is the report writer that has been included in Visual Basic since 1993. It uses a banded approach, as do many other report designers, such as Access's report writer and dBASE. Crystal Reports is included in Visual Studio .NET for use with both Windows Forms and Web Forms. You can deploy your reports and have them store locally or even using a Report Web Service. This chapter uses Windows Forms to show how to create and run Crystal Reports. Note Be sure to verify the licensing before deploying reports that were created using Crystal Reports. In Visual Studio help, look up Crystal Reports and then licensing.
[ Team LiB ]
Page 409
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.1 Create a Report Using Crystal Reports Report Expert
I have created quite a few applications that allow the users to manipulate data in various ways. Now I need to create some reports so that I can present information for my clients and users. How do I create a report with Crystal Reports using one of these Experts I have heard about?
Technique
You can create a report and include it in your projects as needed.
Getting Started Creating a Crystal Report
After right-clicking on your project in the Solution Explorer, you need to choose Add New Item from the Add menu item. You then can pick Crystal Report from the templates and name it appropriately. Note If you name your reports with the prefix of rptReportName, you will be able to find all your reports in one location.
After you have clicked the Open button on the dialog box, you are presented with the Crystal Report Gallery dialog box, shown here in Figure 10.1. Figure 10.1. These Experts can save you time when you're creating reports.
Page 410
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Crystal Reports includes wizards called Experts. These Experts assist you in performing certain tasks, from creating a whole report to creating an individual formula for a field. Experts are actually made up of other Experts. For instance, the Report Expert utilizes the Formula Expert within itself; however, you also can take advantage of the Formula Expert from within the Report Designer.
Types of Reports You Can Create with the Report Expert
This How-To will discuss the Report Expert. This Expert creates various types of reports, listed in Table 10.1, in alphabetical order. Table 10.1. Types of Reports Created by the Report Expert Report Type Crosstab Description
Crosstab reports give you a cross-tabulation of your data, such as sales of customers by years.
Drill Down This report is broken down into sections that start out as hidden, and then allow the user to "drill down" further into the information. An example of this would be a report that lists customers. When the user clicks on a particular customer, the invoices for that customer are displayed. Next, when you click on a particular invoice, its line items (or details) can be displayed. Form This report helps to create preprinted forms that use company logos and forms. Examples of this type include invoices. Forms letters, such as late notices and sales letters, are created using this expert.
Form Letter
Mail Labels This expert allows you to create mailing labels that are any size and any number of columns. Standard The standard report is just that a standard list report that lists your information. It allows you to group and sort information, include formulas, and set an overall format for the report. This is the report that will be demonstrated for this How-To.
SubReport This report helps you to create main reports that utilize subreports. An example is invoices for customers. If the Standard report type is highlighted, click OK, and the Standard Report Expert dialog opens, as shown in Figure 10.2. Figure 10.2. The tabs on this dialog box are actually experts in their own rights.
Page 411
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Tabs Included in the Standard Report Wizard
Included on the Standard Report Wizard are the following tabs:
Data. Specify the database and table that you will be using for this report. You will have a number of different choices from datasets within the current application to OLEDB connections. For this chapter, you will be creating an OLEDB connection to the Northwind database.
Fields. After you have selected your record source, you then get a list of the fields from within your record source (see Figure 10.3). Figure 10.3. Besides fields from your table, you can create formulas (expressions) as well.
Page 412
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
In addition to creating formulas, you can view the data using the Browse Data option and locate fields using the Find Field option.
Group. This tab allows you to specify the group levels you want to include. An example you will see here groups the customer by region (see Figure 10.4). Figure 10.4. It is often useful to be able to organize your reports based on groupings, such as the Region field in this report.
Tip
Page 413
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
If you want to have a field used for grouping, then you will most likely not want to have it listed in the detail section. It is important that you do not choose it back on the Field tab; just choose it from the Group tab. Of course, if you accidentally include it in the detail section after the report is created, you can always delete it later from the report while you're in the Design view.
Total. This tab allows you to specify which fields you want to summarize in the group footers and report footer.
Top N. You can set how you want the groups sorted, based on the totals set by the last tab, Total.
Chart. Create a chart of your data. Select. Filter which records you want to have reported based on field values. You will see how to do this at runtime in How-To 10.5.
Style. You can give your report a number of different looks. You also can specify the title of your report (see Figure 10.5.) Figure 10.5. This chapter will stick to using the Red/Blue border style.
After you have finished specifying your report features, click Finish. Your report will now be displayed in Design view (see Figure 10.6). Figure 10.6. The finished product.
Page 414
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
For this How-To, you want to get to the point where you have the report created. The next How-To describes how to actually view the report on a Windows Form. You can find all the examples in this chapter in the Solution called Visual Basic .NET the Web site. Chapter 10 on
Steps
Open the Visual Basic .NET Chapter 10 solution. In the Solution Explorer, you see the report rptHowTo10_3.rpt. You then see a report that looks similar to the one in Figure 10.7. 1. Right-click on your project in the Solution Explorer, and choose Add New Item menu item from the Add menu item. Type a name for the report in the Name field, and click Open. The Crystal Report Gallery dialog box opens. 2. Leaving the defaults as they are, which is to use the Report Export and create a Standard report, click the OK button. You are taken to the Report Expert, with the Data tab displayed. 3. Double-click on the OLE DB (ADO) node in the Available Data Sources tree if you haven't chosen a data source before. The OLE DB (ADO) dialog box opens the option and asks you to choose an OLE DB provider. Choose Microsoft OLE DB Data Provider for SQL Server (see Figure 10.7) and click Next. You are requested to enter connection information. For this page, type (Local) for the server, check Integrated Security, and type Northwind for the database (see Figure 10.8). Click Finish. Your Available Data Sources will now include (Local) under the OLE DB (ADO) node and Northwind under the local connection. Figure 10.8. Information that is needed to create the Northwind connection.
Page 415
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Expand the tree under Northwind to get to the first DBO, and then expand Tables. You then see the tables listed, including the Customers table. Highlight the Customers table, and click Insert Table. The table is displayed in the Tables in Report list (see Figure 10.9.) Click Next. Figure 10.9. After you have the Tables node expanded, it is easy to tell where your record sources come from.
5.
From the Fields tab, add the fields as displayed in Figure 10.10, and then click Next. You are
Page 416
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
taken to the Group tab. Figure 10.10. These fields will be displayed in the Details section of the report.
6.
Under the (local) node in the field tree, select Region from the Customers table, and click Add. Now you're ready to choose the style. Skip over to the Style tab by clicking on it directly.
7.
Type My First Report for the title of the report, and then select Red/Blue Border for the style. Click Finish, and your report is displayed in Design mode. Figure 10.7. Choosing the OLE DB (ADO) Data provider.
Page 417
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
The next How-To explains how to display your report. You can modify your report by both clicking on controls and changing them in the Design mode, or right-clicking on one of the section bodies (not the gray bands), and choosing Report, Report Expert. This takes you right back into the Report Expert to let you make some tweaks when you have to. You will also see the various tabs of the Report Expert as you right-click and choose some of the individual Experts to give you a hand. Try these right now. Take some time to right-click on some of the section bodies, and select some of the choices from the pop-up menu to play with, such as Report, then Style Expert.
[ Team LiB ]
Page 418
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.2 Display a Report That Was Created
The report doesn't do me much good in Design mode. How do I go about viewing the report?
Technique
You can review a report in a couple of ways. You can view a report either using a Windows Form or a Web Form. Either way, you will also use a control called the Crystal Report Viewer.
Introducing the Crystal Report Viewer
The Crystal Report Viewer is a control that is available in the Toolbox. It is the last control by default. Crystal Report Viewer does far more than just let you view your document on the form. With the Viewer, you can do any of the following:
View the report on the form. Zoom in and out on the document. Expand and collapse groupings on the document. Print from the Viewer. Export from the Viewer. Move around in the document Search for text within the report.
You can see an example of the Crystal Report Viewer on a Windows Form in Figure 10.11, where the example form from this How-To is displayed. Figure 10.11. The Crystal Report Viewer provides the user with several features, but most of the features can be disabled if necessary.
Page 419
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Sometimes you might not want the user to have all the features that come with the Viewer. The good news is that the Viewer actually has its own object model whereby you can set some of the properties at design time or runtime. The Viewer even has an event model that you can program. You can see the object model for the Windows Form CrystalReportViewer in Figure 10.12. Figure 10.12. Using the object model displayed here, you have almost complete control over the Viewer behavior.
Page 420
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Although you can make the Viewer stand on its head using the object model, to get started, you really only have to set one property: the ReportSource. Just as it sounds, the ReportSource tells the Viewer which report to display. You can set the
ReportSource in a variety of ways. You can set the ReportSource property to the file path and
name of a report, or you can create what is called a strongly typed report document.
Specifying the ReportSource by Using the Report
To specify a report file, click on the down arrow in the ReportSource property, and choose (Browse). The Open an Existing Crystal Report dialog box opens. There, you can look for the report that you want to assign within your project folder. The bad part about assigning the report file directly is that when you move the application, the file path is not updated. A better way to assign the ReportSource is to use a Report Document to strongly type the report.
Specifying the ReportSource Using a Strong Typed Report
When you're using strong typed reports, you can move your application and the report file without having to re-establish the file path to the report. To accomplish this, you use what is called a Report document. You can find the Report document in the Component list. In there, it is called ReportDocument. When you pull the ReportDocument component onto your form, you are asked to supply a report to be strong typed. After you have chosen your report, the ReportDocument appears in your Component tray. When you assign the ReportSource, the ReportDocument appears first in the list (see Figure 10.13). Figure 10.13. Using the ReportDocument is the way to go when you're assigning reports to Viewers.
Steps
Page 421
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Open and run the Visual Basic .NET Chapter 10 solution. Click on the button labeled How-To 10.2. You immediately see the report show up that was created in the last How-To. Play with the toolbar buttons on the Viewer to see how they work. When you maximize the form, you the Viewer expands as well. That is because the Viewer is anchored (see Figure 10.14). 1. 2. 3. Create a Windows Form. Drag a CrystalReportViewer control from the toolbox onto the form. Drag a Report document from the Component list onto the form. Type the report name you created in the first How-To (see Figure 10.15). Figure 10.15. This report is strongly typed.
Tip
After you have clicked OK to accept the Report document, you might want to set the Name property of the control to a name with an rd prefix. I named mine rdHowTo10_2. That way, in later code, I know I am dealing with a ReportDocument control.
4. Set the ReportSource property of the CrystalReportViewer control to the name of your Report document. 5. Set the Anchor property of the Viewer to be Top, Bottom, Left, Right. This ensures that the Viewer fills the form, regardless of the size of the form. Figure 10.14. The report displayed in the Crystal Report Viewer.
Page 422
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
That's it, if you open the form now, you will see the report displayed in the form. You get so many features with the Crystal Report Viewer just by dumping it on the form with no code.
[ Team LiB ]
Page 423
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.3 Add Calculated Fields to the Crystal Reports Report
Although creating reports based on given fields in tables is fine, it just does not give the flexibility I need. To have that, I need to know how to add calculated fields to my reports.
Technique
In Crystal Reports, calculated fields are known as formulas. To create and edit formulas, you will use the Formula Editor (see Figure 10.16). Figure 10.16. You can display this Formula Editor from either the Report Expert or the Report design.
When you're in the Report Expert, you can add a new formula by clicking on the Formula button, located on the Fields tab. In Report design, you can add a field by opening the Field Explorer, located to the left of the IDE with the toolbox, and expanding the Formula Fields tree. You can also right-click on the Formula Fields base node and choose New to add a new formula. Formulas are similar to T-SQL expressions in that you can combine fields or values with operators to create a Formula field. For example, a formula called @TotalPricePerUnit is being created for this How-To. You saw it displayed in Figure 10.16. The expression used is this:
{Invoices.UnitPrice}*{Invoices.Quantity}
You can use Formula fields in summary sections and grand totals. The best way to verify a formula is to create it when you use the Report Expert to create a report.
Steps
Open the Visual Basic .NET Chapter 10 solution. In the Solution Explorer, you will see the report
Page 424
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
rptHowTo10_3.rpt. Scroll over to the left so that the last column is visible. This is the Formula field. 1. Right-click on your project in the Solution Explorer and choose Add New Item from the Add menu item. Type the name of the report in the Name field and click Open. The Crystal Report Gallery dialog box opens. 2. Leaving the defaults as they are, which is to use the Report Export and create a Standard report, click the OK button. You are taken to the Report Expert, with the Data tab displayed. 3. Double-click on the OLE DB (ADO) node in the Available Data Sources tree. If you haven't chosen a data source before, the OLE DB (ADO) dialog box opens asking you to choose an OLE DB provider. Choose Microsoft OLE DB Data Provider for SQL Server and click Next. You are requested to enter connection information. For this page, type (local) for the server, check Integrated Security, and type Northwind for the database. Click Finish. Your Available Data Sources will now indicate (Local) under the OLE DB (ADO) node and Northwind under the local connection. 4. Expand the tree under Northwind to get to the first DBO, and then expand Views. You will see the views listed, including the Invoices view. Highlight the Invoices view and click Insert Table. The view is displayed in the Tables in Report list (see Figure 10.17). Click Next. Figure 10.17. The Report Expert considers both tables and views as tables.
5.
From the Fields tab, add the following fields: Invoices.CustomerName, Invoices.OrderID, Invoices.UnitPrice, and Invoices.Quantity.
6.
Click on the Formula button. Type TotalPricePerUnit. Crystal Reports puts the @ before the formula name from now on. You are then brought into the Formula Editor, shown back on Figure 10.16.
7.
Type the formula {Invoices.UnitPrice}*{Invoices.Quantity}; then press Ctrl+S to
Page 425
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
save and close the dialog box. An alternative is to double-click on the fields you want to include. 8. 9. Now select the formula you just created, and add it to the fields to include. You can now go on to select how you want the columns totaled and what you want the style of the report to be. Click Finish when you are done.
Comments
The Formula Editor works similarly to other builders, and it's pretty straightforward to use. Formulas are another step to making sure you can give your clients the full-featured reports they want.
[ Team LiB ]
Page 426
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.4 Select Whether the Report Will Be Displayed, Printed, or Exported Using Visual Basic .NET Code
I know I can use the Crystal Report Viewer to print and export my reports, but I want to be able to have control over that, and maybe not even include the Viewer in some cases.
Technique
For this How-To, you will use a Tab control to display the three options for the user: Print, Export, and View (see Figure 10.18). Figure 10.18. You have flexibility when it comes to letting your users work with reports.
The first tab, Print, allows you to specify the number of copies to print, along with the starting and ending pages.
Printing Using the Report Document
This page will use the PrintToPrinter method shown here:
Me.rdHowTo10_4.PrintToPrinter(Me.txtNumOfCopies.Text, False, Me.txtStartPage.Text, Me.txtEndPage.Text)
The PrintOptions object, found on the ReportDocument, is very useful. The PrintOptions object has the following properties: PaperOrientation, PaperSize, PaperSource,
PrinterDuplex, and PrinterName. You can set these properties either at design time using the
property sheet, or at runtime using code.
Exporting Using the Report Document
When you're exporting using the Report document, you will be using the ExportOptions object. The ExportOptions object is made up of four other properties/objects:
Page 427
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DestinationOptions. This is made up of one of three possible objects: DiskFileDestinationOptions, ExchangeFolderDestinationOptions, or MicrosoftMailDestinationOptions. ExportDestinationType. This gets or sets the export destination type. This will be DiskFile, ExchangeFolder, MicrosoftMail, or NoDestinationType. ExportFormatType. This gets or sets the export format type. It can be one of the following: Excel, HTML32, HTML40, NoFormat, PortableDocFormat, RichText, or WordForWindows. FormatOptions. This gets or sets the FormatOptions. It can be ExcelFormatOptions, HTMLFormatOptions, or PdfRtfWordFormatOptions.
To execute the export, you use the Export method of the DocumentReport object. You can see the page for exporting in Figure 10.19. Figure 10.19. You can control which types of files you want the user to export.
The View tab uses a CrystalReportViewer object on the tab page.
Steps
Open and run the Visual Basic .NET Chapter 10 solution. Click on the button labeled How-To 10.4. Clicking on the tabs, you can see the three options you have to work with. Clicking on the Print button prints your report to the default printer. When you go to the Export tab and click the Export button, a message appears stating that the data has been exported. The last tab, View, displays the report in a Viewer. 1. 2. Create a Windows Form. Then place a Tab control on your form. Add pages for Print, Export, and View, using the TabPages property of the Tab control.
Page 428
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. Drag on a ReportDocument object, and set it to point to the report you created in How-To 10.1. Then name your report document rdHowTo10_4. 4. Place the controls shown in Figure 10.18 and 10.19 onto the tab page with the properties set forth in Table 10.3.
Table 10.3. Controls for the Tab Pages Tab Page Object Property Setting
Print Label Label Label TextBox
Text Text Text Name Text
# of Copies Start Page End Page txtNumOfCopies 1 txtStartPage 0 txtEndPage 0 btnPrint Export Type File Path txtExportFilePath File Name txtExportFileName lstExportType btnExport Top, Bottom, Left, Right
TextBox
Name Text
TextBox
Name Text
Button Export Label Label TextBox Label TextBox ListBox Button View
Name Text Text Name Text Name Name Text
CrystalReportViewer Anchor
ReportSource
rdHowTo10_4
Page 429
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
5. 6. Type Excel and Word Document into the Items collection of lstExportType. Add the code in Listing 10.1 to the Click event of btnPrint. Listing 10.1 frmHowTo10_4.vb: Printing the Report
Private Sub btnPrint_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnPrint.Click Dim po As PrintDialog Me.rdHowTo10_4.PrintToPrinter(Me.txtNumOfCopies.Text, False, _ Me.txtStartPage.Text, Me.txtEndPage.Text) End Sub 7. Add the code in Listing 10.2 to the Click event of btnExport. This code tests the value of lstExportType and assigns the appropriate ExportFormatType and file extension (strExt). The DiskFileDestinationOptions information is supplied, and the Export method is called to complete the export. Listing 10.2 frmHowTo10_4.vb: Exporting the Report
Private Sub btnExport_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnExport.Click Dim strExt As String Try With Me.rdHowTo10_4.ExportOptions Select Case lstExportType.SelectedItem Case "Excel" .ExportFormatType = _ CrystalDecisions.[Shared].ExportFormatType.Excel strExt = ".xls" Case "Word Document" .ExportFormatType = __ CrystalDecisions.[Shared].ExportFormatType.WordForWindows strExt = ".Doc" End Select .ExportDestinationType = _ CrystalDecisions.[Shared].ExportDestinationType.DiskFile Dim ddo As New CrystalDecisions.Shared.DiskFileDestinationOptions() ddo.DiskFileName = Me.txtExportFilePath.Text & _
Page 430
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Me.txtExportFileName.Text & strExt .DestinationOptions = ddo End With Me.rdHowTo10_4.Export() MessageBox.Show("Report Exported!") Catch excp As Exception MessageBox.Show(excp.Message) End Try End Sub
Comments
As you can see, very little code is needed to provide a great deal of functionality. Sometimes when you're using tools such as the Viewer in a tabbed form, the tab pages can become cluttered. If you want to limit the power of the Viewer or make it more streamlined, you can turn off the toolbar and group display by setting DisplayToolbar and DisplayGroupTree to False on the CrystalReportViewer.
[ Team LiB ]
Page 431
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.5 Determine Which Records Will Be Printed at Runtime
I can use the Select Wizard to help limit the records that I want to be displayed on the report, but that doesn't do my users much good when they want control over that when the application is running. How do I determine which records are displayed at runtime?
Technique
To handle this, use the SelectionFormula of the CrystalReportsViewer. When you use the
SelectionFormula to limit your records, you are taking advantage of Crystal Report's Database
optimization. This means that the query you generated by setting the SelectionFormula and the original record source for the report will be "pushed down" to the server.
SelectionFormula Syntax
You can see the syntax for the SelectionFormula here:
CrystalReportViewer1.SelectionFormula = "{Table.Field} = value"
Value can be various data types, delimited by the usual delimiters, such as single quotes for strings. For the new criteria to take effect, after setting the SelectionFormula, you need to call the
RefreshReport method of the CrystalReportViewer. Setting Report Options
To get optimal use out of the SelectionFormula, you need to keep some things in mind. You need to set an option of the report that will ensure it uses the record source indexes if possible. To do this, you right-click on the report and choose Report Options from the Report menu. On the Options page, make sure to check Use Indexes or Server for Speed (see Figure 10.20). Figure 10.20. Customize your report by using the Report Options dialog box.
Page 432
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Another tip is to make sure you use indexed fields whenever possible. Tip Take some time now to check out some of the other report options.
Steps
Open and run the Visual Basic .NET Chapter 10 solution. Click on the button labeled How-To 10.5. You can select Regions from the ComboBox control on the top of the form; the report then reflects the selection (see Figure 10.21). 1. 2. Create a Windows Form. Drag on a ReportDocument object, and set it to point to the report you created in How-To 10.1. Then name your report document rdHowTo10_5. Place the controls shown in Figure 10.21 onto the form with the properties set in Table 10.4.
3.
Table 10.4. Label, Combo, and CrystalReportViewer Controls and Their Property Settings Object Property Setting
Label
Text
Pick a Region
Page 433
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ComboBox CrystalReportViewer
Name Name Anchor
cboRegions cvwRegionReport Top, Bottom, Right, Left rdHowTo10_5
ReportSource
4.
Add the code in Listing 10.3 into the Load event of the form. This code performs a DISTINCT SQL statement to get all of the regions used in the Customers table. The data adapter then fills dtRegions. Before binding dtRegions to the combo box cboRegions, a new data row is added to allow the user to specify All Regions. Listing 10.3 frmHowTo10_5.vb: Populating the Selection Combo Box
Private Sub frmHowTo10_5_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim odaRegions As New _ OleDb.OleDbDataAdapter("SELECT DISTINCT Region FROM Customers", BuildCnnStr("(local)", "Northwind")) Dim dtRegions As New DataTable() odaRegions.Fill(dtRegions) '-- Add the All Regions feature Dim drAll As DataRow = dtRegions.NewRow drAll(0) = "<< ALL Regions >>" dtRegions.Rows.Add(drAll)
With Me.cboRegions .DataSource = dtRegions .ValueMember = "Region" End With
End Sub Note
As with a number of other examples, the BuildCnnStr() function has been created in the
modGeneralRoutines module to create a connection
string.
5. Add the report in Listing 10.4 to the SelectedIndexChanged event of cboRegions. One of the values that is in the Region field of the Customer table is NULL. This code tests for that first by testing this:
Page 434
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6. 7. Me.cboRegions.SelectedItem(0) Is System.DBNull.Value If the selected item is NULL, which uses System.DBNull.Value for the comparison, then the value of IsNull({Customers.Region}) is stored in the SelectionFormula. If All Reasons was chosen, then the SelectFormula is set to the empty string so that all items are chosen. Otherwise, the Customers.Region field is compared to the literal region, supplied by cboRegions. The last task performed is refreshing the report. Listing 10.4 frmHowTo10_5.vb: Setting the SelectionFormula Property
Private Sub cboRegions_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles cboRegions.SelectedIndexChanged With Me.cvwRegionReport If Me.cboRegions.SelectedItem(0) Is System.DBNull.Value Then .SelectionFormula = "IsNull({Customers.Region})" ElseIf Me.cboRegions.SelectedItem(0) = "<< ALL Regions >>" Then .SelectionFormula = "" Else .SelectionFormula = "{Customers.Region} = '" & _ Me.cboRegions.SelectedItem(0) & "'" End If .RefreshReport() End With End Sub Figure 10.21. You can let your user control how much data he sees in the report.
Page 435
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
You can limit the selection displayed on the report in other ways, too. This How-To presented just one way to get you started. Letting your user choose the records gives him the perceived control he wants.
[ Team LiB ]
Page 436
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.6 Print Labels and Control the Order in Which Records Will Be Printed
I need to be able to have my application print labels for my user's customer list. Sometimes my user needs to print labels based on the postal code, and other times he needs to print labels alphabetically by company name. How do I do this at runtime?
Technique
To accomplish this task, you will use the Report Expert to create mailing labels. You then will use code to update the sort order at run-time.
Creating the Mailing Labels
To create the mailing labels, you create a new report and choose Mailing Labels for the type of Expert to use. You then fill in the Data tab, which uses Customers for the table, and grab the following fields: CompanyName, ContactName, ContactTitle, Address, Formula (@CityRegionPostal= { Customers.City} & ", " & { Customers.Region} & " "& { Customers.PostalCode} ), and Country. You can see how this will look in Figure 10.22. Figure 10.22. Fields that will be used in the mailing labels.
After clicking Next, you are taken to the tab that allows you to choose which type of label you want to use. For this How-To, the Address (Avery 5160) is used. Everything else on the page is chosen for you (see Figure 10.23). Figure 10.23. You have control over how your labels look.
Page 437
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Now you can just click Finish, and the final mailing label report is created (see Figure 10.24). Figure 10.24. These appear in nice mailing label format when they're viewed on a form.
Controlling the Sort Order at Runtime
To control the sort order at runtime, you use properties, methods, and objects of the ReportDocument. Specifically, you traverse down the ReportDocument object model, looking at the Database object and moving down to the Fields level. You do this first when you're loading up a combo box with fields that are being used in the report. The following lines of code accomplish
Page 438
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
this:
For Each dfCurr In Me.rdHowTo10_6.Database.Tables.Item(0).Fields Me.cboSortFields.Items.Add(dfCurr.Name) Next dfCurr is a FieldDefinition object, which means it is a field definition for a given field in the
report. The other object that will be used from the Report definition is the DataDefinition object, and the SortFields collection off of that. You can see this with the following lines of code, which set the sorting for the report based on which field they chose in the combo box:
With Me.rdHowTo10_6 dfSort = .Database.Tables.Item(0).Fields.Item(Me.cboSortFields.Text) .DataDefinition.SortFields.Item(0).Field = dfSort End With Me.cvwCustomerLabels.RefreshReport()
You can see once again that the RefreshReport method is called after updating the SortFields item.
Steps
Open and run the Visual Basic .NET Chapter 10 solution. Click on the button labeled How-To 10.6. You can select fields from the ComboBox control on the top of the form, and the report reflects the sorting selection (see Figure 10.25). 1. 2. Create a new Crystal Report. Choose Mail Labels for the Report Expert to use. Fill in the Data tab, choosing Northwind for the database, and Customers for the table to use. 3. Choose the fields as specified by the "Technique" section: CompanyName, ContactName, ContactTitle, Address, Formula (@CityRegionPostal= { Customers.City} & ", " & { Customers.Region} & " " & { Customers.PostalCode} ), and Country. 4. 5. 6. On the Label tab, choose Address (Avery 5160) for the mailing label type. Click Finish. Create a Windows Form. Drag on a ReportDocument object, and set it to point to the report you created in the past few steps. Then name your report document rdHowTo10_6. 7. Place the controls shown in Figure 10.22 onto the form with the properties set forth in Table 10.5.
Table 10.5. Label, Combo, and CrystalReportViewer Controls and Their Property Settings Object Property Setting
Label ComboBox
Text Name
Pick a Field to Sort cboSortFields
Page 439
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
CrystalReportViewer
Name Anchor
cvwCustomerLabels Top, Bottom, Right, Left rdHowTo10_6
ReportSource
8.
Add the code in Listing 10.5 to the Load event of the form. As described in the "Technique" section, this code iterates through each of the fields in the table that the report is based on and loads them into the Items collection of cboSortFields. Listing 10.5 frmHowTo10_5.vb: Populating the Selection Combo Box
Private Sub frmHowTo10_6_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim dfCurr As CrystalDecisions.CrystalReports.Engine.FieldDefinition ' ' Iterate through the table that the report is based on and load the fields into a combo box.
For Each dfCurr In Me.rdHowTo10_6.Database.Tables.Item(0).Fields Me.cboSortFields.Items.Add(dfCurr.Name) Next End Sub 9. Add the code in Listing 10.6 to the SelectedIndexChanged event of cboSortFields. This code takes the selected item from cboSortFields and locates it in the table that the report is based on. The DataDefinition object is retrieved and then assigned to the first items in the SortFields collection. Last, the report is redisplayed using the
RefreshReport method.
Listing 10.6 frmHowTo10_5.vb: Populating the Selection Combo Box
Private Sub cboSortFields_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cboSortFields.SelectedIndexChanged Dim dfSort As CrystalDecisions.CrystalReports.Engine.FieldDefinition ' ' Use the field that is picked in the combo box in the SortFields collection.
With Me.rdHowTo10_6 dfSort = .Database.Tables.Item(0).Fields.Item(Me.cboSortFields.Text) .DataDefinition.SortFields.Item(0).Field = dfSort End With Me.cvwCustomerLabels.RefreshReport() End Sub
Page 440
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 10.25. Let your user sort the mailing labels as needed.
Comments
If you have more than one field you want to sort on, then you could use the same technique, just adding code such as this:
dfSort = .Database.Tables.Item(0).Fields.Item(Me.cboSortFields2.Text) .DataDefinition.SortFields.Item(1).Field = dfSort
The 0 is replaced by 1, and you have another combo box from which you must pick the second sort field.
[ Team LiB ]
Page 441
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 10.7 Create an Onscreen Report That Contains Hyperlinks
My user has a text field in his Customers table that is actually customers' Web sites. Users want to be able to access the site as a hyperlink on an onscreen report. How can I use Crystal Report to create a report that uses hyperlinks?
Technique
For this How-To, you won't be doing coding. You'll just adjust the formatting of a report field to tell it that it needs to treat the field like a hyperlink. Before doing this, you need to modify Northwind.
Adding a Web Site Field to Northwind
To accomplish this, you open the Northwind database in the Server Explorer. You then add a field called Website to the Customers table, with the Data Type of nchar and a size of 50. You then modify the first two records in the Customers table so that the Website field contains www.appsplus.com and www.microsoft.com respectively, as shown in Figure 10.26. Figure 10.26. These will be displayed as hyperlinks on the new report you will create.
Now you are ready to create the report.
Telling the Report That a Field Is a Hyperlink
You create a simple report that is based off the Customers table and contains the fields CompanyName, ContactName, and Website. Then you right-click on the Website field in the report and choose Format. The Format dialog box opens, where you can click on the Hyperlink tab. For the hyperlink type, you should choose Current field value (see Figure 10.27). Figure 10.27. These are the options that you can have for hyperlink actions.
Page 442
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Now that you have told the field to act like a hyperlink, you need to have it look like one. To perform this task, you set the following properties:
BorderColor. This is set to RoyalBlue to give it the color of a hyperlink. BottomLineStyle. This is set to crLSSingleLine. EnableTightHorizontal. This is set to True so that it doesn't highlight the full length of
the field just to the text.
That's it! When you display this in a Viewer, as shown in Figure 10.28, you can click on the Website field, and the Viewer will bring you to the Web site you chose. Figure 10.28. This is a real-time hyperlink.
Page 443
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Steps
Open and run the Visual Basic .NET Chapter 10 solution. Click on the button labeled How-To 10.7. You can click on the hyperlinks, displayed for the Web site, to go to the Web site. 1. Modify Northwind as described in the "Technique" section, adding the Website field to the Customers table. 2. 3. Create a new Crystal Report. Choose Standard for the Report Expert to use. Fill in the Data tab, choosing Northwind for the database, and Customers for the table to use. 4. Choose the fields as specified by the "Technique" section: CompanyName, ContactName, and Website. Click Finish. 5. With the report open in Design mode, right-click on the Website field in the Details section, and choose Format. 6. Make the modifications to the format of the field as described in the "Technique" section, setting the hyperlink type. Then click OK. 7. Make the rest of the format changes as described, setting the BorderColor, BottomLineStyle, and EnableTightHorizontal. 8. 9. Create a Windows Form. Drag on a ReportDocument object, and set it to point to the report you created in the past few steps. Then name your report document rdHowTo10_7. 10. Place a CrystalReportViewer on the form, setting the Anchor property to Top, Bottom, Right, Left and the ReportSource property to rdHowTo10_7.
Comments
Now when you run the report, you get your hyperlinks. You could have performed additional tasks with hyperlinks, such as using the report for reviewing those you want to email, and having the
Page 444
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
field be clickable that way.
[ Team LiB ]
Page 445
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 11. Managing SQL Server Security
In this chapter you will
Create Windows NT/2000 users Create Windows NT/2000 groups Establish a Windows NT/2000 authentication mode Establish mixed-mode authentication Create a standard login Create a Windows NT/2000 login Use a fixed server role Create a database user account Use statement permissions Use object permissions Use fixed database roles Create custom database roles Create application roles Set permission states on tables
This chapter discusses the SQL erver security scheme and explains the options available to you as a Visual Basic developer. It starts by discussing authentication modes and then moves on to the various permissions you can set on SQL Server objects. SQL Server supports a layered security system. From bottom to top, these layers add to the overall protection of the database objects and the data they contain. Keep in mind how SQL Server works. SQL Server is an engine that maintains an environment for database objects and data. Through this environment, SQL Server provides services for searching and sorting data, adding or updating records, and performing other data-oriented tasks. If you look at SQL Server as a multilayered or multidimensional entity, the role played by each of the security layers becomes clear. Each layer and each data-management task has its own set of rules that must be followed. For instance, simply entering the SQL Server environment does not automatically grant access to database. Similarly, the ability to read data stored in the table does not imply the ability to add new records or change existing data. Security is an important issue, and a certain amount of complexity is the price for the high degree of data security and integrity that SQL Server provides.
[ Team LiB ]
Page 446
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.1 Create Windows NT/2000 Users
Although it might seem odd to begin a discussion of SQL Server security by describing the process of adding users to Windows NT/2000, it's important to note that SQL Server security is tightly integrated with the Windows security registry. SQL Server administrators are pleased with the fact that SQL Server automatically recognizes Windows NT and Windows 2000 users, saving a considerable amount of administrative time. This section explains the process of adding new users to Windows 2000. The next section describes how to add functional groups to Windows. Although these sections deal with Windows 2000, the process is nearly identical for Windows NT. Windows must recognize users before they can log in to the network and use the computer's resources. You need to add a number of users to the Windows user registry. How do you make sure that all users are required to provide a network password before they can access the network?
Technique
Windows users cannot be added to the system from within SQL Server's Enterprise Manager. You'll have to use the Windows Control Panel applets to add new users and groups. Note The settings you choose on this page of the Add New User dialog box do not affect the SQL Server settings you establish for the user. The settings you see in Figure 11.4 relate only to Windows and not SQL Server or the database data. Figure 11.4. Most of your users will be set up as Standard Users with no special capabilities.
Note
Page 447
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
The first step in the following example is different on Windows NT 4.0 and Windows 2000. For Windows NT 4.0, you go to Start, Programs, Administrative Tools, User Manager. For Windows 2000, you go to Start, Settings, Control Panel, Administrative Tools, Computer Management; then you right-click on Users. Also, you must have administrative rights on the computer to add users to it.
Steps
SQL Server security is tightly integrated with Windows NT/2000 security. SQL Server recognizes the users and groups that are added to a Windows NT or Windows 2000 domain. The first step toward security for SQL Server, of course, is to add users to the computer system. This section describes how to add individual users to a Windows NT or Windows 2000 computer. SQL Server consults the registered users on the computer when you create logins, discussed in How-To 11.5. The user's name and description are accessible from the SQL Server security dialog boxes and help you recognize each user as you create SQL Server logins and establish security profiles. 1. Choose Start, Settings, Control Panel and open the Users and Passwords Control Panel applet. 2. Make sure the check box labeled Users Must Enter a User Name and Password to Use This Computer is checked, as shown in Figure 11.1. Figure 11.1. This dialog box allows you to add new Windows users and manage their group membership.
Page 448
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. 4.
Click the Add button to open the Add New User dialog box. Fill in the username, the full name of the user, and a description for the new user, as shown in Figure 11.2. Figure 11.2. The information you enter in the Add New User dialog box will be accessible from the SQL Server security dialog boxes.
5.
After you have provided the required user information, click the Next button to move to the
Page 449
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
second page of the dialog box. 6. Enter the new user's initial password into the password text box. Then type the password a second time in the Confirm Password text box (see Figure 11.3). When you're ready, click the Next button. Figure 11.3. Specify the user's initial password in this dialog box. The user will be able to change it later, if necessary.
7.
On the third page of the Add New User dialog box (see Figure 11.4), you specify the type of Windows access you want to provide this user. Although this information is not directly related to SQL Server, most often you will want to leave this setting at its default to Standard User. In most cases, you do not want to provide a user with more access than necessary. Note
The settings you choose on this page of the Add New User dialog box do not affect the SQL Server settings you establish for the user. The settings you see in Figure 11.4 relate only to Windows and not SQL Server or the database data.
8. When all settings are complete, click the Finish button to add the new user to the collection of users on your computer.
Comments
SQL Server's integration with Windows security is one of the major reasons that SQL Server has grown in popularity. Its ability to cooperate with Windows when authenticating users and providing database services dramatically reduces the administrative burden that is normally associated with server database engines. Caution
Page 450
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Be sure to remove your temporary users after you are finished with them so that you do leave them hanging around.
[ Team LiB ]
Page 451
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.2 Create Windows NT/2000 Groups
Windows 2000 recognizes individual users as well as functional groups. You can, for instance, set up a group called Marketing or Sales, and then add new users to the computer. In addition, each user can be added to any of the groups that you've created. Therefore, you might have a marketing manager who belongs to both the Marketing and Management groups. One advantage of using groups is that SQL Server automatically recognizes the registered Windows users. SQL Server is tightly integrated with Windows security, and you are able to use this integration as you set up SQL Server security. This means, for instance, that you can provide the marketing group with access to tables and stored procedures that are related to marketing data, yet deny the salespeople access to those same tables and procedures. The marketing manager mentioned earlier in this chapter is able to work with marketing and management data (such as employee human resources data). Because you are treating multiple users as a single group, the administrative effort is considerably less than if you had gone to the trouble of providing access to each individual user. As you'll soon see, treating users as members of groups greatly simplifies the security administration task. Handling individual users is a real hassle. In large installations with hundreds of users, you spend inordinate amounts of time managing SQL Server security on a user-by-user basis. Instead, you'd like to use Windows groups to add groups of users to the database.
Technique
Use the Administrative Tools in the Control Panel to create groups and add the users you've created to those groups.
Steps
Most often, users are arranged into logical groupings. For instance, all the people in the marketing department are likely to belong to a group named Marketing. Similarly, managers probably belong to a Management group. In this section, you'll learn how to specify the groups on your computer and add the user accounts you've created to those groups. Later, as users log in to SQL Server, they'll be able to log in as themselves or as a group. Although this might sound a bit strange, to SQL Server, an individual user is the same as a group of users. All that SQL Server sees is an identifier ("TonyS" or "Marketing"), and it matches that identity with a Windows network login. 1. 2. Choose Start, Settings, Control Panel to open the Control Panel. Double-click on the Administrative Tools applet to access the Windows 2000 administration options. 3. Select the security settings by double-clicking on the Computer Management option and opening the dialog box you see in Figure 11.5. Figure 11.5. Each Windows group usually contains a number of individual users.
Page 452
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Use the + next to Local Users and Groups to reveal the Users and Groups icons. Right-click on the Groups icon and select New Group from the shortcut menu that appears. (Alternatively, use the New Group menu item under the Action menu). You'll see the New Group dialog box as shown in Figure 11.6. Provide a name for the new group, such as Shift Supervisors, in the Group Name text box at the top of the New Group dialog box. Figure 11.6. Fill in the Group name and Description text boxes. You'll add users to this Windows group in a minute.
5.
Provide a verbose description for the group in the Description text box. Near the bottom left of the New Group dialog box, you'll see two buttons labeled Add and
Page 453
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Check Names (see Figure 11.7). Click on the Add button to open the list of all users who are registered on this computer. Figure 11.7. This list shows all the users within the local Windows domain. The red X indicates disabled Windows accounts.
6.
The top half of the Select Users or Groups dialog box contains an alphabetically sorted list of all the users in the local domain. Use the scrollbar if necessary to locate the user you want to add to the group. Select the user and use the Add button (or double-click on the user) to add the user to the group. As users are added to the group, their names appear in the lower half of the Select Users or Groups dialog box. When you have completed the selection process, click the OK button. You'll be returned to the New Group dialog box. You should see the users you've added to the group displayed in the list at the middle of the dialog box.
7.
When you're finished adding groups to the computer, click the Close button to dismiss the New Group dialog box.
Comments
Normally, as a database developer, you won't be creating Windows 2000 groups. However, in many small environments, developers are required to take on more than a single role. Also, you might find it useful to create a group login just for the applications you write.
[ Team LiB ]
Page 454
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.3 Establish a Windows NT/2000 Authentication Mode
SQL Server is a much more complex database engine than desktop systems such as Jet. SQL Server is a true server engine; it provides access to multiple databases or even hundreds of users simultaneously. Furthermore, unlike Jet, which is tightly bound into Microsoft Access, SQL Server exists as a separate entity on a computer, which most often is located across a network from the user's desktop computer. A building that contains multiple offices is a good analogy for the way that SQL Server is built. The building is secured, and each office within the building is locked. Carrying the analogy further, each office contains locked desk drawers and filing cabinets. A person who wants to use information in one of those file cabinets must enter the building, gain entrance to a locked office, and have a key or other permission to open a locked file cabinet. SQL Server requires each user to be authenticated before it permits the user to open a database. Authentication is somewhat like having to show an employee ID card to a guard at the front door of a building. Without proper credentials, you don't get into the building. Similarly, you don't get "into" SQL Server unless you have been properly authenticated. SQL Server supports two different authentication modes:
Windows NT/2000 authentication. This mode means that SQL Server explicitly trusts Windows to authenticate the user. Anyone who has a valid Windows user ID and password is allowed to access SQL Server. This is known as a trusted connection because SQL Server trusts Windows to allow only qualified people into the computer system and onto SQL Server. Windows NT/2000 Authentication works only with Windows NT or Windows 2000, and it has the distinct advantage of being quite simple to administer. Furthermore, the Windows NT/2000 security provides for expiration and other controls over password usage. In fact, SQL Server even recognizes the user's membership in Windows security groups.
SQL Server and Windows NT/2000 authentication. Using this mode means that both SQL Server and Windows are involved in authenticating the user. The user is not able to access SQL Server unless both Windows and SQL Server are able to verify the user's identity and password. SQL Server and Windows NT/2000 Authentication mode is often referred to as mixed-mode authentication.
The selected authentication mode simply directs SQL Server where to look for the user's credentials. In other words, authentication is performed by SQL Server, and describes how SQL Server verifies the user's identity. You've decided that mixed-mode authentication is too much work, and users are likely to forget either their Windows password or their SQL Server password. In fact, some users have resorted to writing down their passwords on sticky notes attached to their computer monitors. Obviously, this creates a security risk. You'd like to make it as easy as possible for users to get into SQL Server so that they can use the databases you've created for them.
Technique
Enterprise Manager includes all the dialog boxes that are required to set SQL Server's authentication mode. Changing the authentication mode takes only a few moments, and it affects all databases that SQL Server manages.
Steps
Page 455
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SQL Server takes a layered approach to securing the data in its tables. These layers include authentication whereby a user is identified by username and password and permissions on the objects (such as tables and views) stored in the database. As a developer or SQL Server administrator, you must choose which authentication mode your users use to access SQL Server. In Windows NT/2000 authentication mode, any user who is able to log in to Windows is able to access SQL Server.Windows NT/2000 Authentication mode is the easiest possible way for users to access SQL Server. As long as a user is an authorized user of Windows NT or Windows 2000, he'll be able to get into SQL Server. No extra password or user identity is required for admittance to SQL Server, which reduces the risk that a user will store a password in an insecure place. 1. Choose Start, Programs, Microsoft SQL Server, Enterprise Manager to open Enterprise Manager. 2. 3. Open the SQL Server group and right-click on the server you want to configure. Select Properties from the context menu that appears. (The Properties command should be highlighted in the context menu.) 4. 5. Select the Security tab. Select Windows Only from the authentication options near the top of the Security tab, as shown in Figure 11.8. Figure 11.8. Select Windows Only from the Authentication options in the Properties dialog box.
Page 456
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6.
Click the OK button to complete the process and close the Properties dialog box.
Comments
Windows NT/2000 authentication simply means that SQL Server trusts Windows to authenticate users. Windows determines the user's identity and group member as the user logs into his computer. From that point on, the user has full access to SQL Server installations that are configured to accept Windows NT/2000 authentication. The main problem with Windows NT/2000 authentication mode is that it doesn't work with Windows 95, Windows 98, or non-Windows computers. Anyone who is connected to your network from a Unix or Apple Macintosh computer will not be able to use Windows NT/2000 authentication. You'll have to set up mixed-mode authentication for these users. Another problem with Windows NT/2000 authentication is that in many environments, more than one person shares the same computer. For instance, consider a point-of-sale terminal in a retail environment or an industrial computer located on a factory floor. Multiple users typically access these computers, and because SQL Server admits anyone logged into the computer, SQL Server can't distinguish between individual users. This can be a problem in environments where some users must be prevented from viewing certain tables or accessing certain data within a database. Note Although this discussion makes it sound as though SQL Server is passive when working under Windows NT/2000 authentication mode, there is more to the story than discussed here. SQL Sever actually calls Windows
Page 457
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
NT or 2000 to retrieve the user's Windows login identity and group membership. If the user's group membership changes while he is logged into Windows, SQL Server sees the changes as soon as the user tries to access SQL Server.
[ Team LiB ]
Page 458
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.4 Establish Mixed-Mode Authentication
The alternative to Windows NT/2000 authentication is mixed-mode authentication. In this arrangement, a user is first authenticated by Windows, and is again authenticated by SQL Server as he tries to access a database. Mixed-mode is the only authentication for users who are working on Windows 98 computers or Macintoshes, Unix, and other non-Windows machines. My network includes a number of non-Windows computers, such as Apple Macintoshes. In addition, several users are working from Windows 98 computers. I discovered that these users are unable to access the SQL Server databases that I created. It appears that mixed-mode authentication might be the only way for these users to access SQL Server.
Technique
Again, Enterprise Manager provides the dialog boxes that are necessary to set mixed-mode authentication. After mixed-mode is set, users must first log in to Windows (or, at least, access the SQL Server machine from a Windows network) and then provide a username and password to SQL Server before using a database.
Steps
In mixed-mode authentication, the user first logs into Microsoft Windows and then into SQL Server. At each step, the user's credentials are authenticated. Mixed-mode authentication means that SQL Server keeps a record of users who are allowed to log in to SQL Server. It matches their password with the password that is stored with their user record. SQL Server stores the user's login information in a system table named syslogins in the master database. This table includes an encrypted security ID (SID) and the user's encrypted password. The other information that is stored in the syslogins table is discussed in the next two sections. 1. 2. 3. Use Start, Programs, Microsoft SQL Server, Enterprise Manager to open Enterprise Manager. Open the SQL Server group and right-click on the server you want to configure. Select Properties from the context menu that appears. (The Properties command should be highlighted in the context menu.) 4. 5. Select the Security tab. Select SQL Server and Windows (for Windows 2000 and NT, SQL Server and Windows NT is displayed) from the authentication options near the top of the Security tab (see Figure 11.9 ). Figure 11.9. Setting mixed-mode authentication is similar to setting Windows NT/2000 authentication.
Page 459
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
6.
Click the OK button to complete the process and close the Properties dialog box.
Comments
Although it might sound bothersome to provide two passwords before accessing SQL Server, most often the SQL Server password is provided by the front-end application with which the user is working. Users rarely, if ever, actually open Enterprise Manager or Query Analyzer and directly access the data in SQL Server databases. Instead, they'll use front-end applications that are written in Visual Basic, Access, or another database tool. Most often, the user opens the application and the application passes the user's identity and password to SQL Server as the database connection is made. Although mixed-mode authentication might be more of a hassle to your users, it results in considerably better security for your database. Just because a user is able to access your network by using mixed-mode authentication does not mean that he is able to access SQL Server. The paradox is that some users might write down their network or SQL Server password in a location where unauthorized people can see it. However, the same could be said of any security system, and such security breaches must always be avoided.
[ Team LiB ]
Page 460
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.5 Create a Standard Login
The previous sections discussed authentication, which is nothing more than the process of how SQL Server recognizes users. Authentication is much like the method used to allow people to get through the front door of an office building. The building may use a simple key card lock, or the company may use a guard to check IDs as people enter the building. In either case, the person's identity is verified before entry is granted. Earlier in this chapter, you read about the Windows NT/2000 authentication process. When using Windows NT/2000 authentication, a trusted connection is established between SQL Server and the user's computer. However, trusted connections cannot be established between SQL Server and Windows 95 or 98 machines, or Apple Macintoshes, Unix, or other non-Windows computers. After you determine which type of SQL Server authentication to use, you must establish a login for each of your users. A login is how the user gains access to SQL Server after the authentication process. A login is how SQL Server establishes your identity within SQL Server and how SQL Server determines your permissions to use data and database objects. You can choose from two different types of logins:
Standard SQL Server login Windows NT/2000 login
When no trusted connection exists between the user's computer in SQL Server, SQL Server has no way of obtaining the user's identity from the operating system. Therefore, mixed mode application must be used to validate the user, and a standard SQL Server login must be created so that SQL Server recognizes the user. The login you establish only provides access to SQL Server; it does not provide access to databases, data, or database objects. Not every SQL Server user will be working with Windows NT and Windows 2000. Some users might be connected to the network from a Unix or Macintosh machine. These users will not be able to use a Windows NT/2000 login, and you have to establish a standard SQL Server login for them. This is also true of users who are working under Windows 95 and Windows 98.
Technique
SQL Server Enterprise Manager provides the dialog boxes that are necessary to set up standard logins. This section describes these dialog boxes and how to provide the information necessary to create standard SQL Server logins. Creating a login can affect only one person or a group of people; it does not affect how SQL Server operates.
Steps
If the user is connecting to SQL Server from a Unix, Macintosh, or other non-Windows machine, or if the user is running Windows 98, you must create a standard login for him. SQL Server maintains a record of each person's logins and a table named sysxlogins in the master database. This table stores the user's login ID, encrypted password, and other critical information. If you'd like to view the data in this table, use the syslogins view in the master database. The syslogins view uses a SQL statement to arrange the data in a more readable format.
Page 461
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
As the user logs in, regardless of which authentication mode he uses, his user information is compared against the data that is stored in the syslogins table. As long as the user appears to be valid, SQL Server allows him to try to access tables, stored procedures, and data. 1. 2. Open Enterprise Manager and select your server. Use the plus sign (+) next to your server's name to expand the server's object list. Then expand the security icon. 3. 4. Right-click on the Login icon and select New Login from the shortcut menu. You'll now see the new Login dialog box (see Figure 11.10). Enter the new login name in the Name text box. Figure 11.10. Add new Windows NT/2000 logins with the SQL Server Login Properties dialog box.
5. 6.
Select the SQL Server Authentication option button, and enter a password for the login. Select which database this login will normally use from the Database drop-down list in the Default section near the bottom of the New Login dialog box.
Comments
The SQL Server standard login does not permit you to use the user's NT/2000 identity. Therefore, you cannot take advantage of a user's membership in a Windows group to simplify login creation. You can, however, create a shared login. (CS would be named something like Marketing for accounting practices used by everyone who is a member of that group.) The problem is that everyone within that group will use the same password in login name, which might make security
Page 462
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
an issue.
[ Team LiB ]
Page 463
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.6 Create a Windows NT/2000 Login
Any user who is accessing SQL Server from a Windows NT or Windows 2000 computer (but not Windows 98 or ME) can be given a SQL Server Windows NT/2000 login. Although setting up the NT/2000 login is almost the same process as creating a standard login, you have the option of adding the user as any of the following:
An individual user A member of an NT/2000 group A member of the SQL Server built-in group
I want to take advantage of the fact that the users on my system have all been assigned to functional groups (such as marketing and sales) in Windows NT or Windows 2000. Because these groups parallel the user's SQL Server activity, I'd like to use each person's network identity as his SQL Server login. Using a person's Windows NT/2000 group saves a lot of administrative time. Rather than creating a custom login for each user, I can assign a login to a Windows NT/2000 group, and SQL Server can recognize any individual as valid who belongs to the group.
Technique
You first create a Windows 2000 user or group, and then create a SQL Server login for that user or group. Earlier in this chapter, you read how to add users and groups to Windows NT/2000. You'll now use the Windows Enterprise Manager dialog boxes to establish SQL Server logins for those users and groups.
Steps
If the user is working with Windows NT or 2000, you are able to establish a Windows NT/2000 login identity for him. As you'll see, using a Windows NT/2000 login is less work than using standard logins. When a user logs in to a SQL Server or Windows NT/2000 account, his identity is verified against the account information that Windows manages. SQL Server security is tightly integrated with Windows login information, and SQL Server knows and understands the user's identity. SQL Server recognizes the user's personal identity as well as his Windows group membership. Even if no personal SQL Server login is established for the user, as long as a SQL Server login is established for at least one of the Windows groups to which he belongs, he will be able to access SQL Server. The person's identity and Windows group membership is established as he logs in to Windows. As you'll see later in this chapter, these identities play important roles with regard to object permissions and access to data that SQL Server manages. 1. Open Enterprise Manager and select the Security icon. Open this icon by clicking on the plus sign (+) next to it. 2. Select New Login from the Actions menu, or click on Logins with the right mouse button and select New Login from the context menu. Regardless of which method you use, the SQL Server Login Properties dialog box (see Figure 11.10) opens.
Page 464
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. Use the button next to the Name text box to display the list of Windows NT/2000 user and group logins that SQL Server recognizes. The list is alphabetically sorted first by groups, and then by users. In Figure 11.11, you see the list scrolled downward to show the last several groups and the first users in the list. Figure 11.11. The Names list includes both groups and users.
4.
Select a group or user for the new login. If the user or group does not appear in the list, use the drop-down list at the top of the dialog box shown in Figure 11.11 to select another computer on the network.
Comments
Establishing a Windows NT/2000 login account is similar to creating a standard SQL Server login. The biggest difference is that SQL Server recognizes the user's Windows identity,including the password and group membership. The user's identity is how SQL Server determines the individual's access to database data and objects. You'll learn about these important permissions in the sections titled A and B later in this chapter. Don't automatically create logins for every Windows NT/2000 group. This would mean that virtually every user has access to SQL Server. You should provide access to SQL Server only to those users with a legitimate need to use the data that is stored in SQL Server, or to people who are established as SQL Server system administrators.
[ Team LiB ]
Page 465
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.7 Use a Fixed Server Role
Managing a server database engine such as SQL Server can be a time-consuming process. Administrative tasks include backing up the data, adding new users, modifying tables and views, and so on. Most SQL Server administrators find it useful from time to time to permit other people to perform these tasks. Assigning other people tasks such as backing up the databases or administering security allows the system administrators to devote more time to other responsibilities. As a system administrator, I am overwhelmed by the administrative tasks that are required to keep several databases operating efficiently. There's too much to do between database administration, adding new users, performing backups, and other tasks. I'd like to be able to allow an assistant to assume some of these responsibilities so that I won't have to be personally involved in performing these tasks. However, I'm not looking forward to assigning various permissions to all of my administrative assistants. For instance, some people are to be designated as security administrators whereas others will be responsible for updating table designs.
Technique
SQL Server supports the notion of fixed server roles that define certain administrative profiles. Each fixed server role is accompanied by the appropriate permissions to perform the administrative tasks that are associated with the role. Enterprise Manager provides all the dialog boxes that are necessary to assign user accounts to the fixed server roles that SQL Server recognizes. It is important to note that each fixed server role is global within SQL Server. This means, for instance, that the dbcreator fixed server role is able not only to create new databases, but also to make changes to existing databases in SQL Server. SQL Server recognizes eight fixed server roles:
sysadmin. This is the most powerful fixed server role. Members of this role are able to perform all the tasks included with the other roles.
serveradmin. The serveradmin role adjusts the serverwide settings in SQL Server, such as memory usage, authentication mode, and home directories.
setupadmin. This role administers linked servers. A SQL Server installation is able to share SQL Server databases that are located on other computers. The setupadmin group is responsible for creating links to SQL Server installations on other computers.
securityadmin. Members of the securityadmin role add new user and group logins, assign passwords, and perform other security-oriented tasks.
processadmin. This role manages processes that are spawned by SQL Server. dbcreator. Members of this role are responsible for creating and altering databases. diskadmin. The diskadmin role adjusts the disk space that is available for databases, sets the database growth increment (as a percent or in megabytes), and specifies the parameters for the SQL Server log file.
Page 466
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
bulkadmin. SQL Server 2000 includes a number of statements intended to perform bulk inserts to data. Because the BULK INSERT statement can involve considerable amounts of processing time, SQL Server does not allow anyone other than members of the sysadmin and bulkadmin roles to perform this statement.
Steps
Often, you'll want individual users or groups of users to have database administrative responsibilities. For instance, you might want the accounting group to manage its own login names and passwords. In this case, you'll want to join the users in the accounting group to certain fixed server roles, which are predefined special security groups. Each fixed server role defines a category of administrative tasks, and each member of a fixed server role is able to perform those administrative tasks. SQL Server recognizes members of fixed server roles as people who are authorized to perform these administrative tasks. Each role is accompanied by the appropriate SQL Server permissions that are necessary to perform those tasks. 1. 2. Open Enterprise Manager and expand the Security icon. Click on the Server Roles icon to show the eight fixed server roles in the right pane (see Figure 11.12). Figure 11.12. The Server Roles icon reveals the eight SQL Server fixed server roles.
3.
Right-click on any of the fixed server role entries and select Properties from the pop-up menu. Alternatively, select one of the fixed server roles and use the Properties command under the Action menu to open the Server Role Properties dialog box, as shown in Figure 11.13. Figure 11.13. The Server Role Properties dialog box shows you the logins that are added to the selected role.
Page 467
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Use the Add button to open the Add Members dialog box (see Figure 11.14). The Add Members dialog box shows only those logins that have not already been added to the role. In Figure 11.14, only TonyS, the Marketing group, and members of the BUILTIN/Administrators group are not members of the securityadmin fixed server role. Figure 11.14. The Add Members dialog box shows you only those logins that have not been added to the selected role.
5.
Select the login to add to the selected fixed server role and click the OK button.
Comments
Membership in a fixed server role does not grant access to a database or data within the databases. Fixed server roles are intended for administrators and assistant administrators and do not automatically grant access to any of the data that SQL Server manages. Database object permissions (discussed later in this chapter in How-To 11.10) are required to gain access to data and database objects.
Page 468
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
The special sysadmin role should be reserved for trusted and trained system administrators. Members of this role are able to perform all SQL Server administrative tasks, and those tasks are applicable to all databases that SQL Server manages. Obviously, this can lead to serious problems in the wrong hands. Finally, when you add people to fixed server roles, make sure these people understand the consequences of their actions as system administrators. Because fixed server roles are global within SQL Server, the actions that fixed server role members perform could affect all the databases that SQL Server manages. Incorrectly configuring SQL Server or failing to carefully implement security can have a dramatic negative impact on every database that SQL Server manages. Members of the SQL Server BUILTIN/Administrators group are automatically added to the sysadmin fixed server role.
[ Team LiB ]
Page 469
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.8 Create a Database User Account
The logins that you created in How-To 11.5 or 11.6 provide access to SQL Server, but not to any databases within SQL Server. This is much like giving someone a key to a building, but not providing keys to offices within the building. The fixed server role that you might have specified in How-To 11.7 gives the person rights to perform serverwide administrative tasks such as creating or modifying databases. Using the building analogy, this is something like giving an electrician permission to rewire or modify the electrical service within the building. However, neither of these settings actually grants access to databases within SQL Server. Before a user can access a SQL Server database (somewhat like entering a locked office in the building), he must be provided with the database user account. I have been authenticated and logged into SQL Server and now I need to access data that is stored within a SQL Server database. Without a specific database user account, I am unable to access and use data that SQL Server manages.
Technique
Enterprise Manager provides the dialog boxes that are necessary to create user accounts in any of its databases. Be sure to add the user to every database that he requires. Otherwise, the user will not be able to use the data, run stored procedures, or otherwise access the database.
Steps
Simply logging in to SQL Server does not automatically establish a person's database identity. In other words, accessing SQL Server does not mean that SQL Server recognizes the person as a valid database user. This is particularly true when Windows NT/2000 authentication is used. After all, this authentication mode means that anyone who logs in to Windows is able to access the database. SQL Server needs to know exactly who the person is and what data and database objects this person is allowed to access. A SQL Server user account is needed for each user or group of users who is accessing SQL Server. Each SQL Server database maintains an internal registry of user accounts that are permitted into the database. This information is stored in the table named sysusers within the database. The account information travels with the database's MDF file and is backed up when the database is backed up. 1. 2. Open Enterprise Manager and expand the Northwind database icon. Right-click on the Users icon and select New Database User from the shortcut menu that appears. Alternatively, select New Database User from the Action menu. In either case, the Database User Properties dialog box opens (see Figure 11.15). Figure 11.15. You add new user accounts with the Database User Properties dialog box.
Page 470
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3.
Select a user or group login from the drop-down list at the top of the Database User Properties dialog box. If desired, you can provide a different username for the user account. Normally, however, you'll want to avoid complications by using the default username.
4.
Click the OK button to commit the new user account.
Comments
It is important to distinguish between a SQL Server login and a database user account. The SQL Server login simply allows a person to access SQL Server, but it does not provide access to databases. A database user account provides access to one and only one database that SQL Server manages. Each user, therefore, will need an account with each database he intends to use. This is why creating database user accounts for groups of users is much more efficient than adding user accounts for individual users. Database user accounts can be established for individual users as well as groups. The Login name drop-down list in the User Account Properties dialog box contains all the SQL Server logins you have created. The statement earlier that a user without a specific database account is unable to use the database is not entirely correct. SQL Server declines to default user accounts: guest and dbo. The guest account is used whenever a user seeks access to the database in which he has no specific account. Under most situations, the SQL Server system administrator has severely limited the ability of the default user account to access a database within SQL Server. Exactly how this is done is explained in How-To 11.10. The database owner (dbo) account owns all the objects that are created by anyone who is a member of the sysadmin fixed server role. You'll frequently see the dbo account listed as an
Page 471
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
object's owner simply because the database construction is most often left up to SQL Server's system administrators.
[ Team LiB ]
Page 472
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.9 Use Statement Permissions
SQL Server databases can become quite large and complex. It is important to control the number and type of objects that are added to a SQL Server database so that its structure contains only those objects that are actually required for the database's operation. If object creation were not controlled, users could build temporary tables, views, stored procedures, and other database objects that would become permanent additions to the database. There's no easy way to tell whether a particular database object is required by some front-end applications, making it difficult to remove these objects. I want to control unwanted and unneeded object proliferation in my databases. Without some kind of control, users might unnecessarily complicate the database's structure by adding unwarranted objects.
Technique
You will employ statement permissions to permit or disallow users to execute SQL statements that modify the database structure. There are also statement permissions controlling SQL statements that back up the database and its log file. These statements include the following:
CREATE DATABASE. Creates a new database (applicable only in the master database). CREATE DEFAULT. Establishes default values for columns in tables. CREATE FUNCTION. Creates a user-defined function that is saved as a Transact-SQL routine. CREATE PROCEDURE. Creates a stored procedure. CREATE RULE. Adds a rule to a column in a table. A rule specifies the acceptable values for the column.
CREATE TABLE. Creates a new table within the database. CREATE VIEW. Adds a view to the database. BACKUP DATABASE. Backs up the entire database to removable media. BACKUP LOG. Backs up the database's log file to removable media.
Although this security task has been discussed only from the perspective of limiting the user's ability to create database objects, statement permissions are also a way to ensure that users who really need to modify the database structure are able to do so. Statement permissions are applied at the database level. There are no global SQL Server statement permissions.
Steps
Logging in to SQL Server does not mean that a user is actually able to access and use the data and other objects that are stored in SQL Server. Each user account has certain permissions assigned to it that specify the account's ability to use the database and its objects. Statement permissions are one category of database permissions. Statement permissions specify which types of SQL DDL (data definition language) statements a user is allowed to execute against
Page 473
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
the database. DLL statements are frequently used to create and modify tables, add indexes to tables, and perform other data structure operations on the database. Statement permissions limit a user's ability to perform operations that could be dangerous to the database. After statement permissions have been established, the user is able to execute object creation statements (such as CREATE TABLE) only if the statements permission has been granted. By default, SQL Server does not grant statement permissions. As the SQL Server system administrator, you should grant these permissions only to users who require object creation ability. 1. 2. Open Enterprise Manager and expand the Northwind database's icon. Right-click on the Northwind database's icon and select Properties from the shortcut menu. This action opens the database's Properties dialog box (see Figure 11.16). Figure 11.16. The database Properties dialog box includes settings for statement permissions.
3.
Click on the Permissions tab. Notice that the leftmost column contains the roles and logins that you have created within the database. Select a role or login, and check the statement permissions you want to assign.
Comments
Each statement permission has three different states:
Revoke. The user is not given the statement permission unless he is a member of a role
Page 474
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
that has been given the permission. The graphic to depict this state is blank.
Grant. The user is given permission to run the statement. The graphic to depict this state is the check.
Deny. The user is denied the statement permission and cannot run the SQL Statement. The red X depicts this state.
Statement permissions are a great way to permit assistants the ability to add tables, views, stored procedures, and other objects as needed. Because the default setting is to deny these permissions, you do not have to worry about unwarranted object proliferation in your databases.
[ Team LiB ]
Page 475
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.10 Use Object Permissions
At this point, you have added SQL Server logins and established user accounts in each database within SQL Server. In most situations, you want to restrict the user's access to tables, views, stored procedures, and other objects within this database. This is done by setting permissions on these database objects. I do not want every user to have read, write, and update permissions on every table within the database. Otherwise, unauthorized users are able to view data that they are not permitted to see. Often, only certain users are permitted to add new records or to delete existing records in a database table. Without object permissions, I have no way of controlling individual user access to the data within a database.
Technique
You'll use the Enterprise Manager dialog boxes to assign permissions on the objects within a database. SQL Server provides the following object permissions for tables, views, and stored procedures:
Select. Permission to issue SELECT statements against a table or view to retrieve data. Insert. Permission that allows the user to execute the INSERT statement to add new records to a table or view.
Update. Permission that allows the UPDATE statement to run, changing the data in a row of a table or view.
Delete. Permission to run the DELETE statement and remove rows from a table or view. Execute. Permission that allows the user to run stored procedures and functions within the database.
Steps
A SQL Server database contains a wide variety of database objects, such as tables, views, and stored procedures. A user account can be assigned specific permissions on each object in a SQL Server database. These permissions direct SQL Server to allow an account to run stored procedures, view and update data that is contained in tables, and perform other database operations. As you click on the individual object permissions, the check box changes from empty to a green check mark to a red X, as mentioned in the previous How-To. 1. 2. Open Enterprise Manager and expand the Northwind database's icon. Expand the Northwind database's Tables icon to display all the tables in Enterprise Manager's right pane. 3. Right-click on a table in the Tables list, and select Properties from the shortcut menu to open the Table Properties dialog box (see Figure 11.17). Figure 11.17. The Table Properties dialog box displays important information about the table.
Page 476
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Select the Permissions button in the upper-right corner of the Table Properties dialog box to displaythe Permissions tab (see Figure 11.18). Figure 11.18. The Permissions tab contains all the object permission settings for the table.
Page 477
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
5.
Select a user or role from the leftmost column, and then click on the check box in any of the Permissions columns.
Comments
Each permission on an object has three levels of access:
Grant. SQL Server permits all operations whose permission is set to Grant. Revoke. The user is unable to perform the operation unless he's been implicitly granted permission through membership in some role (discussed in How-To 11.11) or through a group. Revoke is the default setting for all permissions.
Deny. The user cannot perform a denied operation, even if permission is implicitly granted by role or group membership.
Most often, unless the user has a specific need to be granted or denied permission on an object, you'll leave the permission set to Revoke. This means that the permission is not provided unless the user is given permission through a database role (discussed in the next section). Generally speaking, it is better to provide too little access to database objects than to grant too much access that could lead to confidentiality or data integrity problems. This is why the default permission on SQL Server objects is set to Revoke by default.
[ Team LiB ]
Page 478
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.11 Use Fixed Database Roles
Creating database accounts and assigning permissions is obviously a lot of work. When you consider that most SQL Server installations service dozens to hundreds of users, it's easy to see that a considerable amount of time and effort goes into administering database security. All in all, creating and managing a database security scheme is one of the most time- and effort-intensive tasks of any database administrator. Fortunately, SQL Server provides a tool to considerably lighten this administrative load. As you'll see in this section, SQL Server makes it easy to assign predefined permissions to groups of users rather than individually handling each user. Setting up database object permissions for individual users is a hassle. Every time a user account is added to SQL Server, the permissions on database objects must be set for the user. I'd like to be able to minimize the amount of time spent designing individual object permissions for my users.
Technique
SQL Server defines many built-in fixed database roles that grant or deny permissions on database objects. Each fixed database role adds or subtracts permissions on all the tables, stored procedures, or other database objects within the database. A user who is added to a fixed database role inherits all the permissions specified by the role. A person can belong to multiple roles, if necessary.
Steps
A fixed database role is similar in some ways to the fixed server roles discussed earlier in this chapter. The difference is that fixed database roles determine permissions to perform operations on objects within a single database, whereas fixed server roles specify the administrative operations that are permitted on all SQL Server databases. SQL Server defines 10 different fixed database roles:
db_owner. As owners of the database, members of this role can perform any task that is granted to the other fixed database roles. The db_owner role includes all administrative, design, and data access permissions.
db_accessadmin. The db_accessadmin role manages the creation of new logins and accounts. These logins and accounts include individual users as well as groups of users.
db_datareader. This role is able to view all data from all tables in the database. db_datawriter. The db_datawriter role is able to add, update, or delete data from all the tables in the database.
db_ddladmin. This role can modify objects within the database. This means that db_ddladmin users can add or delete tables or modify the design of existing tables.
db_securityadmin. Members of the db_securityadmin role manage security on the database. This means they can add new roles and manage statement and object permissions within the database.
db_backupoperator. This role is responsible for backing up the database.
Page 479
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
db_denydatareader. Members of this role are unable to view data in the database. This role is useful for data entry clerks whose job is inputting new data without viewing existing records.
db_denydatawriter. Use this role to prevent users from changing data in the database. This is useful, for instance, for clerical and management staff who are supposed to be able to read, but not update, data.
public. This role is for all users of the database that don't have specifically defined roles or permissions in the database. You can edit the permissions of the public role, but be careful.
The db_prefix on each of these roles is significant. It's there to help distinguish between fixed server roles (explained earlier in this How-To and discussed in the following section) from the fixed database roles explained in this section. 1. 2. Open Enterprise Manager and expand the Northwind database's icon. Locate and expand the Northwind database's Roles icon to display the fixed database roles in Enterprise Manager's right pane (see Figure 11.19). Figure 11.19. SQL Server 2000 defines 10 different fixed database roles.
3.
Right-click on a role (such as db_securityadmin) in the Roles list, and select Properties from the shortcut menu. You'll see the Database Role Properties dialog box (shown in Figure 11.20) open in response. Figure 11.20. Use the Database Role Properties dialog box to assign login accounts to a SQL Server's fixed database role.
Page 480
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
4.
Click on the Add button to open the Add Role Members dialog box (see Figure 11.21). This dialog shows all database accounts that are not currently assigned to the selected role. Figure 11.21. The Add Role Members dialog box shows everyone who is not currently assigned to the selected role.
5.
Click on any members you'd like to add to the selected role. The list box in the Add Role Members dialog box allows you to select multiple logins at one time.
6.
When you are satisfied with your selections, click the OK button to close the Add Role
Page 481
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Members dialog box; then close the Database Role Properties dialog box by clicking on its OK button.
Comments
The fixed database roles are not to be confused with the similar fixed server roles. Each fixed database role applies only to a single database. The members you add to a role are only able to operate with the role inside of the selected database. Fixed server roles, on the other hand, affect all databases within SQL Server as well as SQL Server. Therefore, fixed database role security is the ideal way to assign specific permissions on a single database. This can be useful to allow departmental groups within a company to manage their own databases. Because relatively small amounts of data are influenced by fixed database roles (this depends, of course, on the type and size of the database), it isn't as likely that a poorly trained individual will damage the data within SQL Server.
[ Team LiB ]
Page 482
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.12 Create Custom Database Roles
Even though the 10 built-in fixed server roles might appear to cover all contingencies, it is possible to create custom database roles for your SQL Server databases. One of the problems with the fixed database roles is that they apply to all objects within the database. Therefore, assigning users to the db_datareader role means that they'll be able to read data in all tables and views within the database. What should you do if you want to provide access just to one or two tables instead of every table? My database includes a mix of public and confidential information. I want to set up a role that permits read access to the Categories and Products tables, but does not allow access to the Employees or Customers tables.
Technique
You'll create a custom database role that specifies read permissions on the Products and Categories tables, but does not give access to any other table in the database.
Steps
One of the essential qualities of SQL Server is its flexibility in dealing with almost any environment. As an example of this flexibility, SQL Server provides custom database roles, which are freely modified to include permissions to perform any administrative task. The SQL Server system administrator creates the custom database roles and assigns them to any users who require the special combination of permissions on the database objects. SQL Server recognizes the security profiles that are established with custom database roles the same as fixed database roles. Although considerable work is involved in setting up custom database roles, you are assured that your users can view, edit, and add records only to those tables you want them to. 1. 2. Open Enterprise Manager and expand the Northwind database's icon. Right-click the Northwind database's Roles icon and select New Database Role from the shortcut menu. The New Role dialog box (see Figure 11.22) opens in response. Notice how similar this dialog box is to the Database Role Properties dialog box shown in Figure 11.20. Figure 11.22. Add a custom database role with the New Role dialog box.
Page 483
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. 4.
Provide a name such as ProdCatReadOnly for the custom database role. Add users to the new role as you did in steps 4 and 5 in section 11.11. In this case, you'll add the guest user so that all SQL Server users who are added to this role will have access to the tables.
5. 6.
Click OK to close the New Role dialog box and to establish the ProdCatReadOnly role. Right-click on the ProdCatReadOnly role and select Properties from the shortcut menu. When the Database Role Properties dialog box opens, click on the Permissions button in the upper-right corner to display the Permissions tab (see Figure 11.23). Figure 11.23. Set the database object permissions with the Permissions tab of the Database Role Properties dialog box.
Page 484
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
7.
Locate the Categories and Products table and click on the check box in the SELECT column until a green check mark appears for each table. Notice that as you continue to click on the check box, its icon changes from the green check mark to a red X, and then empty again. These icons indicate the permission states on the table: green means grant, the red X means deny, and the empty check box means revoke.
8.
Click the OK button to close the Permissions dialog box, and then close the Database Role Properties dialog box.
Comments
You'll notice in Figure 11.23 that the list box on the permissions tab shows all the database objects, including tables, views, and stored procedures. You are able to enable or disable the SELECT, INSERT, UPDATE, DELETE, and EXEC permissions for any of the objects that appear in the list. It's easy to go overboard on setting up a custom database role. You can overly complicate a custom database role by overloading it with too many security settings. Generally speaking, you're better off with several simple, easy-to-understand custom database roles than one or two massive, complicated custom roles.
[ Team LiB ]
Page 485
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 11.13 Create Application Roles
As if fixed database roles and custom database roles weren't enough, SQL Server provides a third category of database role. Sometimes you want users to simply start up an application and have access to SQL Server's data through the application. In these cases, you don't want to have to set up logins, user accounts, and other security configurations to accommodate the application's users. This is the job of application roles. I have users who routinely access SQL Server through an application that I've written in Visual Basic. I also have users who use Web pages to access the data using ASP techniques. I'd like a simple and easy way to provide these users with limited access to the database, but I don't want to spend a lot of time configuring SQL Server.
Technique
Create a SQL Server 2000 application role for these users. The application logs into SQL Server and provides the password that is required to access data. Typically, application roles are severely limited in their ability to access data.
Steps
SQL Server provides for the creation of application roles. An application role is established to allow programs that are written in Visual Basic and other programming languages to freely access and update SQL Server data. People cannot use application roles. You cannot add users, groups, or other roles to an application role. The application role is not enabled until a password is provided. At runtime, the user's application will provide the role's name and password to gain access to the data that is granted by the application role. The application is unable to do anything other than the permissions you established for the application role. 1. 2. Open Enterprise Manager and expand the Northwind database's icon. Right-click the Northwind database's Roles icon and select New Database Role from the shortcut menu. The New Role dialog box opens in response (see Figure 11.24). Select the Application Role option button near the bottom of this dialog box. Figure 11.24. The New Role dialog box allows you to create application roles.
Page 486
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
3. 4. 5. 6.
Provide a name and a password for the application role. Click the OK button to save the application role. Right-click the new application role, and select Properties from the shortcut menu. Set the object permissions as you did in steps 6, 7, and 8 in section 11.12 in this chapter.
Comments
An application role bypasses the normal permissions that are applied to a database. A user who is not otherwise able to access data will be able to use a program such as Excel, Word, or Visual Basic to get at the data as long as an application role has been established for the program. The permissions that are established for the application role exist only while the application maintains a connection to the database. While the application role is active, all other permissions that are granted to the user on the database are suspended, and only the permissions that the application role provides are enabled. A user can't exploit an application role to access other databases that SQL Server manages. The only permissions that an application role has on other databases are the permissions granted to the default guest user. Under most circumstances, the system administrator will have disabled or severely limited the SQL Server guest account.
[ Team LiB ]
Page 487
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 12. Utilizing XML Data In Your Visual Basic .NET Applications
In this chapter you will
Utilize XML in .NET Use XML namespaces in .NET Use XMLWriter to create an XML document Use XMLReader to read an XML document Work with the XML document object model Retrieve XML from SQL Server 2000 Work with datasets and XML
Extensible Markup Language (XML) is to data what Hypertext Markup Language (HTML) is to presentation. XML is similar to HTML; in fact, it is derived from the same standard. As you deal with outside systems over the Internet or even by importing data, you will need to access XML data at one time or another.
[ Team LiB ]
Page 488
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Ways of Utilizing XML in .NET
You can utilize XML from within .NET in hundreds of ways. The following list spells out some of those ways. The first three ways will be shown in some of the How-Tos later in this chapter.
Utilizing the XML Document Object Model (DOM) Reading XML with the XMLReader Writing XML with the XMLWriter Validating XML with Schemas Using XPathNavigator in the .NET Framework Integrating XML with Relational Data and ADO.NET
To use XML, you must use the XML namespaces that are available within .NET.
[ Team LiB ]
Page 489
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] XML Namespaces in .NET
.NET utilizes XML for a number of purposes behind the scenes. As such, .NET has a number of namespaces that not only can you use, but that .NET uses as well. Those namespaces are as follows:
System.XML. Provides standards-based support for processing XML. System.XML.Xpath. Contains the XPath parser and evaluation engine. System.XML.XSL. Provides support for Extensible Stylesheet Transformations (XSLT). System.XML.Schema. Contains the XML classes that provide standards-based support for XML Schemas Definition (XSD) language schemas.
You will see some classes within these namespaces utilized in this chapter. You can enhance the classes to handle almost any task you might have that utilizes XML.
[ Team LiB ]
Page 490
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 12.1 Use XMLWriter to Create an XML Document
Sometimes I need to take data that is in my database and write it out to an XML document. I heard that XMLWriter is a good way to do this. What does XMLWriter do, and how do I create an XML document with it?
Technique
The XMLWriter provides a quick way to generate streams or files that contain XML data. The stream is not cached; it is forward-only. The XML data that the XMLWriter generates conforms to W3C XML 1.0 and the namespaces in XML recommendations. With XMLWriter, you can accomplish the following:
Create well-formed XML. Manage the output WriteState property. including methods to determine the progress of the output with the
Flush or close the output. Write multiple documents to one output stream. Encode binary bytes as base64 and as binhex, and write out the resulting text. Report the current namespace prefix, xml:lang, or xml:space scope. Write valid names, qualified names, and name tokens.
XMLWriter has one implementation: the XMLTextWriter. To show you how to use the XMLTextWriter, the sample code will create a data table, allowing the user to add names to it. Then the XMLTextWriter will be used to write the data from the data table into an XML document.
Creating the Data Table
Rather than using a DataAdapter object to create and populate the data table from live data, the code will create the data table from scratch, and the user will add data to it. To perform this task, add the properties and methods shown in Table 12.1. The first object that will be created and utilized is the DataColumn object. Table 12.1. Objects, Properties, and Methods for Creating a DataTable Object Object Property/Method Description Specifies the Column name for the current data column that is being created. Stores the Caption used to be displayed. Adds the current DataColumn object to the collection of columns in the data table.
DataColumn
ColumnName
DataColumn
Caption
DataTable.Columns Add
DataTable
NewRow
Creates a DataRow object.
Page 491
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataRow
Item(ColumnName) Replaces data in the specified column, in the current DataRow object. Add
Adds the data row to the collection of rows in the data table .
DataTable.Rows
Using the XMLTextWriter Implementation
The last task that the example performs is creating the XML document by using the properties and methods of the XMLTextWriter class, shown in Table 12.2. Table 12.2. XMLTextWriter Properties and Methods Used for This How-To Property/Method Description Writes the XML declaration with the version 1.0. Specifies how you want the XML file formatted. In this case, System.Xml.Formatting.Indented is used. Writes the DOCTYPE declaration with the specified name and optional attributes. This allows you to specify the type of objects that this document represents. Allows you to write comments into your XML document. Used for both the rows and the columns, this lets you specify the starting element for a row that is represented from a table.
WriteStartDocument Formatting
WriteDocType
WriteComment WriteStartElement
WriteAttributeString Writes columns and properties for data that is represented in the XML
document.
WriteEndElement Flush Close Steps
Ends the row or column. Flushes the stream from memory. Closes the string.
Open and run the Visual Basic .NET Chapter 12 solution. From the main Web page, click on the hyperlink with the caption How-To 12.1: Use XMLWriter to Create an XML Document. When the page loads, you can enter a few names by entering the last and first names and then clicking the button labeled Add to DataTable. When you have added a few names, click the button labeled Create XML File. Using Explorer, open the file created in C:\ called test.xml (see Figure 12.1). 1. Create a Web Form. Then place the Labels, TextBoxes, Buttons, and DataGrid objects as seen in Figure 12.1 on the form with the properties set as in Table 12.3.
Table 12.3. Label, TextBox, and Button Control Property Settings Object Property Setting
Page 492
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label TextBox Label TextBox Button
Text ID Text ID ID Text
Last Name txtLastName First Name txtFirstName btnAdd Add to DataTable btnCreateXMLFile Create XML File dgDataToWrite hplReturnToMain wfrmMain.aspx
Button
ID Text
DataGrid HyperLink
ID ID NavigateURL
2.
Add the following line to the code module of the form. Place it under the line that reads Web
Form Designer Generated Code.
3. 4. 5. Dim mdtData As New DataTable() Add the code in Listing 12.1 to the Load event of the page. If the data table has not been saved to the Session object, then you need to create it from scratch by first creating the data columns and then adding them to the data table. The DataTable object is then saved to the Session object with the name MyDataTable. If the Session object entry already exists, it is assigned back to the module variable mdtData. Last, the data table is bound to the DataGrid object by calling the BindTheGrid routine, which is described in the next step. Listing 12.1 wfrmHowTo12_1.aspx.vb: Creating a DataTable Object from Scratch
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If (Session("MyDataTable") Is Nothing) Then Dim dcFirstName As New DataColumn() dcFirstName.ColumnName = "FirstName" dcFirstName.Caption = "First Name" mdtData.Columns.Add(dcFirstName) Dim dcLastName As New DataColumn()
Page 493
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
dcLastName.ColumnName = "LastName" dcLastName.Caption = "Last Name" mdtData.Columns.Add(dcLastName) Session("MyDataTable") = mdtData Else mdtData = CType(Session("MyDataTable"), DataTable) End If BindTheGrid() End Sub 6. Create the routine BindTheGrid, shown in Listing 12.2, in the code module for the page. Listing 12.2 wfrmHowTo12_1.aspx.vb: Binding the Data Table to the Data Grid
Sub BindTheGrid() dgDataToWrite.DataSource = mdtData dgDataToWrite.DataBind() End Sub 7. Add the code in Listing 12.3 to the Click event of the btnAdd button. This routine starts off by calling the NewRow method off the mdtData data table, thus creating a new DataRow object. The two columns in drNew are replaced with the values in txtLastName and txtFirstName. The new row is added to the data table, and the text boxes are cleared. Last, mdtData is rebound to the data grid by calling BindTheGrid. Listing 12.3 wfrmHowTo12_1.aspx.vb: Adding Data to the Data Table and Then Rebinding the Data Grid
Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click Dim drNew As DataRow drNew = mdtData.NewRow() drNew.Item("LastName") = Me.txtLastName.Text drNew.Item("FirstName") = Me.txtFirstName.Text mdtData.Rows.Add(drNew) Me.txtLastName.Text = "" Me.txtFirstName.Text = "" BindTheGrid()
Page 494
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
End Sub 8. Add the code in Listing 12.4 to the Click event of the btnCreateXMLFile button. The first task is to declare an instance of the XMLTextWriter. Then the XMLTextWriter creates and opens the file c:\Text.xml. Next, the XML document is created using the Write methods, including the writing of the individual rows of the DataTable object. Last, the data is flushed, and the XMLTextWriter is closed. Listing 12.4 wfrmHowTo12_1.aspx.vb: Creating the XML Document
Private Sub btnCreateXMLFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCreateXMLFile.Click Dim xtwMyData As System.Xml.XmlTextWriter = Nothing Dim intCurrRow As Integer Dim intNumRows As Integer xtwMyData = New System.Xml.XmlTextWriter("c:\Test.XML", Nothing) intNumRows = mdtData.Rows.Count - 1 With xtwMyData .WriteStartDocument(False) .Formatting = System.Xml.Formatting.Indented .WriteDocType("Names", Nothing, Nothing, Nothing) .WriteComment("This file represents names list") .WriteStartElement("names") For intCurrRow = 0 To intNumRows '-- Start the current row .WriteStartElement("name", Nothing) '-- Write the fields .WriteAttributeString("FirstName", _ mdtData.Rows(intCurrRow).Item("FirstName")) .WriteAttributeString("LastName", _ mdtData.Rows(intCurrRow).Item("LastName")) '-- Ending the row .WriteEndElement() Next '-- Write the XML to file and close the writer .Flush() .Close() End With End Sub Figure 12.1. This XML document was created using XMLTextWriter.
Page 495
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
This is one of three ways described in this chapter of how to write data out to an XML document. This is probably the second easiest method. The other two methods are using the XML DOM (described in How-To 12.3), which is the hardest method, and using the WriteXML method off the DataSet object (described in How-To 12.5), which is the easiest method of all three. The amount of control you have over the document matches the degree of difficulty in use.
[ Team LiB ]
Page 496
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 12.2 Use XMLReader to Read an XML Document
In How-To 12.1, I learned how to write out data to an XML document by using the XMLWriter. How do I read data using the XMLReader?
Technique
Whereas the XMLWriter has one implementation (class), the XMLReader has three, depending on the task you need to perform. Those classes are listed in Table 12.4. Table 12.4. XMLWriter Implementations Class Name Purpose/Descriptions Reads character streams. This is a forward-only reader that has methods returning data on content and node types. No validation occurs. Provides a parser over an XML Document Object Model (DOM) API, similar to the XMLNode tree.
XMLTextReader
XMLNodeReader
XMLValidatingReader Takes an XMLTextReader adding validation. In doing so, it provides a
fully compliant validating or non-validating XML parser with DTD, XSD schema, or XML-Data Reduced (XDR) schema support . For this How-To, you will be using the XMLTextReader to read the file and display the results. To do this, you will use the following methods:
Read. Reads a line of the character stream out of the XMLReadReader. AttributeCount. Gives the count of attributes. This depends on the type of data that is being read. In this case, AttributeCount is used to display the individual attributes, which will be columns.
NodeType. Allows you to specify node types in the XML document. In the case of this How-To, the System.Xml.XmlNodeType.XmlDeclaration is checked for so that no information is printed for that type of node. You can see the other node types by looking at intellisense for the NodeType property.
Steps
Value. Represents the actual value of the line in the stream. Close. Closes the stream.
Open and run the Visual Basic .NET Chapter 12 solution. From the main Web page, click on the hyperlink with the caption How-To 12.2: Use XMLReader to Read an XML Document. When the page loads, click the button labeled Read XML File. The example then reads the XML file that is specified in the text box labeled File to Read and displays the information in the text area located at the bottom of the form (see Figure 12.2). 1. Create a Web Form. Then place the Label, TextBox, and Button objects as seen in Figure 12.2 on the form with the following properties set as in Table 12.5.
Page 497
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table 12.5. Label, TextBox, and Button Control Property Settings Object Property Setting
Label TextBox Button
Text ID ID Text
File to Read txtFileToRead btnReadFile Read XML File taOutput hplReturnToMain wfrmMain.aspx
TextArea HyperLink
ID ID NavigateURL
2.
Note
You will find the TextArea control in the HTML Components section of the toolbox. After you have dragged this control onto the Web Form, right-click and choose Run as Server Control from the pop-up menu. This will then run this control as a server side control, and you will be able to work with its properties and methods in code behind.
3. Add the code in Listing 12.5 to the Click event of btnReadFile. To start off, the
XXLTextReader is initialized with the XML document specified in txtFileToRead. Then each node of the document is read using the Read method. The node type is compared to
make sure the current node is not the XMLDeclaration. If it's not, then each of the attributes is displayed; in this case, the columns of each name are entered. After each of the nodes (rows) have been read and added to strOut, then that string is assigned to the InnerText property of the TextArea object called taOutput. Last, the XMLTextReader object is closed. Listing 12.5 wfrmHowTo12_2.aspx.vb: Reading an XML Document Using
XMLTextReader
Private Sub btnReadFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReadFile.Click Dim xtrNames As System.Xml.XmlTextReader Dim strOut As String Dim intAtts As Integer Dim intCurrAtt As Integer Try
Page 498
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
strOut = "Reading file " & _ Me.txtFileToRead.Text & "..." & vbCrLf xtrNames = New System.Xml.XmlTextReader(Me.txtFileToRead.Text) While xtrNames.Read() intAtts = xtrNames.AttributeCount If xtrNames.NodeType <> System.Xml.XmlNodeType.XmlDeclaration Then If intAtts > 0 Then For intCurrAtt = 0 To intAtts - 1 strOut &= xtrNames(intCurrAtt) & " " Next Else strOut &= xtrNames.Value End If End If End While Catch excp As Exception strOut &= "Following Error Occurred: " & excp.Message Finally strOut &= vbCrLf & "Done Processing " & Me.txtFileToRead.Text & "" taOutput.InnerText = strOut If Not xtrNames Is Nothing Then xtrNames.Close() End If End Try End Sub Figure 12.2. The information displayed here was read from an XML document using XMLReader.
Page 499
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
Again, as with XMLTextReader, this falls into the middle of complexity when it comes to reading XML documents. If you want to actually validate the data, then you should use the XMLValidatingReader implementation of the XMLReader, rather than the XMLTextReader.
[ Team LiB ]
Page 500
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 12.3 Work with the XML Document Object Model
I want to have more control over the XML document as I create it. I heard that I can do this with XML DOM. How do I work with the XML Document Object Model?
Technique
In How-Tos 12.1 and 12.2, you saw two ways to independently read and write XML documents. However, what if you want to do both at the same time? To have this kind of flexibility, you need to use the XML Document Object Model, also known as DOM. The DOM class is an XML document that is represented in memory. It allows you not only to programmatically read and write out XML documents, but also to modify those documents in memory. Within the DOM, the XMLNode object is the base object in the DOM Tree, XMLDocument class that extends it. XMLDocument has methods that allow you to perform operations on the document as a whole. It also lets the developer work with the nodes in the entire XML document. Both XMLNode and XMLDocument have performance and usability enhancements over prior versions. The properties and methods of XMLNode and XMLDocument that will be used for this How-To are listed in Table 12.6. Table 12.6. DOM Properties and Methods Used in This How-To Class Name Property/Method Purpose/Description Loads an XML document into the XMLDocument object. In this case, it is a means to create the stub for the XML document that will be created from the dataset.
XMLDocument LoadXML
XMLDocument DocumentElement Serves as the root element for the document. It is, in fact, of the type XMLElement. XMLDocument CreateNode XMLElement AppendChild XMLDocument CreateComment XMLNode AppendChild
Creates an XMLNode object. Appends the node created to the element specified as a child. Adds a comment to the XML document. Appends a node to another node as a child. Saves the current XML document.
XMLDocument Save Steps
Open and run the Visual Basic .NET Chapter 12 solution. From the main Web page, click on the hyperlink with the caption How-To 12.3: Working with the XML Document Object Model. As with How-To 12.1, when the page loads, you can enter a few names. Enter the last and first names, and then click the button labeled Add to DataTable. When you have added a few names, click the button labeled Create XML File. Using Explorer, open the file created in C:\ called test.xml(see
Page 501
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Figure 12.3). 1. Create a Web Form. Then place the Labels, TextBoxes, Buttons, and DataGrid objects as seen in Figure 12.3 on the form with the properties set as in Table 12.7.
Table 12.7. Label, TextBox, and Button Control Property Settings Object Property Setting
Label TextBox Label TextBox Button
Text ID Text ID ID Text
Last Name txtLastName First Name txtFirstName btnAdd Add to DataTable btnCreateXMLFile Create XML File dgDataToWrite hplReturnToMain wfrmMain.aspx
Button
ID Text
DataGrid HyperLink
ID ID NavigateURL
2.
Add the following line to the code module of the form. I place it under the line that reads Web Form Designer Generated Code.
3. 4. 5. Dim mdtData As New DataTable() Add the code in Listing 12.6 to the Load event of the page. If the data table has not been saved to the Session object, then it is created from scratch by first creating the data columns and then adding them to the data table. The DataTable object is then saved to the Session object with the name MyDataTable. If the Session object entry already exists, it is reassigned to the module variable mdtData. Last, the data table is bound to the DataGrid object by calling the BindTheGrid routine, which is described in the next step. Listing 12.6 wfrmHowTo12_3.aspx.vb: Creating a DataTable Object from Scratch
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load
Page 502
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
'Put user code to initialize the page here If (Session("MyDataTable") Is Nothing) Then Dim dcFirstName As New DataColumn() dcFirstName.ColumnName = "FirstName" dcFirstName.Caption = "First Name" mdtData.Columns.Add(dcFirstName) Dim dcLastName As New DataColumn() dcLastName.ColumnName = "LastName" dcLastName.Caption = "Last Name" mdtData.Columns.Add(dcLastName) Session("MyDataTable") = mdtData Else mdtData = CType(Session("MyDataTable"), DataTable) End If BindTheGrid() End Sub 6. Create the routine BindTheGrid, shown in Listing 12.7, in the code module for the page. Listing 12.7 wfrmHowTo12_3.aspx.vb: Binding the Data Table to the Data Grid
Sub BindTheGrid() dgDataToWrite.DataSource = mdtData dgDataToWrite.DataBind() End Sub 7. Add the code in Listing 12.8 to the Click event of the btnAdd button. This routine starts off by calling the NewRow method off the mdtData data table, thus creating a new DataRow object. The two columns in drNew are replaced with the values in txtLastName and txtFirstName. The new row is added to the data table, and the text boxes are cleared. Last, mdtData is rebound to the data grid by calling BindTheGrid. Listing 12.8 wfrmHowTo12_3.aspx.vb: Adding Data to the Data Table and Then Rebinding the Data Grid
Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click Dim drNew As DataRow
Page 503
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
drNew = mdtData.NewRow() drNew.Item("LastName") = Me.txtLastName.Text drNew.Item("FirstName") = Me.txtFirstName.Text mdtData.Rows.Add(drNew) Me.txtLastName.Text = "" Me.txtFirstName.Text = "" BindTheGrid() End Sub 8. Add the code in Listing 12.9 to the Click event of the btnCreateXMLFile button. After getting the number of rows in mdtData, an XML document is started using the LoadXML method. Next, the root element is retrieved so that nodes can then be "hung" from it, using the CreateNode and AppendChild methods. A comment is then added using the
CreateComment method of xdMyData. Then, for each of the rows in the mdtData, nodName is created using CreateNode and AppendChild methods, and node on nodName is added for the LastName and FirstName. Again, these nodes are added using the CreateNode and AppendChild methods. Last, the Save method is used to save the XML document.
Listing 12.9 wfrmHowTo12_3.aspx.vb: Creating the XML Document
Private Sub btnCreateXMLFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCreateXMLFile.Click Dim xdMyData As New System.Xml.XmlDocument() Dim xeRoot As System.Xml.XmlElement Dim intCurrRow As Integer Dim intNumRows As Integer intNumRows = mdtData.Rows.Count - 1 With xdMyData '-- Start the XML document .LoadXml("") xeRoot = .DocumentElement Dim nodRoot As System.Xml.XmlNode = _ .CreateNode(System.Xml.XmlNodeType.Element, "Names", "") xeRoot.AppendChild(nodRoot) '-- Add the comment .CreateComment("This file represents names list created using the XML DOM")
Page 504
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
For intCurrRow = 0 To intNumRows '-- Start the current row Dim nodName As System.Xml.XmlNode = _ .CreateNode(System.Xml.XmlNodeType.Element, "name", "") nodName = nodRoot.AppendChild(nodName) '-- Add the attributes (columns) Dim nodFirstName As System.Xml.XmlNode = _ .CreateNode(System.Xml.XmlNodeType.Element, "FirstName", "") nodFirstName.InnerText = mdtData.Rows(intCurrRow).Item("FirstName") nodName.AppendChild(nodFirstName) Dim nodLastName As System.Xml.XmlNode = _ .CreateNode(System.Xml.XmlNodeType.Element, "LastName", "") nodLastName.InnerText = mdtData.Rows(intCurrRow).Item("LastName") nodName.AppendChild(nodLastName) Next '-- Write the XML to file and close the writer .Save("c:\Test.xml") End With End Sub Figure 12.3. This XML document was created using XMLTextWriter.
Page 505
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
As you can see, working with the DOM takes a bit more time and work. However, when you really need to massage the data, this is the way to go!
[ Team LiB ]
Page 506
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 12.4 Retrieve XML from SQL Server 2000
Sometimes I have to pull data from my SQL Server database into an XML document format. How do I do that with SQL Server 2000?
Technique
To accomplish this task, you will create a Command object with the Transact-SQL SELECT statement that you want to execute. However, at the end of your SQL statement, you will add the clause FOR XML mode. The mode can be any of these that are listed:
RAW. With this mode, each of the rows that is returned in the query result is made into a generic XML element with
as the identifier tag.
AUTO. Each of the rows and the columns are identified with tags for each of the elements and attributes, using the column names as identifier tags.
EXPLICIT. Here, you have to nest and create your query in a particular way. For more information on this mode, check out the SQL Server Books Online.
For this example, the code will use the RAW mode and look like this:
SELECT * FROM Customers FOR XML RAW
To execute the SQL statement in this case, you use the method ExecuteXMLReader. When you use this method, an XMLReader is returned. You should then iterate through the elements as seen in How-To 12.2.
Steps
Open and run the Visual Basic .NET Chapter 12 solution. From the main Web page, click on the hyperlink with the caption How-To 12.4: Retrieving XML from SQL Server 2000. When the page loads, you will see an example of a T-SQL statement that retrieves data from SQL Server 2000 in an XML format. Click on the button labeled Retrieve XML, and the data will be listed in the TextArea at the bottom of the form (see Figure 12.4). 1. Create a Web Form. Then place the Label, TextBox, and Button objects as seen in Figure 12.4 on the form with the properties in Table 12.8 set.
Table 12.8. Label, TextBox, and Button Control Property Settings
Object Label TextBox
Property Text ID Text ID
Setting SQL To Execute txtSQLToExecute SELECT * FROM Customers FOR XML AUTO, ELEMENTS btnRetrieveXML
Button
Page 507
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Text TextArea ID
Retrieve XML taOutput hplReturnToMain
HyperLink ID
NavigateURL wfrmMain.aspx
2. Add the code in Listing 12.10 to the Click event of btnRetrieveXML. Taking the SQL statement displayed in the "Technique" section, the Command object cmdCust is created, and ExecuteXMLReader is invoked. The XMLReader then iterates through each of the elements in the document, and they concatenate to a string. Last, the string is assigned to the InnerText property of taOutput, and the connection to the XMLReader object is closed. Listing 12.10 wfrmHowTo12_4.aspx.vb: Reading an XML Document Using XMLTextReader
Private Sub btnRetrieveXML_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnRetrieveXML.Click Dim cnn As New SqlClient.SqlConnection(BuildCnnStr("(local)", "Northwind")) Dim cmdCust As SqlClient.SqlCommand = New SqlClient.SqlCommand( _ Me.txtSQLToExecute.Text, cnn) Dim xrCust As System.Xml.XmlReader Dim intAtts As Int32 Dim intCurrAtt As Int32 Dim strOut As String Try cnn.Open() xrCust = cmdCust.ExecuteXmlReader() While xrCust.Read() intAtts = xrCust.AttributeCount If xrCust.NodeType <> System.Xml.XmlNodeType.XmlDeclaration Then If intAtts > 0 Then For intCurrAtt = 0 To intAtts - 1 strOut &= xrCust(intCurrAtt) & vbCrLf Next Else strOut &= xrCust.Value & vbCrLf End If End If End While Catch excp As Exception strOut &= "Following Error Occurred: " & excp.Message
Page 508
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Finally strOut &= vbCrLf & "Done Processing " taOutput.InnerText = strOut If Not xrCust Is Nothing Then xrCust.Close() End If cnn.Close() End Try End Sub Note
You have been using the BuildCnnStr() function throughout this book. You should add this function to a module or copy it from other chapters. Here is the code for the function:
Function BuildCnnStr(ByVal strServer As String, ByVal strDatabase As String) As String Dim strTemp As String strTemp = "Data Source=" & strServer & ";" strTemp &= "Initial Catalog=" & strDatabase & ";" strTemp &= "Integrated Security=SSPI" Return strTemp End Function
Figure 12.4. The information displayed here was read from SQL Server in an XML format.
Page 509
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
Normally, you would be taking the XML document that the command object returned and passing that on to another system that requires the data to be in XML format. The data was displayed from the XMLReader for demonstration purposes.
[ Team LiB ]
Page 510
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 12.5 Work with Datasets and XML
Sometimes, I have to pull XML documents into datasets and vice versa. How do I accomplish this using .NET?
Technique
.NET has developed a number of ways to utilize datasets and XML together. The simplest use is pushing data between the two. To do this, you have the two methods belonging to the DataSet object: ReadXML and WriteXML. For both of these methods, you need to provide a filename to read or write the XML document to. To demonstrate how to take advantage of these methods, I created a form that looks similar to the other How-Tos showing how to write XML documents. However, for this example, I also added another button and data grid that will show the data after reading from the XML document.
Steps
Open and run the Visual Basic .NET Chapter 12 solution. From the main Web page, click on the
hyperlink with the caption How-To 12.5: Working with Datasets and XML. As with How-To 12.1, when the page loads, you can enter a few names. Enter the last and first names, and then click the button labeled Add to DataTable. When you have added a few names, click the button labeled Create XML File. Using Explorer, open the file created in C:\ called test.xml. If you click Read XML File, you will see the same data because it was read from text.xml (see Figure 12.5). 1. Create a Web Form. Then place the Labels, TextBoxes, Buttons, and DataGrid objects as seen in Figure 12.5 on the form with the properties set as in Table 12.9.
Table 12.9. Label, TextBox, and Button Control Property Settings Object Property Setting
Label TextBox Label TextBox Button
Text ID Text ID ID Text
Last Name txtLastName First Name txtFirstName btnAdd Add to DataTable btnCreateXMLFile Create XML File dgDataToWrite btnReadFile
Button
ID Text
DataGrid Button
ID ID
Page 511
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataGrid HyperLink
ID ID NavigateURL
dgResultsFromXML hplReturnToMain wfrmMain.aspx
2.
Add the following line to the code module of the form. Then place it under the line that reads Web Form Designer Generated Code.
3. 4. 5. 6. Dim mdtData As New DataTable() Dim mdsData As New DataSet() Add the code in Listing 12.11 to the Load event of the page. If the data table has not been saved to the Session object, then it is created from scratch by first creating the data columns and then adding them to the data table. The DataTable object is then saved to the Session object with the name MyDataTable. A DataSet object is also created because some of the XML methods must be used from the DataSet object, rather than at the DataTable level. If the Session objects entry already exists, it is assigned back to the module variable mdtData and mdsData. Last, the data table is bound to the DataGrid object by calling the BindTheGrid routine, which is described in the next step. Listing 12.11 wfrmHowTo12_5.aspx.vb: Creating a DataTable Object from Scratch
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here If (Session("MyDataTable") Is Nothing) Then Dim dcFirstName As New DataColumn() dcFirstName.ColumnName = "FirstName" dcFirstName.Caption = "First Name" mdtData.Columns.Add(dcFirstName) Dim dcLastName As New DataColumn() dcLastName.ColumnName = "LastName" dcLastName.Caption = "Last Name" mdtData.Columns.Add(dcLastName) mdsData.Tables.Add(mdtData) Session("MyDataTable") = mdtData Session("MyDataSet") = mdsData Else mdtData = CType(Session("MyDataTable"), DataTable) End If
Page 512
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BindTheGrid() End Sub 7. Create the routine BindTheGrid, shown in Listing 12.12, in the code module for the page. Listing 12.12 wfrmHowTo12_5.aspx.vb: Binding the Data Table to the Data Grid
Sub BindTheGrid() dgDataToWrite.DataSource = mdtData dgDataToWrite.DataBind() End Sub 8. Add the code in Listing 12.13 to the Click event of the btnAdd button. This routine starts off by calling the NewRow method off the mdtData data table, thus creating a new DataRow object. The two columns in drNew are replaced with the values in txtLastName and txtFirstName. The new row is added to the data table, and the text boxes are cleared. Last, mdtData is rebound to the data grid by calling BindTheGrid. Listing 12.13 wfrmHowTo12_5.aspx.vb: Adding Data to the Data Table and Then Rebinding the Data Grid
Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click Dim drNew As DataRow drNew = mdtData.NewRow() drNew.Item("LastName") = Me.txtLastName.Text drNew.Item("FirstName") = Me.txtFirstName.Text mdtData.Rows.Add(drNew) Me.txtLastName.Text = "" Me.txtFirstName.Text = "" BindTheGrid() End Sub 9. Add the code in Listing 12.14 to the event of the btnCreateXMLFile button. After loading the dataset from the Session object, the WriteXML method is invoked to save the data into an XML document. Listing 12.14 wfrmHowTo12_5.aspx.vb: Creating the XML Document from the Dataset
Private Sub btnCreateXMLFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCreateXMLFile.Click
Page 513
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
mdsData = CType(Session("MyDataset"), DataSet) mdsData.WriteXml("c:\Test.xml") End Sub 10. Add the code in Listing 12.14 to the Click event of the btnReadFile button. Here, the code reads the XML document by using the ReadXML method off the dsXMLData DataSet object and then binds it to a DataGrid object. Listing 12.15 wfrmHowTo12_5.aspx.vb: Reading the XML Document Back into the Dataset
Private Sub btnReadFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnReadFile.Click Dim dsXMLData As DataSet = New DataSet() dsXMLData.ReadXml("c:\Test.xml") Me.dgResultsFromXML.DataSource = dsXMLData Me.dgResultsFromXML.DataBind() End Sub Figure 12.5. This XML document was created using XMLTextWriter.
Comments
As you can see, for both reading and writing XML document from and to datasets, Microsoft has given us some easy commands to accomplish the task. However, remember that you do have the control over the format of the XML document that you have using the other methods, such as using the DOM.
[ Team LiB ]
Page 514
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Chapter 13. Creating XML Web Services
In this chapter you will
Overview of the XML Web Services infrastructure Get started with XML Web Services Create a simple XML Web Service using parameters Consume XML Web Services Pass a dataset back from an XML Web Service
Methods and other program logic available to applications both on the Web or the desktop are callled XML Web Servers or simply Web Servers. To use the service, or communicate, the consumer will use XML Messaging and HTTP. The same is true when the Web Service is communicating back to the consumer. One of the great things about using XML Web Services is that as long as the consumer can create and consume messages defined for the Web Service, it doesn't matter what the consumer is written in, or even what the platform is. The term used for this is loosely coupled, or in other words, nonproprietary (see Figure 13.1.) Figure 13.1. Notice that no specific languages or platforms are named in this graphic, except to point out ASP.NET, of course.
You also can use XML Web Services either internally or externally to an organization, as long as you
Page 515
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
can get to the network or Internet.
[ Team LiB ]
Page 516
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Overview of the XML Web Services Infrastructure
The infrastructure of Web Services has four main areas:
XML Web Services Directories. Central location to locate XML Web Services that outside organizations create. The UDDI registry is an example of one of these directories. Your Web Service client might not even need to use these if you know the address of the Web Service you are accessing.
XML Web Service Discovery. Discovering documents that describe a particular XML Web Service using the Web Services Description Language (WSDL). The DISCO specification defines an algorithm for locating service descriptions. Again, if you know the location of the service description, you can avoid this process.
XML Web Service Description. Defines what types of methods the XML Web Service uses. Tells clients how to interact with an XML Web Service so that they know how to use it.
XML Web Service Wire Formats. To be able to communicate with all platforms and languages, XML Web Services use open wire formats. These are protocols that any system that is capable of supporting the most common Web standards can understand. SOAP is the main protocol used.
Figure 13.2. Don't panic these steps are performed for you in some cases after you set up the Web reference.
You can find all of the examples in this chapter in the Solution called Visual Basic .NET on the Web site. Note
Chapter 13
You will find the Web Service solution in a separate location called SecurityWebServices on the Web site. The Chapter 13 solution will contain the sample forms that are created to call methods from the Web Service.
Page 517
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
[ Team LiB ]
Page 518
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 13.1 Get Started with XML Web Services
I have heard some great things about XML Web Services, but I don't know how to get started. What do I do to get started working with XML Web Services?
Technique
The best way to get started with XML Web Services is to simply create your own XML Web Service and start playing with it. Visual Studio .NET makes it extremely easy to do just that. To achieve this task, you will be creating your first Web Service, which, of course, will be Hello World. Now, before you start groaning, this example will show you the basics of creating a Web Service without a lot of other fluff that gets in the way and confuses things.
Creating a Web Service
The way you start to create a Web Service is to choose ASP.NET Web Service for a new project. When you have done this, VS will create the Web Service project, and you will be brought to what looks like a blank Web Form, as displayed in Figure 13.3. Figure 13.3. Here is a newly created Web Service project.
Note Remember: Web Services can be created in various ways. Because you are creating this one using Visual Studio .NET, you will be using ASP.NET to create it.
For the most part, you will be using Web Services to provide central processes or functionality that
Page 519
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
you want to be consistent regardless of where you consume it from. This means that you will not be creating a user interface that users will see; you are basically creating a class-like interface that will provide methods (hence the use of Service1.asmx instead of *.aspx). You will use *.asmx as an entry point for your Web Service. To really get going with working with your first Web Service, you will click on the View Code icon in the Solution Explorer. When you do so, you will see the first method to create. That's right it is Hello World. The first thing you should do now is uncomment the lines of code that read as follows:
' Public Function HelloWorld() As String ' HelloWorld = "Hello World" 'End Function
The screen should look like Figure 13.4. Figure 13.4. Your first Web Service method.
That's it! You have created your first Web Service method. Now it's time to test it.
Testing the Web Service
After you have created your Web Service, click the Start toolbar button. Visual Studio will then compile and build your Web Service. After which, Visual Studio will create a test page for your Web Service, as shown in Figure 13.5. Figure 13.5. This page that Visual Studio created gives you instructions on how to specify a namespace for your Web Service within the calling application.
Page 520
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Note As mentioned on this Web page, when you are developing your Web Service, Visual Basic uses a temporary namespace called http://tempuri.org/. When you are going to make the Web service public, you will want to create different namespace for the Web Service. I would recommend just using the examples they give on your test Web page.
One of the items you see on this test Web page is the list of operations, otherwise known as methods you created. If you click on the Hello World method, you will see another page that you will use to invoke the actual method (see Figure 13.6.) Figure 13.6. This page allows you to test your Hello World method.
Page 521
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You also will see example code for calling the method using SOAP, HTTP GET, and HTTP POST. However, you will just be using this test page to check out the Hello World example, and you will be learning how to call methods from Visual Basic behind Web Forms in How-To 3.3. If you click on the Invoke button, you will see the following:
Hello World
This is the value that the method you created returns. That's it! That's all there is to the test page. Note Before telling yourself that this test page doesn't do much, remember that if you did have a problem with the code in your Web Service, the problem would have shown up here. This quick testing saves a lot of hassle of writing code that actually calls the methods and then making sure the calling code wasn't causing errors. Using the test page allows you to debug your Web Service before you integrate it. Okay, I am now off my SOAPbox. Pun intended.
Looking at the Description of the Web Service
Visual Studio .NET saves you from a lot of work. If you click the Back button and go to the main test page, you will see a link to Description in the top sentence. If you click on this link, you will see the SOAP code shown in Listing 13.1. Listing 13.1 http://localhost/WebService1/Service1.asmx?WSDL: Soap Definition for Your First Web Service
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The really nice thing to remember is that Visual Studio .NET generates all this code for you, so you don't have to.
Steps
For this How-To, you will create the example Web Service that was discussed in the "Technique" section. 1. 2. Open up Visual Studio .NET to the Start Page, with no projects or solutions opened. From the File menu, choose New, Project. You will see the New Project dialog box. Highlight
Page 524
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
the ASP.NET Web Service template (see Figure 13.7.) Then click OK. You will then be given a blank *.asmx file. Figure 13.7. You will be using the ASP.NET Web Service template for this project.
3.
Click on the in the Solution Explorer. You will see the commented out method called Hello World. Uncomment the lines of code that read as follows:
4. 5. 6. 7. 8. ' Public Function HelloWorld() As String ' HelloWorld = "Hello World" 'End Function Click the Start button. You are shown the test page as described in the "Technique" ssection.
Comments
Although this is definitely the simplest example to be given while creating a Web Service, if you look at the description of even this simple Web Service and you see all the SOAP that is generated, you can appreciate all the work Microsoft has done to make the generation of Web Services using Visual Studio as painless as possible.
[ Team LiB ]
Page 525
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 13.2 Create a Simple XML Web Service Using Parameters
I have seen how to create a Web Service using the sample that Microsoft provides. This was instructive but not very useful. How do I create a Web Service that uses parameters?
Technique
For this How-To, you are going to create the start of a security Web Service. This security Web Service is going to take in two parameters: Login Name and Password. It will then check against a table that you will create of names, passwords, and security levels. The method you will create first will then pass back True or False if the name and password are found.
Looking at the Security Table
The security table is included in the Web Service's Web folder. It is called WebServiceSecurity.MDB and is, in fact, a jet database. You can see the table created,
tblUsers, in Figure 13.8.
Figure 13.8. Using the tblUsers, you can look up usernames and passwords
The method created for this first real example will take in the username and password and then look up the username. If the username is found, the method will then compare the password. If the password matches, then True will be returned from the method. Otherwise, False will be returned.
Passing Parameters
You will pass parameters to Web Service methods just as you would to any other methods or functions, as shown in the function header for the Web Service method created in this How-To:
Page 526
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Public Function TestUser(ByVal strUserID As String, ByVal strPassword As String) As Boolean
The return value is also assigned to the name of the function.
Specifying Descriptions for the Web Service and Methods
You can help developers who use your Web Service by adding descriptions to the Web Service and each of the methods you create. This cuts down on the number of support requests you get, and is a good habit to get into. For the Web Service, you will place it in the WebService header, where you will want to specify your own namespace as well:
_ Public Class SecurityServices_
This causes the description specified to be displayed as the first line on the main test page. For the method, you will include the description in the Web Method header:
Public Function TestUserPassword(ByVal strUserID As String, _ ByVal strPassWord As String) As Boolean
You can see what the lines of code look like in the designer in Figure 13.9. Figure 13.9. Adding descriptions to the Web Service.
Now it's time to put it all together.
Steps
Page 527
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Open and run the SecurityWebService solution. From the main test page, click on the link for the method TestUserPassword. You are presented with a page to input the user ID and password (see Figure 13.10.) If you type FSBarker for the strUserID and test for the strPassword, the value True is returned; otherwise, False is returned. 1. 2. Create an ASP.NET Web service project, calling it SecurityWebService. Highlight the default .asmx file created in the Solution Explorer, renaming it to SecurityServices.asmx. 3. Click on the View Code button in the Solution Explorer. Change the WebService at the top of the code to read as follows: 4. 5. 6. 7. 8. _ Public Class SecurityServices Add the code in Listing 13.2 to the code of the Web Service. (Double-click on the Web Service to bring up the code.) You could replace the commented out lines that display for the Hello World Web method. This code starts off by specifying the description for the Web Method and then declaring the function header for the method called TestUserPassword. The parameters strUserID and strPassword are passed, and a Boolean type value is returned. The rest of this routine should look somewhat familiar because a DataAdapter object is created, and a DataTable object is filled, based on the username that was passed in. If a record is not found for the user, then False is passed back. If a record is found and the password matches, then True is passed back. If the password for the user does not match, then False is passed back. Listing 13.2 SecurityServices.asmx.vb: Web Method to Validate Username and Password
Public Function TestUserPassword(ByVal strUserID As String, _ ByVal strPassword As String) As Boolean Dim ocnn As New _ OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=E:\InetPub\wwwroot\SecurityWebService\" & _ "WebServiceSecurity.MDB") Dim odaUsers As New _ OleDb.OleDbDataAdapter("Select * from tblUsers " & _ "Where UserID = '" &strUserID & "'", ocnn) Dim dtUsers As New DataTable() odaUsers.Fill(dtUsers) If dtUsers.Rows.Count = 0 Then
Page 528
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
TestUserPassword = False ElseIf dtUsers.Rows(0).Item("Password") = strPassword Then TestUserPassword = True Else TestUserPassword = False End If End Function Note
If you have a problem with sharing rights on the database, you might want to include "Mode=Share Deny None;" in your connection string.
9.
Press the Start button on the toolbar to test the service. Figure 13.10. Testing a simple security Web Service.
Comments
When you are working in code for your Web Service, you can perform the majority of tasks, including ADO.NET, that you can in ASP.NET, except for those depending on a user interface (UI). You have now seen how to specify parameters. Now check out the next How-To to see how to consume, or use, your Web Service in an application.
[ Team LiB ]
Page 529
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 13.3 Consume XML Web Services
I have created this Web Service that takes the username and password and returns True or False based on whether the username and password check out. I have even tested the Web Service to make sure it works correctly. How do I use, or consume, this Web Service in another application?
Technique
To use a Web Service, you need to create a reference to it.
Setting Up the Web Reference to the Web Service
To set up a Web reference, you choose Add Web Reference from the Project menu. You are then presented with the Add Web Reference dialog box, which allows you to browse for Web Services using the Universal Description Discovery Integration (UDDI) directories, as described in the beginning of the chapter. However, you will be able to browse to the Web Service you created and supply the name of the full URL using localhost to the name of the .asmx file you created, in this case:
http://localhost/securitywebservice/SecurityServices.asmx
After you have specified this, you will see the methods appear for your Web Service (see Figure 13.11.) Figure 13.11. You can test the Web Service right in this dialog box.
Note You can see two methods for this Web Service: TestUserPassword and GetUserInfo. The second method is discussed in How-To 13.4.
Page 530
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
After you have clicked Add Reference to accept the new reference, you can use the methods in your application. You can double-check that the reference is there by looking for it under the Web Reference node that appears in the Solution Explorer (see Figure 13.12.) Figure 13.12. You can see the reference created in the Solution Explorer.
Calling Web Service Methods
After you have created the reference to the Web Service, you will create a reference within your application, much like you would to other object models. Following is a snippet of code that performs this very task:
Dim wsSec As localhost.SecurityServices wsSec = New localhost.SecurityServices() If wsSec.TestUserPassword(Me.txtUser.Text, Me.txtPassword.Text) Then
As you can see, the method TestUserPassword is called just as another other method or function is called.
Steps
To preview this How-To, open the solution called Visual Basic .NET chapter folder. Note Chapter 13, located in the
Page 531
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
You will probably have to re-establish the Web reference for the Web Service that is used for this example. Locate where you have installed SecurityWebServices and set the reference.
When you run the project, the first form that comes up is the main switchboard with each of the How-Tos listed for this chapter. Click on How-To 13.3. The form for How-To 13.3 opens. If you type FSBarker for the User and Test for the Password, you get a message box telling you that you can continue into the application (see Figure 13.13). 1. Create a new Visual Studio .NET project using the Windows Application project template. Create a Windows Form, and place the controls shown in Table 13.1 in the order displayed in Figure 13.13.
Table 13.1. Label, TextBox, and Command Button Control Property Settings Object Property Setting
Label TextBox Label TextBox Button
2.
Text Name Text Name Name
User txtUser Password txtPassword btnLogin
As described in the "Technique" section, set a reference to the Web Service you created in the previous How-To. Remember to point to the *.asmx file created in the Web Service. Choose Add Web Reference from the Project menu.
3.
Add the code listed in Listing 13.3 to the Click event of btnLogin by double-clicking on the button. This routine instantiates an instance of the Web Service. Then, using the wsSec object, the routine calls the TestUserPassword method. This method is passed the username and password that were entered. Listing 13.3 frmHowTo13_3.vb: Web Method to Validate Username and Password
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click Dim wsSec As localhost.SecurityServices wsSec = New localhost.SecurityServices()
Page 532
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
If wsSec.TestUserPassword(Me.txtUser.Text, Me.txtPassword.Text) Then MessageBox.Show("You may go into the applcation.") Else MessageBox.Show("You may not go into the application.") End If End Sub Figure 13.13. This login form takes advantage of a Web Service for authentication.
Comment
Note that passing parameters and using the return value is just like using methods from other objects or even functions from your own applications.
[ Team LiB ]
Page 533
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] 13.4 Pass a Dataset Back from an XML Web Service
I want to be able to get more data than just a single value. How do I retrieve a whole dataset from a Web Service?
Technique
When you need to pass back a record or multiple records from a Web Service, you have to pass it back as a DataSet object, rather than a DataTable object. For this How-To, you will pass back the record of the user who is requested. Before returning the record, however, the code removes the Password column. You don't particularly want that information going out over the Net(see Listing 13.4). Listing 13.4 SecurityServices.asmx.vb: Passing Back a DataSet Object
Public Function GetUserInfo(ByVal strUserID As String) As DataSet Dim ocnn As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=E:\InetPub\wwwroot\SecurityWebService\WebServiceSecurity.MDB") Dim odaUsers As New _ OleDb.OleDbDataAdapter("Select * from tblUsers Where UserID = '" & strUserID & "'", ocnn) Dim dsUsers As New DataSet() odaUsers.Fill(dsUsers) '-- remove the password column dsUsers.Tables(0).Columns.Remove("Password") Return dsUsers End Function
Note Although you could limit the SELECT string to only return the necessary columns, and not have to delete the Password column, there are two reasons for coding it the way it was done. 1. It shows how to delete columns from a data table. 2. If the goal is to include all the columns in the table and accept the Password column, then when other columns are added, you will not have to touch the code because the * is being used.
Tip When referring to tables on the receiving end, as displayed in step 2 of this How-To, you have to refer to tables in the dataset by their ordinal values. Therefore, some information in the description of the Web Service method about the dataset might be warranted.
Page 534
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Steps
To preview this How-To, open the solution called Visual Basic .NET Chapter 13, found in this chapter's folder. On the main form, click on the button labeled How-To 13.4. The form for How-To 13.4 then opens. If you type FSBarker for the User and Test for the Password, you can see the user's information listed in the DataGrid object (see Figure 13.14). Otherwise, a message box appears saying that you cannot see the data. 1. Open the SecurityWebServices Web Service project you created in How-To 13.2. Add the code from Listing 13.4 in the "Technique" section to create the GetUserInfo method. Test the new Web method. When you do so, you will see some XML, as shown here in Listing 13.5. Listing 13.5 Dataset Sent Back as XML
- - - - - - - - - - - FSBarker F. Scott Barker 3
Page 535
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
2. Open the Windows Project where you created the Login windows Form. Create a new Windows Form and place the controls shown in Table 13.2 in the order displayed in Figure 13.14.
Table 13.2. Label, TextBox, DataGrid, and Command Button Control Property Settings Object Property Setting
Label TextBox Label TextBox DataGrid Button
3.
Text Name Text Name Name Name
User txtUser Password txtPassword dgUserInfo btnLogin
Add the code in Listing 13.6 to the Click event of btnLogin. This code once again checks the username and password by calling the TestUserMethod of the Web Service. If the username and password check out, then the GetUserInfo method is called, passing the username once again. The first table from the returned dataset is assigned to the DataSource property of dgUsers. Listing 13.6 frmHowTo13_4.vb: Retrieving a Dataset from a Web Service
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click Dim wsSec As localhost.SecurityServices wsSec = New localhost.SecurityServices() If wsSec.TestUserPassword(Me.txtUser.Text, Me.txtPassword.Text) Then dgUserInfo.DataSource = wsSec.GetUserInfo(Me.txtUser.Text).Tables(0) Else MessageBox.Show("No information may be presented.") End If End Sub Figure 13.14. The information in the data grid was retrieved from a Web Service.
Page 536
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Comments
You can use Web Services in literally thousands of ways. This chapter just covers a couple, but it should be enough to start you down the path of using them productively.
[ Team LiB ]
Page 537
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Appendix A. Desktop Development With ADO
You will learn about the following in this appendix:
When to use ADO (local database/single-tier applications) Looking at the ADO Object Models Using the Connection object Working with the ADO Recordset object Executing a SQL Server stored procedure by using ActiveX Data Objects Executing batch updates with ADO and SQL Server Creating SQL Server objects with ActiveX Data Objects Perform a transaction using ActiveX Data Objects
Although it's true that in the .NET environment, you will want to use ADO.NET for the majority of your development, developers have invested a lot of time and money into ActiveX Data Objects (ADO), and you might want to use it for desktop applications.
[ Team LiB ]
Page 538
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] When to Use ADO (Local Database/Single Tier Applications)
ADO was Microsoft's last data-access method, and it is now the standard for most Office, Web, and Visual Basic environments prior to .NET. The following products ship ADO in the box:
Microsoft Office 200x Visual Studio 6.0 (including all the languages in the box) SQL Server 7.0, 2000
Data Access Objects (DAO), the standard prior to even ADO, was used throughout Office and Visual Basic, but it wasn't designed to be used with Web environments such as Visual InterDev and other data servers. Currently, no plan is underway to update DAO beyond DAO 3.6, which includes support for Unicode and some bug fixes, but doesn't have any other new features included beyond 3.5.
[ Team LiB ]
Page 539
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Looking At the ADO Object Models
That's right, object models, plural. Unlike DAO, which consists of one object model, ADO has several separate object models. Note With ADO.NET, you use Namespaces and classes rather than references and object models. Although this takes some getting used to, it isn't too bad after a while.
ADO's object models work together to give you the objects and collections that are necessary to work with your data. A couple of the object models consist of the following:
ActiveX Data Objects 2.7 (ADODB) allows you to create and work with recordsets, as well as perform error handling.
ADO Extensions 2.7 for DDL and Security (ADOX) is the data definition language, allowing you to work with and modify the database schema. Security objects are also included in this object model.
Although these are separate object models and will be explained as such, you will also use them cohesively. For instance, to modify the table's structure, you need to get to the Tables collection located off the Catalog object in the ADOX library; however, this Catalog will have its
ActiveConnection property set to the Connection object (ADODB). Take a look at what makes
up the individual object models.
The ActiveX Data Objects 2.7 (ADODB) Object Model
The ActiveX Data Objects object model (see Figure A.1) consists of the following:
Connection object. Equivalent to the Database object in DAO, this is where most of your
work with ADO begins. All the objects and collections that are mentioned after this come from the Connection object.
Errors collection/Error object. Identical to the DAO errors collection and error object, this allows developers to manage error handling.
Command object. This allows you to run a query against a database and return records in a Recordset object, to manipulate a database's structure, and to execute a bulk operation. A collection of parameters is used with the Command object. Recordset object. Similar to the DAO Recordset object, you can open the Recordset objects as read-only or dynamic. Each Recordset object also has a Fields collection. Stream object. This object allows you to read in special tree-structured hierarchies, such as
e-mail messages or file systems. You can even point the object to an URL, provided the system has set it up in a consistent manner. This is another way that ADO allows developers to read outside data, such as from other applications or over the Internet. You
Page 540
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
could not do this easily with DAO. Figure A.1. The object model for ActiveX Data Objects 2.7.
Most of the work is done in the ADODB module when you use ADO. Whenever you use recordsets, this is also the object model to use.
[ Team LiB ]
Page 541
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Referencing the Type Libraries
Before seeing how to use these collections and objects, you need to know how to reference the object model libraries for use. The object models are found in type libraries in the file system. A type library contains the information about the object models such as the collections, properties, and methods. Referencing the type libraries isn't difficult, but it is still very important. Because Visual Basic .NET uses ADO.NET by default, you will have to reference all the object models you are going to need. To reference the object models, choose Add Reference from Visual Studio .NET's Project menu. After you're in the Add Reference dialog box, click on the COM tab. You then have to find the type libraries for the object models and select them. The type library name that you will be using is as follows: Microsoft ActiveX Data Objects 2.7 Library. This is also referred to as the ADODB object model. You can see this library, as well as other Microsoft ActiveX Data Objects Libraries, in Figure A.2. Figure A.2. Registering the COM type libraries.
Tip You can use both ADO libraries and ADO.NET classes in the same application without worrying about the order of libraries in the references. This is great when you're converting applications from ADO to ADO.NET. To use all libraries and not worry about the order of reference, you must prefix your objects with the library with which they come. Here are some examples, with the specific library types:
Dim odaTest as OLEDB.OLEDBDataAdapter Dim rstTestADO as ADODB.Recordset Dim catTest as ADOX.Catalog
Page 542
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Although not all objects are shared between the libraries, it's a good idea to specify the library while you're getting used to the objects.
After the library has been selected, you can see the ADODB reference entry in the Solution Explorer under references.
[ Team LiB ]
Page 543
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Using the Connection Object
As with ADO.NET, you will be using the Connection object to set up a connection to the database of your choice. As you get started looking at the different examples, take a look at the main form that will be used to launch each of them, shown in Figure A.3. Figure A.3. This form, called frmMain, is the Main form that is used for the examples in this Appendix.
The button that is used for this example is called btnOpenConn, and the following is the code used for the Click event, shown here in Listing A.1. Listing A.1 frmMain.vb: Code for Calling the Routine to Open and Display the ADO Connection
Private Sub btnOpenConn_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOpenConn.Click OpenAndDisplayADOConnection(Me.txtCurrentResults) End Sub
Each of the buttons calls examples, passing the text box called txtCurrentResults. This text box is located at the bottom of the form. For clarity, the examples have been grouped in modules by section. In this case, the first example routine, called OpenAndDisplayADOConnection, can be found in basConnectionExamples.vb. The code for this routine is shown in Listing A.2. Listing A.2 basConnectionExamples.vb: Code for Opening and Displaying the ADO Connection
Sub OpenAndDisplayADOConnection(ByVal txtResults As TextBox)
Page 544
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Dim cnnNet As New ADODB.Connection() Dim strConnect As String = _ "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & "Persist Security Info=False;Initial Catalog=Northwind;Data Source=(local)" cnnNet.Open(strConnect) txtResults.Text = "New connection string : " & _ vbCrLf & vbCrLf & cnnNet.ConnectionString cnnNet.Close() End Sub
As you can see from this example, using the ADO Connection object is virtually the same as ADO.NET. You can see this example being executed in Figure A.4. Figure A.4. The text displayed here is the connection string that was set.
Listing A.3 provides two other examples of using the connection object, also found in basConnectionExamples.vb. The first is code to open a connection to a Jet database by using a workgroup file, username, and password. The second is to open a Jet version of the Northwind database. Listing A.3 basConnectionExamples.vb: Two Examples of Opening Jet Databases
Sub DisplayProviderAndSecuredAccessDB(ByVal txtResults As TextBox) Dim cnnNet As New ADODB.Connection() cnnNet.Provider = "Microsoft.Jet.OLEDB.4.0" cnnNet.Properties("Jet OLEDB:System database").Value = _
Page 545
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html "c:\Books\VBNETHowTo\Examples\AppA\MySystem.mdw" cnnNet.Open("Data Source=c:\Books\VBNETHowTo\Examples\AppA\MyMDB.mdb;" & "User Id=Admin;Password=MyPW") txtResults.Text = cnnNet.ConnectionString End Sub Sub OpenNorthwindADOConnection(ByRef cnnCurr As ADODB.Connection) Dim strConnect As String = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & "Persist Security Info=False;Initial Catalog=Northwind;Data Source=(local)" Try cnnCurr.Open(strConnect) Catch expADO As Exception MessageBox.Show("The following error occurred: " & expADO.Message) End Try End Sub
In the last routine, you can also see how to use the Try…Catch…End Try block to trap any exceptions that might occur. Next you will see how to use the Connection object with the Recordset object in VB .NET.
[ Team LiB ]
Page 546
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Working with the ADO Recordset Object
The central object in the ADODB object model is the Recordset object. You will be using this object when you want to manipulate records one at a time or bring back a set of records with which to work. With ADO, when you declare the type of variable you are going to use, you can instantiate it at the same time with the New keyword.
Displaying Records by Using GetString
For debugging purposes, you can also dump the whole recordset into a string variable for display. Listing A.4 shows you how to do this. Listing A.4 basRecordsetExamples.vb: Opening and Retrieving a Recordset for Display
Sub OpenRecordsetWithGetStringDisplayExample(ByVal txtResults As TextBox) Dim cnn As New ADODB.Connection() Dim rstCurr As New ADODB.Recordset() OpenNorthwindADOConnection(cnn) rstCurr.Open("Select * from Orders where OrderDate = '06/12/97'", cnn, ADODB.CursorTypeEnum.adOpenForwardOnly) txtResults.Text = rstCurr.GetString rstCurr.Close() End Sub
Using the OpenNorthwindADOConnection subroutine listing in Listing A.3, a connection object is referenced, and that is passed to the Open method of a Recordset object. Tip Notice that the cursor type returned will be
ADODB.CursorTypeEnum.adOpenForwardOnly. Because all that is
happening is the data being dumped to a string, using this cursor type makes sense. This will give you the best performance. Some other choices include adOpenDynamic, adOpenKeyset, adOpenStatic, and
adOpenUnspecified.
You can run this example by clicking on the button labeled Open a Recordset with GetString Display on the main form. Figure A.5 shows what you will see. Figure A.5. The GetString method is handy for checking out data.
Page 547
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Editing and Updating Records
You can use several methods to perform editing and updating of records in code. Unlike the last section in which you could open the recordset as a Forward Only type cursor, you will want to open it as a Dynamic type cursor. You can see this in Listing A.5. Listing A.5 basRecordsetExamples.vb: Opening and Retrieving a Recordset for Display
Sub OpenRecordsetWithEditingExample(ByVal txtResults As TextBox) Dim Dim Dim Dim cnn As New rstCurr As fldCurr As strTemp As ADODB.Connection() New ADODB.Recordset() ADODB.Field String
OpenNorthwindADOConnection(cnn)
rstCurr.Open("Select * from Orders where OrderDate = '06/12/97'", cnn, ADODB.CursorTypeEnum.adOpenDynamic, _ ADODB.LockTypeEnum.adLockOptimistic) With rstCurr Do Until .EOF strTemp = strTemp & " Old Field Value: " & _ .Fields("ShippedDate").Value '-- Updating the release date .Fields("ShippedDate").Value = DateAdd(DateInterval.Day, 5, _ .Fields("ShippedDate").Value)
Page 548
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html .Update() strTemp = strTemp & " New Field Value: " & _ .Fields("ShippedDate").Value & vbCrLf .MoveNext() Loop End With txtResults.Text = strTemp rstCurr.Close() End Sub
You can see that the Update method is used after assigning the value that you want to the field you specify. You could have specified other fields to be updated as well. Note Notice that when updating individual fields in the recordset, the Value property is specified to be updated. You didn't have to do this in VB 6.0 or VBA, but .NET doesn't allow for default properties, which the Value property is.
You don't have to explicitly use an Edit method; in fact, you won't find one like you could in previous editions. To add a new record, you must use the AddNew method before updating field values. To delete a record, you use the Delete method. One last thing to discuss about recordsets is how to persist, or save a recordset to disk.
Persisting a Recordset
This example will open up two recordsets: one from the Orders table, and one from a file created from the Orders table called OrdersForDate.rst. The code, shown in Listing A.6, opens the Orders table for a specific date and uses the GetString method to stash the contents to the results text box. The routine then saves that recordset using the Save method, and passes the adPersistADTG format enumerator. You could save the recordset as XML by using adPersistXML. The code opens the file into a recordset and prints it by saving it to the results TextBox control. Listing A.6 basRecordsetExamples.vb: Persisting a Recordset to Disk
Sub PersistingARecordset(ByVal txtResults As TextBox) Dim cnn As New ADODB.Connection() Dim rstOrig As New ADODB.Recordset() Dim rstPersist As New ADODB.Recordset() Const adCmdFile As Long = 256 OpenNorthwindADOConnection(cnn)
Page 549
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html '-disk. rstOrig.Open("Select * from Orders where OrderDate = '06/12/97'", cnn, ADODB.CursorTypeEnum.adOpenStatic) txtResults.Text = "Original Records : " & vbCrLf & rstOrig.GetString '-- Delete any existing old copies. ' If you don't, you will get an error. On Error Resume Next Kill("OrdersForDate.rst") '-- Create the persistent recordset in the applications directory On Error GoTo 0 rstOrig.Save("OrdersForDate.rst", ADODB.PersistFormatEnum.adPersistADTG) cnn = Nothing rstOrig = Nothing ' Open the persisted recordset rstPersist.Open("OrdersForDate.rst", Options:=adCmdFile) txtResults.Text = txtResults.Text & vbCrLf & vbCrLf & _ "Persisted File : " & vbCrLf & rstPersist.GetString rstPersist.Close() End Sub
That's all there is to it. You will find that you can do most other things with recordsets using VB .NET that you have been able to do in other languages. Now take a look at another common task that you must do if you are using ADO with Visual Basic .NET: calling stored procedures.
Open forward only and readonly since we are just saving it to
[ Team LiB ]
Page 550
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Executing a SQL Server Stored Procedure By Using ActiveX Data Objects
If you are doing an ADO development with client server for backends, then you probably call stored procedures. In doing so, you will use the ADO Command object, as well as the Parameter object if you are passing parameters. You will create a Command object and supply the command text, which in this case will be the name of the stored procedure, called CustOrdersHist. You can see the T-SQL for CustOrderHist in Listing A.7. This stored procedure returns product names and the total quantity purchased of those products for a given customer. Listing A.7 Northwind SQL Server Database: T-SQL for the Stored Procedure Called
CustOrdersHist ALTER PROCEDURE CustOrderHist @CustomerID nchar(5) AS SELECT ProductName, Total=SUM(Quantity) FROM Products P, [Order Details] OD, Orders O, Customers C WHERE C.CustomerID = @CustomerID AND C.CustomerID = O.CustomerID AND O.OrderID = OD.OrderID AND _ OD.ProductID = P.ProductID GROUP BY ProductName
You will then specify the type of Command object you are creating of ADODB.CommandTypeEnum.adCmdStoredProc. in this case by using the type
The next step is to create a parameter that the Command object will use. This parameter will match the one specified in CustOrdersHist, called CustomerID. You can see the actual code for this routine, called UseAStoredProcedureWithAParameter, in Listing A.8. Listing A.8 basCommandExamples.vb: Calling a Stored Procedure By Using Parameters
Sub UseAStoredProcedureWithAParameter(ByVal txtResults As TextBox) Dim Dim Dim Dim Try cmd.CommandText = "CustOrderHist" cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc prm = cmd.CreateParameter("CustomerID", ADODB.DataTypeEnum.adChar, ADODB.ParameterDirectionEnum.adParamInput, 5) cmd.Parameters.Append(prm) prm.Value = "CHOPS" OpenNorthwindADOConnection(cnn) cmd.ActiveConnection = cnn rstCurr.Open(cmd) txtResults.Text = rstCurr.GetString cnn As New ADODB.Connection() rstCurr As New ADODB.Recordset() cmd As New ADODB.Command() prm As ADODB.Parameter
Page 551
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html Catch excp As Exception MessageBox.Show(excp.Message) End Try End Sub
The last thing that this routine does is open a recordset based on the Command object. This is to the use just those records that are needed. In this case, the GetString method is used to assign it to the results text box. If you are using a bulk query, shown in the next section, you would use the Execute method. To see the routine in A.8 executed, click on the button with the caption Stored Procedure with Parameter, located on the frmMain form for this Appendix project.
[ Team LiB ]
Page 552
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Executing Batch Updates with ADO and SQL Server
The biggest difference between this section and the previous one is the fact that in the last section, a recordset being populated using a Command object. With the Command object, no data was affected. That is one type of use for a Command object. What if you want to perform bulk tasks against a recordset? This is the major use for using the Command object because you don't necessarily need it for populating a recordset. The Parameter object is also not used. It was not necessary for the example, although you would want to use it if criteria were being implemented. To learn how to perform a bulk operation using ADO in Visual Basic .NET, see this simple Update SQL statement, shown here:
Update Orders Set ShippedDate = DeliveryDate+1
This statement adds a day to the date in the ShippedDate column for all the records in the Orders table. This statement is being assigned to the CommandText property of the Command object instead of to the name of a stored procedure. Another important task is setting the CommandType property to be ADODB.CommandTypeEnum.adCmdText. This tells ADO that you are performing a bulk operation. Last, the Execute method is called from the Command object. This routine, called
ExecuteABatchCommand, can be seen in Listing A.9.
Listing A.9 basCommandExamples.vb: Creating and Executing a Bulk Query
Sub ExecuteABatchCommand(ByVal txtResults As TextBox) Dim Dim Dim Dim Dim cnn As cmd As prm As rstOld rstNew New ADODB.Connection() New ADODB.Command() ADODB.Parameter As New ADODB.Recordset() As New ADODB.Recordset()
'-- In .NET, we can assign values as we declare variables Dim strSQL As String = "Update Orders Set ShippedDate = ShippedDate+1" Dim strDispSQL As String = _ "Select OrderID, ShippedDate From Orders Where OrderID < 10251" '-- Open the connection OpenNorthwindADOConnection(cnn) '-- Open the Orders table and display the ShippedDate as they were. rstOld.Open(strDispSQL, cnn) txtResults.Text = "Old Values: " & vbCrLf & vbCrLf & rstOld.GetString '-- Set up the Command object to use the SQL string. cmd.ActiveConnection = cnn cmd.CommandText = strSQL cmd.CommandType = ADODB.CommandTypeEnum.adCmdText '-- Execute the command cmd.Execute() '-- Reopen the Orders table and redisplay the ShippedDate Field
Page 553
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html rstNew.Open(strDispSQL, cnn) txtResults.Text = txtResults.Text & vbCrLf & vbCrLf & "New Values: " & vbCrLf & vbCrLf & rstNew.GetString End Sub
For this example recordset, objects were used merely to display the before and after data, as seen in Figure A.6. Figure A.6. Although they're not pretty, you can see the values of the OrderID and DeliveryDate before and after the routine has been executed.
You can also use the Insert and Delete statements to perform other bulk operations with the
Command object. One of the last tasks that is useful to perform using ADO with SQL Server is to
create objects such as tables on-the-fly.
[ Team LiB ]
Page 554
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Creating SQL Server Objects with ActiveX Data Objects
It is worthwhile to mention an example of creating a new table object with fields and primary key specified, even though the majority of the work of creating objects using ADO and SQL Server is done in the T-SQL Statement that you create. You will execute this statement using the Command object, as shown in Listing A.10. Listing A.10 basStoredProcedureExamples.vb: Creating SQL Server Objects with ADO and T-SQL
Sub CreatingASQLServerObjectFromADO(ByVal txtResults As TextBox) Dim Dim Dim Dim Dim cnn As cmd As prm As rstOld rstNew New ADODB.Connection() New ADODB.Command() ADODB.Parameter As New ADODB.Recordset() As New ADODB.Recordset()
'-- In .NET, we can assign values as we declare variables. ' This is where the hard work is. Dim strSQL As String = "CREATE TABLE Test (PrimaryIntFld Integer IDENTITY(1,1) PRIMARY KEY, Field2 Text)" '-- Open the connection OpenNorthwindADOConnection(cnn) '-- Set up the Command object to use the SQL string. cmd.ActiveConnection = cnn cmd.CommandText = strSQL cmd.CommandType = ADODB.CommandTypeEnum.adCmdText '-- Execute the command cmd.Execute() End Sub
This routine is a lot like the previous example except for the SQL statement and the fact that results aren't displayed. You can see the results by going to the Visual Studio .NET Server Explorer, zeroing in on the tables for the Northwind database, and opening the new Test table in Design mode, as shown in Figure A.7. Figure A.7. Creating objects such as this table is just a matter of learning the correct SQL syntax.
Page 555
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Note If you already had the tables displayed for Northwind, you might need to right-click on the Tables node and choose Refresh.
[ Team LiB ]
Page 556
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ] Conclusion
Well, there you have it. As you can see, you can use ADO in Visual Basic .NET under the covers in basically the same way that you did in prior versions of VB. Just as a parting word of advice for this Appendix: Convert as much of your code to take advantage of ADO .NET as possible. However, if you have several developers and need to crank out a simple application with Visual Basic .NET in a hurry, ADO is still available.
[ Team LiB ]
Page 557
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F] [G] [H] [I] [J] [K] [L] [M] [N] [O] [P] [Q] [R] [S] [T] [U] [V] [W] [X]
[ Team LiB ]
Page 558
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
"" (double quotation marks) # (number sign) % (percent sign)
& (ampersand)
variables, declaring > (right arrow button) < (left arrow button) *.asmx file extension + (plus sign) - (minus sign) 2nd 2nd
.NET namespaces
XML (Extensible Markup Language) System.XML namespace System.XML.Schema namespace System.XML.Xpath namespace System.XML.XSL namespace 2nd
XML
(Extensible Markup Language) .NET Framework Developer's Guide 2nd
.NET namespaces
bound list boxes, creating 2nd 3rd 4th 5th .vb file extension .xsd file extension ? (question mark)
@ (at symbol)
parameters 2nd [ ] (square brackets) ^ (caret) _ (underscore)
1stBackupDevices list box
populating (code) 2nd 3rd 4th
1stC ustomers
Click event, code
1stDatabases list box
populating (code) 2nd 3rd 4th 5th
1stLookUpTables Items collection
data, adding
1stLookupTables
pointing to items (code) 2nd
1stUnSelected list box reloading
code
1stUnselected list box reloading
code 3621 error
[ Team LiB ]
Page 559
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
abstract classes AcceptChanges method access (Public) modifiers 2nd 2nd
access levels
deny (object permissions) grant (object permissions) revoke (object permissions)
accessing
command buttons on forms CommandText property libraries 2nd 2nd
accounts
database users, creating 2nd 3rd 4th 5th 6th
Windows NT/2000
disabled 2nd
Action menu commands
New Group Properties Action property
actions
execution on forms 2nd
Actions menu commands
New Login ActivateEditing routine creating (code) 2nd
ActiveEditing frmHowTo1_4.vb
SaveRecord routing, calling (code) text boxes, disabling (code) 2nd 2nd
ActiveEditing subroutine
calling (code) 2nd ActiveX Data Objects 2.7 (ADODB) ActiveX Data Objects 2.7 object model (ADODB) 2nd 3rd ActiveX Data Objects. adapters.
[See ADO]2nd [See ADO]
[See also data adapters]2nd [See also data adapters]
Add button
clicking, effects Add Class command (Add menu) Add Members dialog box 2nd
Add menu commands
Add Class Add New Item Add method Add New Item command (Add menu) Add New User dialog box 2nd 3rd 2nd 2nd
Add Reference
command (Project menu) dialog box Add Reference command (Project menu) Add Role Members dialog box Add Table dialog box Add to DataTable button 2nd 3rd 2nd
Page 560
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Add Web Reference command (Project menu)
adding buttons
to DataGrid control 2nd 3rd 4th
data
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th to Items collection data to lookup tables 2nd 2nd
lookup table information methods to interfaces
2nd 3rd 4th
properties to interfaces 2nd records 2nd 3rd 4th 5th 6th 7th 8th 9th 10th buttons canceling in DataGrid object (code) to data tables (code) 2nd
2nd 3rd 4th 5th
rows
in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th AddNew method 2nd
AddObjectForTransfer method
Administrative Tools
groups and users, adding ADO 2nd (ActiveX Data Objects) 2nd ADODB (ActiveX Data Objects 2.7 object model) 2nd 3rd and ADO.NET, comparing 2nd 3rd batch updates, executing Connection object 2nd 3rd 4th 5th
2nd 3rd 4th 5th
connections
opening and displaying (code) local databases 2nd 2nd
Microsoft Office 200x object models 2nd
OLE DB data provider
choosing 2nd Recordset object records, displaying 2nd 3rd records, editing 2nd 3rd 4th records, updating 2nd 3rd 4th recordsets, persisting 2nd 3rd 4th single tier applications 2nd SQL Server 2000 SQL Server 7.0 SQL Server objects, creating 2nd 3rd 4th SQL Server stored procedures, executing 2nd 3rd 4th type libraries, referencing 2nd 3rd Visual Studio 6.0
ADO 2.x
cursors ADO Extensions 2.7 for DDL and Security (ADOX) ADO.NET 2nd and ADO (ActiveX Data Objects), comparing 2nd 3rd
batch updates
on-the-fly, creating on-the-fly, executing objects 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
2nd 3rd 4th 5th 6th 7th 8th 9th
Page 561
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
stored procedures
parameterized, executing 2nd 3rd 4th 5th 6th 7th 8th Windows forms objects, using in Web forms
ADO.NET code
writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th SQL (auto-generated) strongly typed datasets XSDs 2nd 3rd ADO.NET. 2nd 3rd 2nd 3rd
[See also DataSet object]
ADODB
(ActiveX Data Objects 2.7) ADODB (ActiveX Data Objects 2.7 object model) 2nd 3rd ADODB.CursorTypeEnum.adOpenForwardOnly cursor type
ADOX
(ADO Extensions 2.7 for DDL and Security) Advanced Options button Alfred's Fried Foods Alias property ALL clause Allow Nulls Allow Nulls property ALTER TABLE statement 2nd
ampersand ( & )
variables, declaring Anchor property
APIs
DMF (Distributed Management Framework) references, setting 2nd 3rd 2nd 3rd
SQL-DMO
objects 2nd AppendChild (XMLElement class) AppendChild (XMLNode class)
applets Windows NT/2000 C ontrol Panel
groups and users, adding
Application object
methods properties Application Role button application roles (SQL Server security) 2nd 3rd 4th 5th ApplicationException
applications
assemblies
desktop (VB .NET)
generic search forms, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th exceptions
single tier
ADO (ActiveX Data Objects) 2nd states
Web (ASP.NET)
generic search forms, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd arrow buttons (right and left)
ASP.NET Web applications
Page 562
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
generic search forms, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd
Web Forms
developing Windows forms objects, using in Web forms ASP.NET Web Service templates 2nd 3rd assemblies
assigning reports
with ReportDocument 2nd
UDFs (user-defined functions)
code 2nd
variables
syntax
assigning values text boxes
code 2nd
at symbol (@)
parameters 2nd Attach Database button AttachDBWithSingleFile method 2nd
attaching
database file, code 2nd
files
to databases 2nd
routines
to SelectedIndexChanged event
SQL Server databases
code 2nd AttributeCount method
attributes
AutoEventWireUp 2nd
authentication login forms
XML Web Services mixed-mode 2nd 3rd 4th 5th
authentication mode SQL Server
Enterprise Manager Windows NT/2000 AUTO mode 2nd 3rd 4th 5th 6th 7th 8th
auto-generated SQL
VB .NET tools, writing ADO.NET code 2nd 3rd AutoEventWireUp attribute 2nd AutoIncrement property AutoPostBack property
[ Tea m LiB ]
Page 563
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] backing up databases
with SQL-DMO SQL databases SQL Server databases 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th BACKUP DATABASE statement
backup devices 1stBackupDevices list box
populating (code) 2nd 3rd 4th names, retrieving (code) BACKUP LOG statement Backup object methods properties Backup/Restore Wizard 2nd
BackupDevice object
methods properties
BackupDevices object
methods properties
backups
performing (code) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
basC ommandExamples.vb
bulk queries, creating and executing (code) stored procedures, calling (code) 2nd 3rd 2nd
basC onnectionExamples.vb ADO connections
opening and displaying (code)
JET databases
opening (code) 2nd
basRecordsetExamples.vb recordsets
opening and retrieving (code) persisting to disks (code) 2nd 2nd 3rd 4th
basStoredProcedureesExamples.vb
SQL Server objects, creating (code)
batch updates
executing 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th on-the-fly, creating in ADO.NET on-the-fly, executing in ADO.NET BEGIN statement BeginEdit method BeginLoadData method
behavior
of Crystal Report Viewer, controlling 2nd behaviorial control of classes 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
BETWEEN operator
syntax 2nd
BETWEEN statement
data, generating (code) bigint data type (SQL Server) 2nd
Page 564
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
binary data type (SQL Server) BinderContext class
binding columns to controls
properties 2nd
data
to ComboBox control 2nd 3rd 4th 5th 6th 7th 8th 9th to DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th data grids to DataView control (code)
data tables
code 2nd 3rd 4th 5th 6th 7th 8th
DataSet control
with ListBox control properties 2nd filling and binding products to DataGrid object (code) text boxes 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd 2nd 2nd
to datasets to list boxes
BindingContext object
BindingManagerBase object BindingManagerBase objects BindTheGrid routine 2nd bit data type (SQL Server)
blocks If[ellipsis dots] Then
code 2nd
Try[ellipsis dots]C atch[ellipsis dots]End
Catch statements
Try[ellipsis dots]C atch[ellipsis dots]End Try
controls, ignoring exceptions, trapping Try[ellipsis dots]Catch[ellipsis dots]Finally exceptions 2nd
blue wavy lines (code) BorderColor property
borders
Red/Blue style 2nd BottomLineStyle property
bound contols
on Web Forms at runtime 2nd
bound controls
at runtime 2nd
data
editing and updating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th error handling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th on Web Forms 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
AutoPostBack property DataBind method IsPostBack property 2nd Web server and HTML controls, comparing 2nd
records
adding and deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Windows forms
bound list boxes, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th bound list boxes, displaying data data bound forms 2nd 3rd 4th 5th 6th 7th
2nd 3rd 4th 5th 6th 7th 8th 9th
data, binding to controls 2nd 3rd 4th 5th 6th 7th 8th 9th
Page 565
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
data, editing and updating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
DataGrid control, drilling down to data 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th developing 2nd
error handling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th records, adding and deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th text boxes, binding and viewing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
bound list boxes
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th
data
displaying 2nd 3rd 4th 5th 6th 7th
boxes bound list
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th data, displaying 2nd 3rd 4th 5th 6th 7th
list
text boxes, binding and viewing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
message
displaying
text
binding and viewing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
boxes.
text boxes
[See also list boxes]
brackets
square ([ ])
break points
setting in stored procedures 2nd Web pages
browsers
Object Browser
btnAccept button click event
code 2nd
btnAdd
Click event, code 2nd 3rd
btnAdd button click event
code Click event, code 2nd 3rd
btnAttach button click event
code
btnBackup button click event
code
btnC ancel
Click event, code 2nd
btnC ancel button click event
code 2nd
btnC lose button click event
code 2nd 3rd
btnC onnect button click event
code
btnC onnection button
Page 566
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
disabling (code) enabling (code) 2nd 2nd
btnC reateTable click event
PerformTask( ) function, calling (code)
btnC reateUDF click event
code
btnC reateXMLFile button
Click event, code 2nd 3rd
btnDelete
Click event, code btnDelete button enabled properties, toggling (code) 2nd 3rd 4th 5th 2nd
btnDeleteTable click event
PerformTask( ) function, calling (code) 2nd
btnDetach button click event
code toggling (code)
btnEdit
Click event, code
btnEdit button
enabled properties, toggling (code) 2nd 3rd 4th 5th
btnEdit command button
ActiveEditing subroutine, calling (code) 2nd
btnExecute
click event (code) Click event, code
btnExport button click event
code
btnLoadList
Click event, code btnLoadList button
btnLocateFile button click event
code
btnLogin button
Click event, code 2nd
btnModifyTable click event
PerformTask( ) function, calling (code) btnNew button 2nd
btnOpenC onn button click event
code
btnPrint button click event
code
btnReadFile button
Click event, code 2nd
btnRestore button click event
code
btnRetrieve
code
btnRetrieveXML button
Click event, code
Page 567
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
btnSave
Click event, code
btnSave click event
trapping save exceptions (code) 2nd
btnSearch button click event
code 2nd
btnSelect button click event
code 2nd
btnTestValidator
Click event, code
btnTransfer button click event
code
btnUnSelect button click event
code 2nd
btnUpdate button click event
code
btnUseUDF click event
code
btnVerify button click event
code
btnView
Click event, code 2nd
btnView button click event
code Build button BuildCnnStr function 2nd BuildCnnStr routine BuildCnnStr( ) function 2nd builders. 2nd
[See also Query Builder]
building SQL statements
with Query Builder
SQL strings
code
built-in functions
T-SQL 2nd
built-in stored procedures sp-tables
testing 2nd
bulk queries creating and executing
code 2nd bulkadmin (fixed server role)
business rules
data constraints 2nd
Button control
properties 2nd 3rd 4th 5th 6th
button controls
click events, adding (code)
Page 568
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Button object
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th
buttons Add
clicking, effects Add to DataTable 2nd 3rd
adding
to DataGrid control 2nd 3rd 4th Advanced Options Application Role arrow (right and left Attach Database
btnAccept
click event (code) 2nd
btnAdd
click event (code) Click event, code 2nd 3rd
btnAttach
click event (code)
btnBackup
click event (code)
btnC ancel
click event (code) 2nd
btnC lose
click event (code) 2nd 3rd
btnC onnect
click event (code)
btnC onnection
disabling (code) enabling (code) 2nd 2nd
btnC reateXMLFile
Click event, code btnDelete enabled properties, toggling (code) 2nd 3rd 4th 5th 2nd 3rd
btnDetach
click event (code) toggling (code)
btnEdit
enabled properties, toggling (code) 2nd 3rd 4th 5th
btnEdit command
ActiveEditing subroutine, calling (code) 2nd
btnExport
click event (code) btnLoadList
btnLocateFile
click event (code)
btnLogin
Click event, code btnNew 2nd
btnOpenC onn
click event (code)
btnPrint
click event (code)
btnReadFile
Click event, code 2nd
Page 569
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
btnRestore
click event (code)
btnRetrieve
code
btnRetrieveXML
Click event, code
btnSearch
click event (code) 2nd
btnSelect
click event (code) 2nd
btnTransfer
click event (code)
btnUnSelect
click event (code) 2nd
btnUpdate
click event (code)
btnVerify
click event (code)
btnView
click event (code) Build 2nd
C ancel
clicking, effects
command
accessing on forms 2nd 2nd data (to edit, save, or cancel)
C ommand
properties
command
properties
C ommand
properties properties, settings 2nd 3rd 4th
C ommand Button control
properties 2nd 3rd 4th 5th 6th 7th 8th property settings 2nd 3rd 4th 5th 6th 7th
C ommand Button object
properties 2nd 3rd 4th property
C onnect
enabling Create XML File 2nd 3rd
DataGrid control
events Delete Detach Edit Ellipsis events on data grids Execute Export Invoke 2nd 2nd 2nd
ItemC ommand event
Repeater control events, programming
Label, TextBox, and C ommand
control property settings 2nd
Page 570
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label, TextBox, ListBox, and C ommand
property settings 2nd
Letter Button controls
click events (code) 2nd Letter Button result sets, filling (code) 2nd 3rd 4th Load List 2nd 3rd Locate File New Connection Open a Recordset Perform Backup Permissions 2nd Print
properties
setting property settings 2nd PushButton 2nd
Radio Button object
properties rbDistinct Radio Button control Read XML File
records
adding deleting RegionID, displaying Run Query
Save
clicking, effects Search SQL Server Authentication Stored Procedure with Parameter Use Distinct Use UDF View Code 2nd
[ Tea m LiB ]
Page 571
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
calculated fields, adding to reports 2nd 3rd 4th 5th
calling ActiveEditing subroutine
code 2nd GenerateData routine code 2nd 3rd
LoadProducts routine
code
PerformTask( ) function
code 2nd 3rd
RefreshIndividual routine
code 2nd 3rd
routines
code 2nd 3rd 4th 5th 6th 7th 8th 9th
SaveRecord routine
code 2nd search forms 2nd
stored procedures
code 2nd 3rd
UDFs
(user-defined functions) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th XML Web Services methods 2nd calling pages, returning to (code) 2nd
calls RefreshIndividual subroutine
adding (code) 2nd
C ancel button
clicking, effects
C ancel command
code
canceling edits
code 2nd 2nd canceling changes to data, code
canceling data
command buttons 2nd
canceling editing/adding records
in DataGrid object (code)
cancelling
data grid edits (code) caret (^) Cascade Delete Related Records cascade deletes
C atch statements
in Try[ellipsis dots]Catch[ellipsis dots]End Try block
catching
exceptions (code) 2nd 3rd
categories DropDown control
loading (code) loading;code 2nd 3rd 4th
Page 572
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
list boxes
repopulating (code) 2nd
loading
into list boxes (code) 2nd 3rd 4th 5th
C C ustomer class
code 2nd constructors (code) 2nd
mFax variable
event handlers (code) property declarations (code)
C C ustomerID class constructors
code 2nd
C C ustomerID.vb
constructors (object-based), code constructors, code 2nd 3rd CustomerID property, code
changes
updating to servers (code) 2nd 3rd 4th chapters in book, source code (Web site) char data type (SQL Server)
characters
Unicode
C hart tab
Standard Report Wizard
check boxes
Create Columns Automatically at Run Time, checking
Run Time
Create Columns Automatically, unchecking Unassigned Products Only 2nd Unassigned Products Only check Users Must Enter a User Name and Password to Use This Computer 2nd
C heckBox object
properties 2nd property
C heckC hanged event
code 2nd
child records
cascade deletes Choose a Query Type page (DataAdapter Configuration Wizard) Choose Your Data Connection page (DataAdapter Configuration Wizard) Choose Your Data Connection pge (DataAdapter Configuration Wizard)
class declarations MaximumStringLengthExceededException
code
classes
abstract ADO.NET code, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th SQL (auto-generated) strongly typed datasets XSDs 2nd 3rd behavioral control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th BinderContext 2nd 3rd 2nd 3rd
C C ustomer
code 2nd constructors (code) 2nd
Page 573
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
mFax variable event handlers (code) property declarations (code)
C C ustomerID
constructors (code) 2nd 3rd
C NumberString
code 2nd 3rd 4th international phone number extensions (code) code 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
creating to implement interfaces
creation control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th
C ustomer
code
data
errors, communicating to developers 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th validating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th validation code, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st
22nd 23rd 24th 25th 26th 27th data providers 2nd default properties defining 2nd 3rd 4th 5th in interfaces definition diagrams 2nd inheritance permission keywords 2nd
instances
definition
interfaces
implementing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 2nd member override keywords
members
definition
methods
adding to interfaces 2nd 3rd MustInherit keyword
objects
definition
OleDb
performance improvement parameterized properties pointers properties 2nd 3rd 4th adding to interfaces read-only properties 2nd 2nd
SQLC lient
performance improvement 2nd
variables
declarations (code) write-only properties 2nd
XMLDocument
CreateComment CreateNode DocumentElement LoadXML methods 2nd
properties 2nd Save
Page 574
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XMLElement
AppendChild
XMLNode
AppendChild methods 2nd
properties 2nd XMLNodeReader XMLReader 2nd
XMLTextReader XMLValidatingReader classes.
[See also data providers]
clauses
ALL DISTINCT records, displaying 2nd
C lear method
code 2nd
click events
adding to button controls (code)
btnAccept button
code 2nd
btnAdd button
code
btnAttach button
code
btnBackup button
code
btnC ancel button
code 2nd
btnC lose button
code 2nd 3rd
btnC onnect button
code
btnC reateTable click
PerformTask( ) function, calling (code) 2nd
btnC reateUDF
code
btnDeleteTable click
PerformTask( ) function, calling (code) 2nd
btnDetach button
code
btnExecute
code
btnExport button
code
btnLocateFile button
code
btnModifyTable click
PerformTask( ) function, calling (code) 2nd
btnOpenC onn button
code
btnPrint button
code
btnRestore button
code
btnSave
Page 575
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
trapping save exceptions (code) 2nd
btnSearch button
code 2nd
btnSelect button
code 2nd
btnTransfer button
code
btnUnSelect button
code 2nd
btnUpdate button
code
btnUseUDF
code
btnVerify button
code
btnView button
code 2nd
C lick events
for 1stCustomers (code) for btnAdd (code) 2nd 3rd 2nd 3rd
for btnAdd button (code) for btnCancel (code) 2nd
for btnCreateXMLFile button (code) for btnDelete (code) for btnEdit (code) for btnExecute (code) for btnLoadList (code) for btnLogin button (code) 2nd 2nd 2nd
2nd 3rd
for btnReadFile button (code)
for btnRetrieveXML button (code) for btnSave (code) for btnTestValidator (code) for btnView (code) 2nd
click events Letter Button controls
code 2nd
clicking
Add button, effects Cancel button, effects Delete key, effects Save button, effects client-side cursors
clients
state management 2nd XML Web Services Description Close (XMLTextWriter) Close method
closing forms
code 2nd 3rd 2nd forms (code)
C NumberString class
code 2nd 3rd international phone number extensions (code)
code
1stBackupDevices list box, populating 2nd 3rd 4th 5th 6th 7th 8th
Page 576
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
1stCustomers Click event 1stDatabases list box, populating 2nd 3rd 4th 5th 6th
1stLookupTables
pointing to items 2nd
1stUnSelected list box
reloading
1stUnselected list box
reloading
ActivateEditing routine
creating 2nd 3rd
ADO connections
opening and displaying 2nd 3rd 4th ADO.NET, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th SQL (auto-generated) strongly typed datasets XSDs 2nd 3rd backup device names, retieving backups, performing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 2nd 3rd 2nd 3rd
basC ommandExamples.vb
bulk queries, creating and executing stored procedures, calling 2nd 3rd 2nd
basC onnectionExamples.vb
ADO connections, opening and displaying JET databases, opening 2nd
basRecordsetExamples.vb
recordsets, opening and retrieving 2nd 3rd 4th recordsets, persisting to disks 2nd
basStoredProcedureesExamples.vb
SQL Server objects, creating BEGIN statement btnAccept button click event 2nd btnAdd button click event btnAdd button Click event btnAdd Click event 2nd 3rd
2nd 3rd
btnAttach button click event btnBackup button click event btnCancel button click event btnCancel Click event 2nd 2nd 3rd 2nd
btnClose button click event
btnConnect button click event
btnC onnection button
disabling 2nd enabling 2nd btnCreateUDF click event btnCreateXMLFile button Click event btnDelete Click event 2nd 2nd 3rd
btnDetach button click event btnDetach button, toggling 2nd btnEdit Click event btnExecute Click event btnExecute click event btnExport button click event btnLoadList Click event btnLocateFile button click event btnLogin button Click event 2nd
btnOpenConn button click event
Page 577
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
btnPrint button click event btnReadFile button Click event btnRestore button click event btnRetrieve btnRetrieveXML button Click event btnSave Click event btnSearch button click event 2nd btnSelect button click event 2nd btnTestValidator Click event btnTransfer button click event btnUnSelect button click event 2nd btnUpdate button click event btnUseUDF click event btnVerify button click event btnView button click event 2nd btnView Click event 2nd 2nd
bulk queries
creating and executing 2nd button controls, adding click events calling pages, returning to 2nd Cancel command CCustomer class 2nd
constructors 2nd 3rd property declarations
C C ustomerID.vb
constructors 2nd 3rd constructors (object-based) CustomerID property
changes
updating servers 2nd 3rd 4th CheckChanged event 2nd
class variable declarations 2nd classes 2nd 3rd creating to implement interfaces default properties defining 2nd 3rd 4th 5th interfaces, implementing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
methods, adding to interfaces parameterized properties properties 2nd 3rd 4th properties, adding to interfaces read-only properties 2nd
write-only properties 2nd Clear method 2nd 3rd
CNumberString class 2nd 3rd 4th
columns
listing in databases 2nd 3rd 4th columns, sorting 2nd ComboBox control, adding column names ComboBox control, loading 2nd 3rd 2nd 3rd
connection strings
creating 2nd 3rd 4th 5th 6th 7th 8th 9th establishing 2nd connection strings, creating 2nd
constructors
for CCustomerID class 2nd 3rd 4th
Page 578
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
inserting rows into tables 2nd object-based for CCustomerID class testing constructors, testing 2nd ContactName property Customer class 2nd 2nd
customer information
listing 2nd
C ustomerData.vb
DataAdapter Configuration Wizard 2nd 3rd SELECT command text Update command text CustomerID property 2nd 2nd 3rd
C ustomerInterface.vb
ICustomer interface, properties (code)
C ustomerInterface9_1.vb
delete method, declaring (code) ICustomer interface interfaces ReadOnly keyword save method, declaring (code) Customers XSD 2nd CustOrdersHist stored procedure, T-SQL 2nd
data
adding to data tables generating 2nd regenerating saving 2nd 2nd 3rd 4th
data grids
binding to DataView control edits, cancelling page indexes, updating paging through 2nd records, deleting 2nd 3rd 4th 5th 6th records, posting 2nd 3rd 4th 5th 6th setting to edit mode sorting 2nd updating 2nd
data tables
binding 2nd 3rd 4th 5th records, adding 2nd 3rd data tables, adding data data tables, binding data tables, loading 2nd
2nd 3rd 2nd 3rd
DataAdapter Configuration Wizard 2nd 3rd 4th database files, finding and attaching 2nd
database list boxes
loading 2nd 3rd 4th database names, retrieving 2nd 3rd
DataGrid control
loading 2nd 3rd 4th 5th 6th
DataGrid controls
populating 2nd 3rd 4th 5th
DataGrid object
loading 2nd records, canceling editing/adding
Page 579
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
special instructions 2nd
DataSet object
passing
datasets
loading 2nd retrieving from XML Web Services returning as XML 2nd 3rd
DataTable object
creating 2nd 3rd 4th tracking 2nd 3rd 4th 5th DataTable object, creating 2nd 2nd
DataView object, setting RowFilter property default properties, declaring
DefineValidC hars method
declaring Delete command
delete method
declaring 2nd
Delete method
implementing testing
detail pages
hyperlinks 2nd DialogResult, setting 2nd 3rd DoesCustomerIDExist function
DropDown control
loading 2nd 3rd 4th 5th
dsC ustomers.xsd
Customers XSD 2nd Edit command
edits
canceling 2nd END statement event handlers 2nd
for mFax variable
events
wiring for DataGrid control exception handling 2nd
exceptions
catching 2nd 3rd passing 2nd
formatting
UDFs (user-defined functions) 2nd
forms
closing 2nd 3rd 4th 5th loading 2nd 3rd opening 2nd 3rd 4th
frmHowTo.vb
constructors, testing
frmHowTo1_1
data sets, filling frmHowTo1_2.vb 2nd
frmHowTo1_3.vb
dataset, refreshing 2nd RefreshIndividual routine, calling 2nd RefreshIndividual subroutine, adding calls 2nd
Page 580
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmHowTo1_4.vb
ActiveEditing subroutine, calling 2nd data, canceling changes data, saving to servers 2nd 2nd
SaveRecord routine, calling 2nd text boxes, disabling text boxes, toggling 2nd 3rd 4th 2nd
frmHowTo1_5.vb
data, saving (code) 2nd 2nd dsCustomerIndividual dataset, adding records (code) edits, canceling (code) 2nd 2nd 3rd 2nd
list boxes, reloading (code)
mbAddNew variable, resetting (code) records, deleting (code) 2nd 3rd
frmHowTo1_6.vb
btnSave click event, trapping save exceptions (code) exceptions, catching 2nd 3rd exceptions, passing 2nd 2nd
frmHowTo1_7.vb
enabled properties of buttons, toggling forms, closing 2nd records, saving before closing 2nd 2nd 3rd 4th 5th
frmHowTo1_8.vb
DataGrid control, refreshing 2nd datasets, filling 2nd 3rd 4th
frmHowTo1_9
forms;opening (code) 2nd
frmHowTo1_9b
datasets;loading (code) 2nd
frmHowTo10_4.vb
reports, exporting 2nd reports, printing
frmHowTo10_5.vb
Selection combo box, populating SelectionFormula property, setting 2nd 3rd
frmHowTo13_3.vb
passwords, validating (code) usernames, validating (code)
frmHowTo13_4.vb
datasets, retrieving from XML Web Services
frmHowTo3_1.vb
list boxes, loading 2nd 3rd
frmHowTo3_2.vb
list boxes, loading 2nd
frmHowTo3_3.vb
ComboBox control, loading records, locating 2nd text boxes, assigning values 2nd 2nd 3rd
frmHowTo3_4.vb
button controls, adding click events columns, sorting 2nd ComboBox control, adding column names data tables, loading 2nd 3rd 2nd 2nd 3rd
DataView object, setting RowFilter property
frmHowTo6_1.vb
data, regenerating
Page 581
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
forms, loading SQL strings, building
frmHowTo6_2.vb
SQL statements, storing and executing 2nd
frmHowTo6_3.vb
data, generating 2nd GenerateData routine, calling 2nd 3rd
frmHowTo6_4.vb
left outer joins
frmHowTo6_6.vb
PerformTask( ) function, calling (code) SQL statements, executing (code) SQL statements, loading (code) 2nd 2nd 3rd
frmHowTo6_7.vb
forms, loading (code) 2nd SQL statements, storing (code) 2nd
frmHowTo6_8.vb
UDFs (user-defined functions), assigning UDFs (user-defined functions), creating 2nd 2nd 3rd 4th 5th
UDFs (user-defined functions), displaying data UDFs (user-defined functions), updating SELECT statement 2nd
frmHowTo7_1.vb
btnConnection button;disabling 2nd btnConnection button;enabling database list boxes, loading list boxes, repopulating routines, reloading list boxes 2nd routines;calling 2nd SQL Servers, loading 2nd 2nd
2nd 3rd 4th
frmHowTo7_2.vb
1stBackupDevices list box, populating 1stDatabases list box, populating backups, performing (code) routines, loading SQL Servers routines;calling 2nd 3rd 4th 5th 6th 7th
frmHowTo7_3.vb
1stBackupDevices list box, populating 1stDatabases list box, populating backups, performing (code) routines, calling SQL Servers, loading 2nd 3rd
frmHowTo7_4.vb
1stBackupDevices list box, populating 2nd 1stDatabases list box, populating 2nd forms, closing routines, calling SQL Servers, loading tables, copying 2nd 3rd 4th 5th
frmHowTo7_5.vb
1stDatabases list box, populating btnDetach button, toggling database files, finding and attaching forms, closing 2nd routines, calling SQL Server database, detaching SQL Server databases, attaching 2nd 2nd
Page 582
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SQL Servers, loading
frmHowTo8_1.vb
1stUnSelected list box, reloading list boxes, loading categories 2nd list boxes, populating 2nd 3rd 4th 5th 6th routines, calling servers, updating 2nd 3rd 4th 5th 6th
frmHowTo8_2.vb
1stLookupTables, pointing to items connection strings, establishing 2nd DataGrid control, populating 2nd 3rd 4th 5th 2nd
frmHowTo8_3.vb
columns, listing in databases 2nd DataGrid control, loading SQL strings, creating 2nd stored procedures, executing 2nd 3rd 4th 5th tables, listing in databases 2nd 3rd
frmHowTo8_4.vb
search forms, creating custom properties 2nd stored procedures, executing tables, listing in databases
frmHowTo8_4a.vb
Letter Button result sets, filling 2nd records, loading into text boxes 2nd 3rd
frmHowTo8_4b.vb
DialogResult, setting 2nd key values, storing 2nd
Letter Button controls, click events search forms, creating custom properties 2nd 3rd stored procedures, executing tables, listing in databases
frmHowTo8_6.aspx
data grids, deleting records 2nd 3rd 4th 5th 6th data grids, posting records 2nd 3rd 4th 5th 6th data grids, updating page indexes data tables, adding records 2nd 3rd
DataGrid object, canceling editing/adding records DataGrid object, special instructions DataTable object;tracking 2nd 3rd 4th 5th
frmHowTo8_7.vb
columns, listing in databases 2nd DataGrid control, loading 2nd 3rd SQL strings;creating 2nd 3rd 4th stored procedures, executing 2nd 3rd 4th tables, listing in databases 2nd
frmHowTo8_8a.vb
Letter Button result sets, filling 2nd records, loading 2nd 3rd Session object, storing values
frmHowTo8_8b.vb
calling pages, returning to 2nd data grids;updating key values, storing 2nd
Letter Button controls, click events stored procedures, executing tables, listing in databases
Page 583
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmHowTo9_2.vb
CCustomer class 2nd CCustomer class, property declarations class variable declarations Customer class TextBoxChange method, writing values in text boxees TextChanged event ToString method, property information output 2nd 2nd
frmHowTo9_4.vb
CCustomer class, constructors 2nd ReadValuesFromDataRow method 2nd
frmHowTo9_5.vb
Clear method 2nd constructors, inserting rows into tables constructors, testing Delete method, implementing Delete method, testing Save method, implementing Save method, testing WriteChangesToDB method 2nd 2nd 3rd 4th 5th
frmHowTo9_6
ContactName property InvalidPhoneNumberException MaximumStringLengthExceededException;class declaration phone numbers, validating 2nd 3rd
frmHowTo9_6.vb
DoesCustomerIDExist function If[ellipsis dots] Then block InvalidCustomerIDException, declaring ValidateCustomerID method
frmHowTo9_7.vb
event handlers
frmMain.vb
ADO connections, opening and displaying forms;opening (code) routines, calling 2nd
GenerateData routine
calling 2nd 3rd 4th
HTML
repRegions Repeater control repTerritories Repeater control
http[colon, no spaces]//localhost/WebService1/Service1.asmx?WSDL
XML Web Services, SOAP definition (code) 2nd 3rd 4th 5th ICustomer interface properties If[ellipsis dots] Then block international phone number extensions
InvalidC ustomerIDException
declaring 2nd InvalidPhoneNumberException 2nd
IsValid method
declaring
JET databases
opening 2nd 3rd 2nd 3rd 4th key values, storing left outer joins 2nd
Page 584
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Letter Button controls
click events 2nd 3rd 4th Letter Button result sets, filling 2nd 3rd 4th
list boxes
categories, loading 2nd 3rd 4th 5th populating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th reloading 2nd 3rd 4th 5th list boxes, loading 2nd 3rd 4th 5th
list boxes, repopulating Load event 2nd
LoadIndividual routine
creating 2nd 3rd
LoadList routine
creating 2nd
LoadProducts routine
calling lstSQLServers list box m (adding to)
MaximumStringLengthExceededException
class declaration
mbAddNew variable
resetting 2nd
mdtProducts DataTable object
rows, finding 2nd
modGeneralRoutines.vb
connection strings, creating 2nd 3rd 4th 5th 6th 7th 8th 9th
modPublicVariables.vb
public variables, declaring
modSQLDMORoutines.vb
backup device names, retrieving connection strings, creating 2nd database names, retrieving SQL Servers, loading 2nd 2nd 3rd
Northwind SQL Server database
CustOrdersHist stored procedure, T-SQL code overloaded methods PageIndexChanged command parameterized properties 2nd
passwords
validating 2nd 3rd
PerformTask( ) function
calling 2nd 3rd phone number extensions phone numbers, validating 2nd 2nd 3rd
PhoneDatatypes.vb
CNumberString class 2nd 3rd DefineValidChars method, declaring event handlers international phone number extensions IsValid method, declaring phone number extensions StringValue property ThrowException method, declaring ProductID detail information, loading 2nd property declarations (VB .NET) 2nd property declarations (VB 6)
Page 585
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
public varibles, declaring ReadOnly keyword 2nd 2nd
ReadValuesFromDataRow method
records
adding to data tables deleting 2nd 3rd loading into text boxes records, locating 2nd 2nd 3rd 2nd
recordsets
opening and retrieving 2nd 3rd 4th 5th persisting to disks 2nd
RefreshIndividual routine
calling
reports
exporting 2nd 3rd printing 2nd
repRegion Repeater control
loading repTerritories Repeater control loading routines calling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th list boxes, reloading 2nd SQL Servers, loading
rows
deleting in data grids 2nd 3rd finding save exceptions, trapping 2nd
save method
declaring
Save method
implementing testing 2nd 3rd 4th 5th
SaveRecord routine
creating 2nd 3rd replacing 2nd 3rd SaveRecord subroutine
search forms
custom properties, creating 2nd 3rd 4th 5th
SecurityServices.asmx.vb
DataSet object, passing passwords, validating (code) usernames, validating (code) SELECT command text
SELEC T statement
data, displaying updating 2nd
SelectedIndexC hanged
code 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th SelectedIndexChanged event
SelectedIndexChanged event, adding
Selection combo box
populating 2nd 3rd
SelectionFormula property
setting
servers
Page 586
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
updating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Session object
values, storing
session variables
tracking 2nd 3rd source code for chapters in book (Web site) SQL Server database, detaching 2nd
SQL Server databases
attaching 2nd
SQL Server objects
creating
SQL Servers
loading 2nd 3rd 4th SQL Servers, loading 2nd 3rd 4th
SQL statements
executing loading 2nd loading and executing storing 2nd storing and executing 2nd
SQL strings
building creating 2nd 3rd 4th 5th 6th
stored procedures
calling 2nd 3rd executing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
StringValue property 2nd
Table control
loading 2nd 3rd 4th 5th
Table data type
creating and returning
tables
copying 2nd 3rd 4th 5th 6th 7th listing in databases 2nd 3rd 4th 5th 6th 7th 8th
text boxes
toggling 2nd 3rd 4th text boxes, assigning values 2nd
TextBoxC hange method
text boxes, writing values TextChanged event 2nd 3rd 2nd
ThrowException method
declaring
ToString method
property information output 2nd 3rd
UDFs (user-defined functions)
assigning 2nd creating 2nd 3rd 4th 5th data, displaying SELECT statement, updating 2nd Update command Update command text 2nd 3rd 4th
UseAStoredProcedureWithAParameter routine
usernames
validating 2nd ValidateCustomerID method validation controls 2nd
Page 587
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
validation, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th
VB .NET
property declarations
VB 6
default properties property declarations wavy blue lines
Web pages
initializing 2nd 3rd 4th 5th linking loading 2nd 3rd
wfrmHowTo12_1.aspx.vb
data tables, adding data data tables, binding 2nd 3rd 2nd
DataTable object, creating
XML documents, creating 2nd
wfrmHowTo12_2.aspx.vb
XML documents, reading 2nd 3rd
wfrmHowTo12_3.aspx.vb
data tables, adding data data tables, binding 2nd 2nd 3rd 2nd
DataTable object, creating
XML documents, creating 2nd
wfrmHowTo12_4.aspx.vb
XML documents, reading 2nd
wfrmHowTo12_5.aspx.vb
data tables, adding data data tables, binding 2nd 2nd
DataTable object, creating XML documents, creating
XML documents, reading into datasets
wfrmHowTo5_1.aspx.vb
customer information, listing RefreshIndividual routine, calling Web pages, loading
wfrmHowTo5_2.aspx.vb
validation controls
wfrmHowTo5_3.aspx.vb
LoadProducts routine, calling rows, finding Web pages, initializing 2nd 3rd
wfrmHowTo5_4.aspx.vb
DropDown control, loading 2nd 3rd 4th Table control, loading 2nd 3rd 4th
wfrmHowTo5_5a.aspx
repRegions Repeater control, HTML repTerritories Repeater control
wfrmHowTo5_5a.aspx.vb
DropDown control, loading repRegion Repeater control, loading Table control, loading
wfrmHowTo5_5b.aspx
repTerritories Repeater control, HTML
wfrmHowTo5_5b.aspx.vb
repTerritories Repeater control, loading
Page 588
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
wfrmHowTo5_6.aspx.vb
data grids, binding to DataView control data grids, paging through data grids, sorting Web pages, loading
wfrmHowTo5_7.aspx
events, wiring for DataGrid control
wfrmHowTo5_7.aspx.vb
changes, updating servers 2nd 3rd 4th data grids, cancelling edits data grids, setting to edit mode DataGrid object, loading 2nd 2nd
records, adding to data tables rows, deleting in data grids
2nd 3rd
session variables, tracking 2nd 3rd
wfrmHowTo5_8a.aspx.vb
products, filling and binding to DataGrid object
wfrmHowTo5_8b.aspx.vb
ProductID, loading detail information 2nd
wfrmHowTo8_5.aspx
1stUnselected list box, reloading list boxes, loading categories 2nd 3rd list boxes, populating 2nd 3rd 4th 5th 6th routines, calling servers, updating 2nd 3rd 4th WriteChangesToDB method 2nd
XML documents
creating 2nd 3rd 4th 5th 6th 7th reading 2nd reading into datasets reading with XMLTextReader 2nd 3rd
XML Web Services
SOAP definition 2nd 3rd 4th 5th
code (VB .NET) reports
displaying 2nd 3rd 4th 5th 6th 7th exporting 2nd 3rd 4th 5th 6th 7th 8th 9th printing 2nd 3rd 4th 5th 6th 7th 8th 9th Code command (View menu) collapsing routines
collections Items
data, adding Items (index) SelectedIndices (index) collection SQL-DMO 2nd String Collection Editor 2nd Table Mappings 2nd
Column Name property Column property
columns
adding to tables
binding to controls
properties 2nd Create Columns Automatically at Run Time check box, checking Create Columns Automatically, unchecking
Page 589
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
CustomerID (Customers table) CustomerID (Orders table) 2nd 2nd
data
entering
data grids
templates
DataGrid Property Builder
Columns tab DataItem.RegionURL HyperLink
listing in databases
code 2nd 3rd 4th
names
adding to ComboBox control (code) NULL properties 2nd 3rd SELECT string setting for DataGrid control 2nd sorting sorting (code) 2nd 2nd 3rd
SQL Server database objects 2nd 3rd 4th 5th Columns tab (DataGrid Property Builder) columns.
[See also fields]
C OM
type libraries, registering
combo boxes
customers, finding
Selection
populating (code) 2nd 3rd 4th 5th 6th
C ombo control
property settings 2nd
C omboBox control
column names, adding (code) 2nd 3rd
data
binding to 2nd 3rd 4th 5th 6th 7th 8th 9th
datasets
filling (code) loading (code) properties property settings 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 2nd 3rd
C omboBox object
properties 2nd 3rd 4th property property settings 2nd
C ommand button
properties 2nd settings 2nd 3rd 4th
C ommand Button control
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th property settings 2nd 3rd 4th 5th 6th 7th
C ommand Button object
properties 2nd 3rd 4th 5th property
command buttons
accessing on forms 2nd 2nd data (to edit, save, or cancel)
Page 590
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
properties Command object 2nd 3rd
actions
executing with SQL statements 2nd methods properties
TextBox control
populating with stored procedures 2nd CommandBuilder object methods properties
commands Action menu
New Group Properties
Actions menu
New Login
Add menu
Add Class Add New Item 2nd
C ancel
code
context menu
New Login Properties CREATE FUNCTION
Delete
code
Edit
code
File menu
New
PageIndexC hanged
code
pop-up menu
Copy Generate Dataset Paste Run as Server Control 2nd
Project menu
Add Reference 2nd Add Web Reference
Report menu
Report Options SELECT command text, code
shortcut menu
New Database Role New Database User New Login Update code Update command text, code 2nd 3rd
View menu
Code Indexes/Keys commands. 2nd
[See also T-SQL (Transact-SQL) commands]
Page 591
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
CommandText property CommandText property, accessing 2nd
companies
Alfred's Fried Foods CompareValidator control
C ompareValidator object
properties
comparing
ADO (ActiveX Data Objects) and ADO.NET 2nd 3rd OleDb and SQLClient objects Web server and HTML controls compound indexes Confirm Password text box 2nd 2nd
C onnect button
enabling connected data Connection object 2nd
ADO (ActiveX Data Objects) 2nd 3rd 4th 5th methods properties
connection strings
BuildCnnStr( ) function
creating
code 2nd 3rd 4th 5th 6th 7th 8th 2nd 3rd 2nd creating (code)
establishing (code) text, displaying
2nd
connections ADO (ActiveX Data Objects)
opening and displaying (code) 2nd
databases
with SQL-DMO objects 2nd
Northwind database
creating 2nd trusted (SQL Server)
conrtrols
bound at runtime 2nd
constraints
defining 2nd 3rd 4th 5th 6th for data 2nd
of indexes
constructors C C ustomer class
code 2nd
for C C ustomerID class
code for CCustomerID class (code) 2nd
object-based
for CCustomerID class (code) objects
rows, inserting into tables
code
testing
code 2nd
consuming
XML Web Services 2nd 3rd 4th 5th 6th 7th
Page 592
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
methods, calling 2nd Web references 2nd 3rd
C ontactName property
code
context menu commands
New Login Properties
C ontrol Panel applets (Windows NT/2000)
groups and users, adding
control property settings
Label, TextBox, and Command button 2nd
C ontrol.ViewState property
definition
controlling
classes, creation and behavior Crystal Report Viewer behavior sort order at run-time 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 2nd
controls
arranging on forms 2nd 3rd 4th 5th
bound
AutoPostBack property DataBind method IsPostBack property 2nd on Web Forms 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 2nd
Web server and HTML controls, comparing
button
click events, adding (code) 2nd
Button
properties 2nd 3rd 4th 5th 6th
columns, binding to
properties 2nd
C ombo
property settings 2nd
C omboBox
data, binding to 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd datasets, filling (code) loading (code) properties property settings 2nd 3rd 4th 5th 6th 7th 8th 9th
2nd 3rd
C ommand Button
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th property settings 2nd 3rd 4th 5th 6th 7th CompareValidator
C rystal Report Viewer
reports, displaying 2nd 3rd 4th 5th 6th 7th 8th 9th
C rystalReportViewer
property settings 2nd
customer orders
header information, displaying CustomValidator 2nd 2nd
data
DataSet DataView in Windows forms OleDbCommand OleDbConnection 2nd 3rd
Page 593
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
OleDbDataAdapter SqlCommand SqlConnection SqlDataAdapter
DataGrid
button events on data grids 2nd buttons, adding 2nd 3rd 4th buttons, events 2nd
columns, setting 2nd data grids, hyperlinking from rows to detail pages data, adding 24th 25th 26th data, binding to data, deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 2nd 3rd 4th 5th 6th 7th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd
24th 25th 26th 27th 28th 29th 30th data, displaying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
data, drilling down to data, editing 24th 25th 26th data, manipulating data, new items
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd
2nd
data, paging through 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th data, sorting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th datasets, filling (code) events, wiring (code) 2nd 2nd
General properties, setting 2nd loading (code) 2nd 3rd 4th 5th 2nd
lookup tables, adding data objects, handling 2nd 3rd
Paging properties, setting 2nd populating (code) 2nd 3rd 4th 5th
properties 2nd 3rd 4th property settings 2nd 3rd 4th 5th 6th refreshing (code) 2nd 2nd
schemas;loading into data tables DataGrid Web server DataList Web server DataRepeater DataSet 2nd
binding with ListBox control properties 2nd for frmHowTo1_9b forms DataView data grids, binding (code) 2nd 2nd 3rd
ddSortby
SelectedIndexChanged event, attaching routines
DropDown
loading (code) 2nd 3rd 4th 5th populating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th propeties
Export tab page
objects and properties
Hyperlink
properties
HyperLink
propeties ignoring with Try[ellipsis dots]Catch[ellipsis dots]End Try block
Page 594
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Label
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th properties, settings 2nd 3rd 4th property settings 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th propeties
Label, TextBox, ListBox, and C ommand button
property settings 2nd
Letter Button
click events (code) 2nd
ListBox
loading populating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th properties 2nd 3rd 4th 5th 6th 7th properties, setting to bind DataSet control 2nd properties, settings 2nd 3rd 4th property settings 2nd 3rd 4th 5th 6th 7th ListBox Web server ListBox Windows Forms
OleDataAdapter
for frmHowTo1_9b forms 2nd 3rd
OleDbDataAdapter
controls 2nd
on Web Forms
bound at runtime OpenFileDialog order information, displaying 2nd 2nd
Print tab page
objects and properties properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th setting settings property settings 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th RangeValidator rbDistinct Radio Button Regular ExpressionValidator
Repeater
data, displaying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th events, programming lists, buttons and hyperlinks lists, displaying regional territories 2nd 3rd properties repRegion, loading (code) repRegions, HTML code repTerritories, code repTerritories, HTML code repTerritories, loading (code) 2nd templates 2nd 3rd 2nd
URLs (uniform resource locators), creating 2nd Repeater Web server
repRegion Repeater
loading (code)
repRegions Repeater
HTML code
repTerritories Repeater
code HTML code
Page 595
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
loading (code) RequiredFieldValidator Selected Products ListBox tab pages 2nd
Table
data, displaying loading (code) persistence propeties tables, displaying 2nd Table Web server 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th
objects, creating 2nd TextArea
TextBox
populating 2nd properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th properties, settings 2nd 3rd 4th property settings 2nd 3rd 4th unbound on forms Unselected Products ListBox
validation
code messages, displaying on Web Forms 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
property settings 2nd 3rd
validation (Web Forms)
property settings 2nd 3rd 4th 5th validation errors 2nd Validation Web server 2nd 3rd ValidationSummary lists, look of
validator
reaction inconsistencies
View tab page
objects and properties Web server and HTML, comparing controls. 2nd
[See also bound controls]
cookies
definition Copy command (pop-up menu)
copying tables
between SQL Server databases code 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th
Create Columns Automatically at Run Time check box, checking Create Columns Automatically, unchecking Create Database dialog box CREATE DATABASE statement CREATE DEFAULT statement CREATE FUNCTION command CREATE FUNCTION statement CREATE PROCEDURE statement Create Relationships dialog box CREATE RULE statement CREATE TABLE statement 2nd 3rd 4th CREATE VIEW statement 2nd 3rd 2nd
Page 596
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Create XML File button 2nd 3rd
CreateComment (XMLDocument class) CreateNode (XMLDocument class)
creatin
objectsd 2nd
creating ActivateEditing routine
code 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th bound list boxes
bulk queries
code 2nd
classes
to implement interfaces 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
connection strings
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
custom properties
for search forms 2nd 3rd 4th 5th data adapters data tables 2nd
2nd 2nd 3rd 4th 5th 6th
database user accounts
DataTable object
code 2nd 3rd 4th 5th 6th Delete Record Detach/Attach SQL Server Database dialog box 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th dialog boxes forms GenerateData routine 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
generic search forms
data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th 47th 48th 49th 50th GetBackupDevices routine GetSQLDatabases routine
indexes
with Property Pages dialog box interfaces LoadIndividual routine 2nd code 2nd 3rd 2nd
LoadList routine
code 2nd LoadSelectedProducts routine 2nd LoadUnSelectedProducts routine mailing labels 2nd 3rd Northwind database connections 2nd
objects
with SQL syntax on-screen reports with hyperlinks fields as hyperlinks 2nd 3rd Web site fields, adding 2nd 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
on-the-fly batch updates in ADO.NET
point-and-click query tool
data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
point-and-click SQL Server query tool
data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
reports
with Report Expert 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
Page 597
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SaveRecord routine
code 2nd 3rd SQL Server database 2nd 3rd 4th 5th 6th constraints, defining 2nd 3rd 4th 5th 6th default values, defining fields, defining 2nd 3rd 4th 5th 6th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th 6th 7th 8th 9th
indexes, defining
primary keys, defining
stored procedures, creating 2nd 3rd 4th 5th tables, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
tables, defining relationships 2nd 3rd 4th 5th 6th 7th 8th 9th views, creating 2nd 3rd 4th 5th 6th 7th 8th
SQL Server database objects column properties 2nd 3rd columns 2nd rows 2nd
table properties 2nd 3rd tables 2nd
SQL Server objects
code SQL Server objects with ADO (ActiveX Data Objects) 2nd 3rd 4th SQL statements
SQL strings
code 2nd 3rd 4th creating 2nd standard logins 2nd 3rd 4th 5th stored procedures 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th T-SQL commands 2nd Table data type tables 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th CREATE TABLE statement 2nd 3rd tblCustomerPhones table UDFs 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
(user-defined functions) calling 2nd code, formatting 2nd
parameters, passing scalar types, returning 2nd table types, returning 2nd
UDFs (user-defined functions)
code 2nd 3rd 4th 5th URLs (uniform resource locators) 2nd views 2nd 3rd 4th 5th 6th 7th 8th
Web Forms Windows NT/2000 groups Windows NT/2000 logins 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
XML documents
code 2nd 3rd 4th 5th 2nd data tables, creating
with XMLTextWriter 2nd 3rd 4th with XMLWriter 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th XMLTextWriter 2nd 3rd XML Web Services 2nd 3rd 4th 5th 6th 7th XML Web Services with parameters descriptions 2nd methods, descriptions 2nd 2nd 3rd 4th 5th 6th
Page 598
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
parameters, passing 2nd security tables 2nd creation control of classes 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th Criteria property Crosstab reports
C rystal Report
Gallery dialog box Crystal Report Gallery dialog box
C rystal Report Viewer
behavior, controlling 2nd
reports
displaying 2nd 3rd 4th 5th 6th 7th 8th 9th ReportSource property 2nd 3rd Crystal Reports Experts licensing
reports
calculated fields, adding 2nd 3rd 4th 5th creating with Report Expert 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
displaying 2nd 3rd 4th 5th 6th 7th displaying with Viewer 2nd 3rd 4th 5th 6th 7th 8th 9th
exporting 2nd 3rd 4th 5th 6th 7th 8th 9th fields as hyperlinks 2nd 3rd labels, printing 2nd 3rd 4th 5th 6th 7th 8th mailing labels, creating 2nd 3rd on-screen, adding Web site fields 2nd
on-screen, creating with hyperlinks 2nd 3rd 4th 5th 6th options, setting 2nd printing 2nd 3rd 4th 5th 6th 7th 8th 9th printing at run-time 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th records, printing 2nd 3rd 4th 5th 6th 7th 8th ReportSource property 2nd 3rd SelectionFormula syntax 2nd
sort order, controlling at run-time 2nd
C rystalReportViewer control
property settings 2nd
C rystalReportViewer object
property settings 2nd CType( ) function cursor data type (SQL Server)
cursors
ADO 2.x client-side Dynamic type Forward Only type
types
ADODB.CursorTypeEnum.adOpenForwardOnly custom database roles (SQL Server security) 2nd 3rd 4th 5th 6th
C ustomer class
code
customer information listing
code
customer orders
header information, displaying 2nd
information
Page 599
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
controls to display 2nd displaying (code) 2nd 3rd 4th
C ustomerData.vb
DataAdapter Configuration Wizard, code 2nd 3rd SELECT command text, code Update command text, code 2nd 3rd 2nd
CustomerID column (Customers table) CustomerID column (Orders table) 2nd
C ustomerID property
code
C ustomerInterface.vb IC ustomer interface
properties (code)
C ustomerInterface9_1.vb delete method
declaring (code)
IC ustomer interface
code
interfaces
code ReadOnly keyword, code
save method
declaring (code)
customers finding
in combo boxes
RefreshIndividual routine
calling (code)
customers orders
details, drilling down to
C ustomers page
search forms, calling 2nd
C ustomers table
CustomerID column 2nd list Server Explorer Customers XSD, code 2nd Customers, CustomerCustomerDemo, and CustomerDemographics table
customizing
reports 2nd
C ustomTask object
methods properties CustomValidator control 2nd CustOrdersHist stored procedure, T-SQL code
[ Tea m LiB ]
Page 600
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D ] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] DAO
(Data Access Objects) 2nd
data adding
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th to Items collection adding to lookup tables 2nd
binding
to ComboBox control 2nd 3rd 4th 5th 6th 7th 8th 9th to DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th canceling changes (code) 2nd
command buttons
to edit, save, or cancel connected constraints 2nd 2nd
controls
DataSet DataView in Windows forms OleDbCommand OleDbConnection OleDbDataAdapter SqlCommand SqlConnection SqlDataAdapter 2nd 3rd
deleting
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th details, retrieving disconnected
displaying
in bound list boxes 2nd 3rd 4th 5th 6th 7th in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th templates 2nd 3rd
URLs (uniform resource locators), creating 2nd with Repeater control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
with SELECT statement (code) with Table control 2nd 3rd 4th 5th 6th 7th 8th 9th
displaying in DataGrid control 2nd drilling down to 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th editing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th notifying users 2nd entering into columns errors, communicating to developers 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
exporting
with SQL-DTS filling DataGrid control
generating
Page 601
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
code 2nd
loading into list boxes 2nd manipulating 2nd 3rd methods objects 2nd 3rd 2nd 3rd
paging through
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th properties 2nd 3rd regenerating (code) retrieving from SQL Server 2000 database 2nd 3rd 4th 5th 6th 7th retrieving with DataReader object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
saving
code 2nd 2nd to servers (code)
sorting
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
tables
binding (code) updating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th validating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th validating on Web Forms validation code, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd
23rd 24th 25th 26th 27th views Data Access Objects.
[See DAO]2nd [See DAO]
Data Adapter Configuration Wizard 2nd
data adapters
creating 2nd Table Mappings collection 2nd data bound forms 2nd 3rd 4th 5th 6th 7th 8th 9th
data driven
definition
data grids
binding to DataView control (code) button events 2nd
data tables
binding (code) 2nd 3rd 4th 5th 6th 7th 2nd 3rd data tables, binding (code) EditItemIndex
edits
cancelling (code) HyperLink columns hyperlinking from rows to detail pages information, retrieving 2nd 2nd 3rd 4th 5th 6th 7th
page indexes
updating (code)
paging through
code
records
deleting (code) posting (code) 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
rows
deleting (code) 2nd 3rd setting to edit mode (code)
sorting
code
Page 602
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
sorting, setting 2nd 3rd 4th templates
updating
code Data Link Properties dialog box data providers classes 2nd
OLE DB (ADO)
choosing 2nd
data sets
filling with frmHowTo1_1 (code)
data sources
choosing
Data tab
Standard Report Wizard
data tables binding
code 2nd 3rd 4th 2nd 3rd binding (code) creating 2nd
data
adding (code) data, adding (code) loading (code) 2nd 3rd 2nd 3rd
records
adding (code) locating (code) 2nd 2nd
records, adding, code 2nd 3rd schemas, loading 2nd
text boxes
assigning values (code) Data Transformation Services. 2nd
[See DTS]
data types
bigint (SQL Server) binary (SQL Server) bit (SQL Server) char (SQL Server) cursor (SQL Server) datetime (SQL Server) decimal (SQL Server) float (SQL Server) image (SQL Server) int (SQL Server) money (SQL Server) nchar (SQL Server) ntext (SQL Server) numeric (SQL Server) nvarchar (SQL Server) real (SQL Server) smalldatetime (SQL Server) smallint (SQL Server) smallmoney (SQL Server) SQL Server 2nd 3rd 4th 5th sql_variant (SQL Server) Table creating and returning
Page 603
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
table (SQL Server) text (SQL Server) timestamp (SQL Server) tinyint (SQL Server) uniqueidentifier (SQL Server) varbinary (SQL Server) varchar (SQL Server)
data-bound multi-select list boxes
data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th data-driven techniques 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
data-bound multi-select list boxes
21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th
generic search forms
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th 47th 48th 49th 50th
lookup tables
updating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th
point-and-click query tool
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
point-and-click SQL Server query tool
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
DataAdapter frmHowTo1_2.vb
code 2nd
DataAdapter C onfiguration Wizard
Choose a Query Type page Choose Your Data Connection page code 2nd 3rd 2nd 2nd
Generate the SQL Statements page DataAdapter object methods 2nd 3rd
properties 2nd 3rd DataAdapter Update method
database list boxes loading
code 2nd Database property Database Role Properties dialog box Permissions tab 2nd Database User Properties dialog box 2nd 2nd
databases 1stDatabases list box
populating (code) 2nd 3rd 4th 5th application roles (SQL Server security) 2nd 3rd 4th 5th
backing up
with SQL-DMO
btnDetach button
toggling (code)
classes
code 2nd 3rd
columns
listing (code) 2nd 3rd 4th
Page 604
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
connecting to
with SQL-DMO objects 2nd custom database roles (SQL Server security) 2nd 3rd 4th 5th 6th db_accessadmin (fixed database role) db_backupoperator (fixed database role) db_datareader (fixed database role) db_datawriter (fixed database role) db_ddladmin (fixed database role) db_denydatareader (fixed database role) db_denydatawriter (fixed database role) db_owner (fixed database role) db_securityadmin (fixed database role)
Detach/Attach SQL Server Database dialog box
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th detaching 2nd diagrams
dialog boxes
creating and connecting to 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
files
attaching 2nd finding and attaching (code) 2nd
fixed database roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th how-to, design view 2nd
JET
opening (code) JET database engine 2nd
list boxes
loading (code) 2nd lists, refreshing 2nd
local
ADO (ActiveX Data Objects) 2nd
names
retrieving (code) 2nd 3rd
Northwind
customers, tracking demographics
Northwind SQL Server
Customers table list null values, interpreting public (fixed database role) reattaching
records
inserting
relationships
Create Relationships dialog box rights, sharing Server Explorer 2nd 2nd
SQL
backing up verifying
SQL Server
attaching (code) backing up 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
constraints, defining 2nd 3rd 4th 5th 6th creating 2nd 3rd 4th 5th 6th default values, defining detaching (code) 2nd 3rd 4th 5th 6th
Page 605
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
fields, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th 6th 7th 8th 9th
indexes, defining
primary keys, defining
restoring 2nd 3rd 4th 5th 6th 7th 8th 9th 10th stored procedures, creating 2nd 3rd 4th 5th tables, copying between tables, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
tables, defining relationships 2nd 3rd 4th 5th 6th 7th 8th 9th verifying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 2nd 3rd 4th 5th 6th 7th 8th
views, creating
SQL Server 2000
data, retrieving 2nd 3rd 4th 5th 6th 7th
SQL Server database objects
column properties 2nd 3rd columns 2nd creating rows 2nd
table properties 2nd 3rd tables 2nd
SQL-DMO
(SQL-Distributed Management Objects) 2nd 3rd objects
states
supporting
tables
listing (code) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th many-to-many relationship one-to-many relationship one-to-one relationship referential integrity 2nd 3rd searching 2nd 3rd 4th 2nd
updating
methods, implementing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th user accounts, creating 2nd 3rd 4th 5th 6th user options
users
logging in databases.
[See also data-driven techniques]
DataBind method Databind method DataColumn object methods properties DataDefinition object DataFormatString property
DataGrid control
button events on data grids 2nd buttons, adding 2nd 3rd 4th buttons, events 2nd
columns, setting 2nd
data
adding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th binding to 2nd 3rd 4th 5th 6th 7th 8th 9th deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th
Page 606
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
displaying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th drilling down to 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th editing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th manipulating 2nd new items paging through 2nd 3rd 4th 5th 6th 7th 8th 9th 10th sorting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
data grids
hyperlinking from rows to detail pages data, displaying 2nd 2nd 3rd 4th 5th 6th 7th
datasets
filling (code) 2nd events, wiring (code) General properties, setting 2nd
loading
code loading (code) 2nd 3rd
lookup tables
data, adding 2nd
objects
handling 2nd 3rd Paging properties, setting 2nd populating (code) 2nd 3rd 4th 5th
properties 2nd 3rd 4th property settings 2nd 3rd 4th 5th 6th refreshing (code) 2nd
schemas
loading into data tables 2nd
DataGrid object loading
code 2nd
products
filling and binding (code) properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd records, canceling editing/adding (code) special instructions, code
DataGrid Property Builder
Columns tab General tab Paging tab DataGrid Web server control
DataGrids
displaying 2nd DataItem.RegionURL column DataList Web server control DataReader object data, retrieving 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
list boxes
loading (code) methods properties datareader.Read( ) method DataRepeater control DataRow object methods 2nd 2nd 3rd
Page 607
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
properties 2nd DataRowView object
DataSet
(data control) controls 2nd
frmHowTo1_2.vb
code 2nd
DataSet control
binding with ListBox control properties 2nd
DataSet controls
for frmHowTo1_9b forms DataSet object methods 2nd 3rd
passing
code properties 2nd 3rd 4th 5th 6th 7th 8th
DataSet objects data
editing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
rows
adding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
datasets dsC ustomerIndividual
records, adding (code) loading (code) 2nd 2nd
passing from XML Web Services 2nd 3rd 4th 5th 6th 7th
refreshing
code 2nd retrieving from XML Web Services (code) returning as XML (code) 2nd 3rd
strongly typed
VB .NET tools, writing ADO.NET code 2nd 3rd tables
text boxes
binding 2nd XML documents 2nd 3rd 4th 5th 6th 7th 8th 9th creating (code) reading (code) DataSource property DataSource property (list boxes) 2nd 2nd
DataTable object
creating (code) DataTable object 2nd
C omboBox control
loading (code) 2nd 3rd
creating
code 2nd 2nd creating (code)
list boxes
loading (code) methods objects 2nd 2nd 3rd 4th 5th 2nd 3rd
properties 2nd 3rd 4th 5th records, locating 2nd 3rd 4th 5th 6th 7th 8th 9th
Page 608
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SQL Server
results, retrieving 2nd 3rd 4th 5th 6th
tracking
code 2nd 3rd 4th 5th
DataTable.C olumns object
methods properties
DataTable.Rows object
methods 2nd properties 2nd DataTextField property DataType property DataValueField property
DataView
(data control) DataView control data grids, binding (code) DataView object records, filtering 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th records, sorting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th RowFilter property, setting (code) 2nd
DateDiff function
Days_to_Ship, displaying DateDiff( ) function Days_to_Ship, displaying datetime data type (SQL Server)
DateTimePicker object
properties Days_To_Ship (SQL statements, displaying in labels) 2nd db_accessadmin (fixed database role) db_backupoperator (fixed database role) db_datareader (fixed database role) db_datawriter (fixed database role) db_ddladmin (fixed database role) db_denydatareader (fixed database role) db_denydatawriter (fixed database role) db_owner (fixed database role) db_securityadmin (fixed database role) dbcreator (fixed server role)
ddSortby control SelectedIndexC hanged event
routines, attaching decimal data type (SQL Server)
declarations
CCustomer class properties (code) class variables (code) MaximumStringLengthExceededException class, code Private property (VB .NET code) property (VB 6 code) DECLARE statement 2nd 2nd
declaring default properties
code
DefineValidC hars method
code
Page 609
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
delete method
code InvalidCustomerIDException (code)
IsValid method
code
local variables
in T-SQL 2nd
public variables
code
save method
code
ThrowException method
code 2nd Default keyword
default properties
classes, defining
declaring
code
in VB 6
code
default values
defining 2nd 3rd 4th 5th 6th
DefineValidC hars method declaring
code
defining
classes 2nd 3rd 4th 5th default properties in interfaces methods, adding to interfaces parameterized properties properties 2nd 3rd 4th properties, adding to interfaces read-only properties 2nd 2nd 3rd
write-only properties 2nd constraints 2nd 3rd 4th 5th 6th default values 2nd 3rd 4th 5th 6th
fields 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th indexes 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th 6th 7th 8th 9th
primary keys
table relationships 2nd 3rd 4th 5th 6th 7th 8th 9th tables 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
definitions
class Control.ViewState property cookies data driven HTML hidden fields inheritance instances of classes loosely coupled messages members of classes method signature objects query strings
definitios
Page 610
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XSD
(XML Schema Definition) Delete button
Delete command
code
Delete key
clicking, effects Delete method 2nd
delete method declaring
code
Delete method
implementing code
testing
code delete object permission Delete Record, creating deletes, cascade
deleting data
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th lookup table information 2nd
records 2nd 3rd 4th 5th 6th 7th 8th 9th 10th buttons code 2nd 3rd 2nd 3rd
exceptions, catching (code) in data grids (code)
2nd 3rd 4th 5th 6th
rows
in data grids (code) 2nd 3rd in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th tables 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th DROP TABLE statement 2nd
DeliveryDate
values 2nd demographics of customers, tracking deny access level (object permissions) deny state (statement permissions) DESC (Sort property) Description text box 2nd
descriptions
of methods 2nd Web Services, creating with parameters 2nd XML Web Services 2nd viewing 2nd 3rd 4th 5th
XML Web Services Description descriptive languages.
[See also WSDL]
design time DataGrid control
columns, setting 2nd Paging properties, setting 2nd
design view
database how-to 2nd
Design view
reports, displaying 2nd
Page 611
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
designers
Report Designer View Designer Diagram pane Grid pane properties Results pane SQL pane tables 2nd
designes
Taable Designer
desktop applications (VB .NET)
generic search forms, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th DestinationOptions (ExportOptions object) Detach button
Detach/Attach SQL Server Database dialog box
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th DetachDB method 2nd
detaching
databases 2nd SQL Server database, code detail data, retrieving
detail information of Product ID
loading (code) 2nd
detail pages
hyperlinks 2nd rows, hyperlinking to 2nd 3rd 4th 5th 6th 7th
Details section of reports
fields 2nd
developing
Windows forms Devices property dgRegion_CancelCommand routine dgRegion_DeleteCommand routine dgRegion_EditCommand routine dgRegion_UpdateCommand routine Diagram pane (View Designer) 2nd
diagrams
databases of classes 2nd
dialog boxes
Add Members Add New User Add Reference Add Role Members Add Table connecting to databases Create Database 2nd 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 2nd 2nd 2nd 3rd
Create Relationships
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th Crystal Report Gallery Data Link Properties Database Role Properties Permissions tab 2nd Database User Properties 2nd 2nd 2nd
Detach/Attach SQL Server Database
Page 612
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th Format Generate Dataset New Group New Project New Role 2nd 3rd 4th 2nd
OLE DB (ADO) dialog box Properties Windows Only option Property Builder 2nd
Property Pages
indexes, creating opening 2nd
Report Options
reports, customizing 2nd Server Role Properties 2nd SQL Server Login Properties 2nd
Standard Report Expert
tabs 2nd Table Properties 2nd Permissions tab 2nd DialogResult, setting (code) 2nd
directories
XML Web Services Directories
disabled
Windows NT/2000 accounts 2nd
disabling btnC onnection button
code 2nd
text boxes
code 2nd 2nd text boxes, code disconnected data
discoveries XML Web Services
Discovery diskadmin (fixed server role)
disks
recordsets, persisting to (code) 2nd 3rd
displaying ADO connections
code 2nd connection string text 2nd customer order header information 2nd
data
in bound list boxes 2nd 3rd 4th 5th 6th 7th in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th templates 2nd 3rd
URLs (uniform resource locators), creating 2nd with Repeater control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 2nd
with SELECT statement (code) with Table control
2nd 3rd 4th 5th 6th 7th 8th 9th
data in DataGrid control 2nd DataGrids 2nd
Formula Editor
displaying 2nd
Page 613
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
lists
look of in ValidationSummary control message boxes
messages
in validation controls
order information
controls 2nd records 2nd 3rd in DISTINCT clause 2nd regional descriptions regional territories 2nd 3rd RegionID reports 2nd 3rd 4th 5th 6th 7th in Design view 2nd
ReportSource property 2nd 3rd with Crystal Report Viewer 2nd 3rd 4th 5th 6th 7th 8th 9th
SQL statements
in lables 2nd table results
tables
with Table control 2nd 2nd Windows NT/2000 domain users DisplayMember property DisplayMember property (list boxes) Dispose method DISTINCT clause records, displaying 2nd Distributed Management Framework.
[See DMF]
2nd
DMF
(Distributed Management Framework) APIs (Application Programming Interfaces) 2nd 3rd
DOC UMENT object
properties 2nd 3rd 4th 5th Document Object Model.
[See also XML, DOM]
DocumentElement (XMLDocument class)
documents
Report 2nd Name property, setting reports, exporting 2nd 3rd 4th reports, printing 2nd
XML
creating (code) 2nd 3rd 4th 5th creating with XMLTextWriter 2nd 3rd 4th creating with XMLWriter 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th data tables, creating 2nd
data, retrieving from SQL Server 2000 database 2nd 3rd 4th 5th 6th 7th datasets 2nd 3rd 4th 5th 6th 7th 8th 9th reading (code) 2nd
reading into datasets (code) reading with XMLReader 2nd 3rd 4th 5th 6th 7th 8th 2nd 3rd
reading with XMLTextReader (code) XMLTextWriter 2nd 3rd XML Web Services Discovery
DoesC ustomerIDExist function
code DOM.
[See also XML, DOM]
Page 614
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
domains Windows NT/2000
users, displaying 2nd double quotation marks ("") Drill Down reports
drilling
down to customer orders details down to data 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
DROP TABLE statement 2nd
DropDown control loading
code 2nd 3rd 4th 5th populating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th properties
DropDown object
properties 2nd 3rd
dsC ustomerIndividual dataset
records, adding (code) 2nd
dsC ustomers.xsd
Customers XSD, code 2nd
DTD SQL-DTD objects
tables, copying 2nd
DTS
(Data Transformation Services) 2nd
packages
tasks and workflows DTSPackage Object Library Dynamic type cursor 2nd
[ Tea m LiB ]
Page 615
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
Edit button
Edit command
code
edit mode
data grids, setting to (code) edit, remove SQL Server as subheading from servers main entry]
editing
data 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd command buttons
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th notifying users 2nd
data grids
cancelling (code) 2nd 2nd lookup table information records 2nd 3rd 4th canceling in DataGrid object (code) EditItemIndex
editors
Formula Editor displaying 2nd String Collection Editor 2nd
edits canceling
code element tags Ellipsis button 2nd
Enabled properties
on Windows forms 2nd 2nd 3rd 4th 5th enabled properties of buttons, toggling (code) EnableTightHorizontal property
enabling btnC onnection button
code 2nd Connect button
encoding
Unicode encrypted security ID (SID) END statement EndCurrentEdit method EndEdit method
engines
JET database engine
Enterprise Manager
Backup/Restore Wizard SQL Server authentication mode
error handling
with bound controls 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
error notices
ListAvailableSQLServer method ErrorMessage property
Page 616
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
errors
3621 of data, communicating to developers throwing 2nd unhandled Errors collection/Error object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
event handlers
code
for mFax variable
code
events
buttons in DataGrid control 2nd buttons on data grids 2nd
C heckC hanged
code 2nd
ItemC ommand
Repeater control events, programming
Load
code 2nd
of Repeater control
programming
SelectedIndexC hanged
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, adding routines, attaching
TextC hanged
code 2nd 3rd 4th wiring for DataGrid control (code) events.
[See also click events]2nd [See also click events]3rd [See also click events]
exception handling
code
exceptions
3621 error application ApplicationException catching (code) 2nd 3rd
errors, unhandled
InvalidC ustomerIDException
declaring (code)
InvalidPhoneNumberException
code
MaximumStringLengthExceededException
class declaration, code passing (code) 2nd
save
trapping (code) system trapping with Try[ellipsis dots]Catch[ellipsis dots]End Try block Try[ellipsis dots]Catch[ellipsis dots]Finally block Try[ellipsis dots]Catch[ellipsis dots]Finally blocks Execute button Execute method execute object permission ExecuteABatchCommand routine ExecuteReader method 2nd 2nd 2nd
executing
Page 617
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
actions on forms batch updates 2nd
2nd 3rd 4th 5th
bulk queries
code 2nd 2nd 3rd 4th 5th 6th on-the-fly batch updates in ADO.NET
parameterized stored procedures in ADO.NET 2nd 3rd 4th 5th 6th 7th 8th SQL Server stored procedures with ADO (ActiveX Data Objects) 2nd 3rd 4th
SQL statements
code 2nd 3rd 4th
stored procedures
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 2nd objects, properties and methods update statement EXIST statement expanding routines
Experts
(Crystal Reports)
experts
Formula Expert Mailing Labels Expert Standard Report Expert dialog box tabs Experts. 2nd
[See also Report Expert]
EXPLICIT mode Export button Export method
Export tab page objects
properties ExportDestinationType (ExportOptions object) ExportFormatType (ExportOptions object)
exporting data
with SQL-DTS files 2nd reports 2nd 3rd 4th 5th 6th 7th 8th 9th code 2nd
ExportOptions object 2nd DestinationOptions ExportDestinationType ExportFormatType FormatOptions
expressions
tables 2nd Extensible Markup Language.
[See XML]
extensions of files
.vb .xsd
[ Tea m LiB ]
Page 618
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] fields
adding in Report design as hyperlinks 2nd 3rd calculated, adding to reports 2nd 3rd 4th 5th defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th Details section of reports 2nd Formula
HTML hidden
definition in recordsets, updating in tables of mailing labels 2nd
primary
index functions 2nd primary key properties 2nd
Fields tab
Standard Report Wizard fields.
[See also columns]
2nd
file extensions
*.asmx
File menu commands
New
files
*.asmx extension .vb extension .xsd extension attaching to databases exporting 2nd 2nd 2nd
in databases
finding and attaching (code) 2nd
filling datasets
code 2nd 3rd 4th Letter Button result sets, code 2nd 3rd 4th 5th filling and binding products to DataGrid object (code) FillSchema method 2nd
Filter tab
Standard Report Wizard
filtering records
with DataView object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
finding customers
in combo boxes records 2nd 3rd 4th 5th 6th 7th 8th 9th 10th inner joins joins left outer joins 2nd
right outer joins 2nd
rows
code
Page 619
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
finding and attaching
database files, code finding. 2nd
[See also locating]
fixed database roles
db_accessadmin db_backupoperator db_datareader db_datawriter db_ddladmin db_denydatareader db_denydatawriter db_owner db_securityadmin public fixed database roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th
fixed server roles
bulkadmin dbcreator diskadmin processadmin securityadmin serveradmin setupadmin sysadmin fixed server roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th float data type (SQL Server) Flush (XMLTextWriter)
foreign keys
CustomerID column (Orders table) Form Letter reports Form reports Format dialog box FormatOptions (ExportOptions object) 2nd
formats
XML Web Services Wire Formats
formatting code
UDFs (user-defined functions) Formatting (XMLTextWriter) 2nd
forms
actions, executing 2nd
closing
code 2nd 3rd 2nd 2nd closing (code)
command buttons, accessing
controls
arranging 2nd 3rd bound at runtime properties, setting controls, arranging 2nd creating data bound 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd
frmHowTo1_9b
DataSet controls 2nd 3rd OleDataAdapter controls 2nd 3rd frmMain
Page 620
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
generic searches
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th 47th 48th 49th 50th 51st 52nd 53rd 54th 55th 56th 57th 58th 59th 60th 61st 62nd 63rd 64th 65th 66th 67th 68th 69th 70th 71st 72nd 73rd 74th 75th 76th 77th 78th 79th 80th 81st 82nd 83rd 84th 85th 86th 87th 88th 89th 90th 91st 92nd 93rd 94th 95th 96th 97th 98th 99th 100th 101st How-To 1.1, opening 2nd
loading
code 2nd loading (code)
login
XML Web Services authentication
objects
changes to 2nd
opening
code 2nd 3rd 4th 2nd 3rd 4th order information, displaying (code)
public variables, declaring (code) 2nd record sources, searching
records
loading into text boxes (code) 2nd 3rd
search
calling 2nd custom properties, creating (code) 2nd 3rd 4th 5th 6th 7th
SQL databases
backing up and verifying
tables
searching 2nd 3rd 4th TextBox control, populating 2nd unbound controls user options
Windows objects
using in Web forms forms.
[See also Windows forms]2nd [See also Windows Forms]3rd [See also Web Forms]
Formula Editor displaying 2nd Formula Expert Formula fields
formulas
adding tables 2nd Forward Only type cursor frameworks. Friend object
[See also DMF]
frmHowTo.vb
constructors, testing, code
frmHowTo1_1
data sets, filling (code)
frmHowTo1_2.vb
code 2nd
frmHowTo1_3 Label control
property settings 2nd 3rd 4th
TextBox control
property settings 2nd 3rd 4th
frmHowTo1_3.vb
Page 621
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
datasets
refreshing (code) 2nd
RefreshIndividual routine
calling (code) 2nd
RefreshIndividual subroutine
calls, code to add 2nd
frmHowTo1_4.vb ActiveEditing subroutine
calling (code) 2nd
data
canceling changes (code) saving to servers (code) 2nd 2nd
SaveRecord routine
calling (code) 2nd
text boxes
disabling (code) toggling (code) 2nd 3rd 4th 2nd
frmHowTo1_5.vb data
saving (code) 2nd
dsC ustomerIndividual dataset
records, adding (code) 2nd
edits
canceling (code) 2nd
list boxes
reloading (code) 2nd 3rd 4th 5th
mbAddNew variable
resetting (code) 2nd
records
deleting (code) 2nd 3rd
text boxes
toggling (code) 2nd 3rd 4th
frmHowTo1_6.vb btnSave click event
trapping save exceptions (code) 2nd
exceptions
catching (code) passing (code) 2nd 3rd 2nd
frmHowTo1_7.vb
enabled properties of buttons, toggling (code) forms, closing (code) 2nd 2nd 2nd 3rd 4th 5th
records, saving before closing (code)
frmHowTo1_8.vb DataGrid control
refreshing (code) 2nd
datasets
filling (code) 2nd 3rd 4th
frmHowTo1_9 forms
opening (code) 2nd
frmHowTo1_9b datasets
loading (code) 2nd
forms
DataSet controls 2nd 3rd OleDataAdapter controls 2nd 3rd
Page 622
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmHowTo10_4.vb reports
exporting (code) printing (code) 2nd
frmHowTo10_5.vb Selection combo box
populating (code) 2nd 3rd
SelectionFormula property
setting (code)
frmHowTo13_3.vb
passwords, validating (code) usernames, validating (code)
frmHowTo13_4.vb
datasets, retrieving from XML Web Services (code)
frmHowTo3_1.vb
list boxes, loading (code) 2nd 3rd
frmHowTo3_2.vb
list boxes, loading (code) 2nd
frmHowTo3_3.vb
ComboBox control, loading (code) records, locating (code) 2nd 2nd 2nd 3rd
text boxes, assigning values (code)
frmHowTo3_4.vb
button controls, adding click events (code) columns, sorting (code) 2nd 2nd 3rd
ComboBox control, adding column names (code) data tables, loading (code) 2nd 3rd
DataView object, setting RowFilter property (code)
2nd
frmHowTo6_1.vb
data, regenerating (code) forms, loading (code) SQL strings, building (code)
frmHowTo6_2.vb SQL statements
storing and executing (code) 2nd
frmHowTo6_3.vb
data, generating (code) 2nd 2nd 3rd GenerateData routine, calling (code)
frmHowTo6_4.vb
left outer joins, code frmHowTo6_5.vb
SQL statements
loading and executing
frmHowTo6_6.vb
PerformTask( ) function, calling (code) SQL statements, executing (code) SQL statements, loading (code) 2nd 2nd 3rd
frmHowTo6_7.vb
forms, loading (code) 2nd SQL statements, storing (code) 2nd
frmHowTo6_8.vb UDFs (user-defined functions)
assigning (code) creating (code) 2nd 2nd 3rd 4th 5th
data, displaying (code) SELECT statement, updating (code) 2nd
Page 623
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmHowTo7_1.vb btnC onnection button
disabling (code) enabling (code) 2nd 2nd 2nd 3rd 4th
database list boxes, loading (code) list boxes, repopulating (code)
routines
calling (code) 2nd 3rd 2nd list boxes, reloading (code)
SQL Servers
loading (code) 2nd
frmHowTo7_2.vb
1stBackupDevices list box, populating (code) 1stDatabases list box, populating (code) backups, performing (code) 2nd 3rd 4th 5th 6th 7th
routines
SQL Servers, loading (code)
frmHowTo7_3.vb
1stBackupDevices list box, populating (code) 1stDatabases list box, populating (code) backups, performing (code) routines, calling (code) SQL Servers, loading (code) frmHowTo7_4.vb 1stBackupDevices list box, populating (code) 1stDatabases list box, populating (code) forms, closing (code) routines, calling (code) SQL Servers, loading (code) tables, copying (code) 2nd 3rd 4th 5th 2nd 2nd 2nd 3rd
frmHowTo7_5.vb
1stDatabases list box, populating (code) btnDetach button, toggling (code) database files, finding and attaching (code) forms, closing (code) routines, calling (code) SQL Server database, detaching (code) SQL Server databases, attaching (code) SQL Servers, loading (code) 2nd 2nd 2nd
frmHowTo8_1.vb 1stUnSelected list box
reloading (code)
list boxes
populating (code) 2nd 3rd 4th 5th 6th 2nd list boxes, loading categories (code)
routines
calling (code)
servers
updating (code) 2nd 3rd 4th 5th 6th
frmHowTo8_2.vb 1stLookupTables
pointing to items (code) 2nd
connection strings
establishing (code) 2nd
DataGrid control
populating (code) 2nd 3rd 4th 5th
Page 624
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
frmHowTo8_3.vb columns
listing in databases (code) DataGrid control, loading (code) SQL strings, creating (code) 2nd stored procedures, executing (code) 2nd 3rd 4th 5th 2nd
tables
listing in databases (code) 2nd 3rd
frmHowTo8_4.vb
search forms, creating custom properties (code) stored procedures, executing (code) 2nd
tables
listing in databases (code) frmHowTo8_4a.vb Letter Button result sets, filling (code) 2nd
records
loading into text boxes (code) 2nd 3rd
frmHowTo8_4b.vb
DialogResult, setting (code) key values, storing (code) 2nd 2nd
Letter Button controls, click events (code) search forms, creating custom properties (code) stored procedures, executing (code) 2nd 3rd
tables
listing in databases (code)
frmHowTo8_6.aspx data grids
page indexes, updating (code) records, deleting (code) records, posting (code) 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
data tables
records, adding (code) 2nd 3rd
DataGrid object
records, canceling editing/adding (code) special instructions (code)
DataTable object
tracking (code) 2nd 3rd 4th 5th
frmHowTo8_7.vb columns
listing in databases (code) 2nd
DataGrid control
loading (code) 2nd 3rd
SQL strings
creating (code) 2nd 3rd 4th 2nd 3rd 4th stored procedures, executing (code)
tables
listing in databases (code) 2nd
frmHowTo8_8a.vb
Letter Button result sets, filling (code) 2nd
records
loading (code) 2nd 3rd
Session object
values, storing (code)
frmHowTo8_8b.vb
calling pages, returning to (code) 2nd
data grids
Page 625
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
updating (code) key values, storing (code) 2nd
Letter Button controls, click events (code) stored procedures, executing (code)
tables
listing in databases (code)
frmHowTo9_2.vb C C ustomer class
code 2nd property declarations (code) class variable declarations (code)
C ustomer class
code property declarations (VB .NET code) property declarations (VB 6 code)
TextBoxC hange method
text boxes, writing values (code) TextChanged event (code) 2nd
ToString method
property information output (code) 2nd
frmHowTo9_4.vb
CCustomer class, constructors (code) 2nd 2nd ReadValuesFromDataRow method, code
frmHowTo9_5.vb
Clear method, code 2nd
constructors
rows, inserting into tables (code) constructors, testing (code) Delete method, implementing (code) Delete method, testing (code) Save method, implementing (code) Save method, testing (code) WriteChangesToDB method, code 2nd 2nd 3rd 4th 5th
frmHowTo9_6
ContactName property, code InvalidPhoneNumberException, code
MaximumStringLengthExceededException
class declaration, code phone numbers, validating (code) 2nd 3rd
frmHowTo9_6.vb
DoesCustomerIDExist function (code) If[ellipsis dots] Then block (code) InvalidCustomerIDException, declaring (code) ValidateCustomerID method (code)
frmHowTo9_7.vb
event handlers, code frmMain form
frmMain.vb ADO connections
opening and displaying (code)
forms
opening (code) 2nd
routines
calling (code)
functions
BuildCnnStr 2nd
Page 626
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BuildCnnStr( ) 2nd
built-in
T-SQL 2nd CType( )
DateDiff
Days_to_Ship, displaying DateDiff( ) Days_to_Ship, displaying
DoesC ustomerIDExist
code In-Line of indexes 2nd 2nd
PerformTask( )
calling (code) scaler T-SQL commands 2nd 3rd 4th 5th 6th Table Trim 2nd 3rd
UDFs
(user-defined functions) calling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, formatting 2nd
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th parameters, passing scalar types, returning 2nd table types, returning 2nd userk-defined functions.
[See also UDFs]
[ Tea m LiB ]
Page 627
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] General properties
in DataGrid control, setting 2nd General tab (DataGrid Property Builder) Generate Dataset command (pop-up menu) Generate Dataset dialog box Generate the SQL Statements page (DataAdapter Configuration Wizard) 2nd 2nd
GenerateData routine
calling code creating 2nd 3rd
generating data
code 2nd
generic search forms
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th 47th 48th 49th 50th
GetBackupDevices routine
creating GetPageNum( ) routine GetPageRows( ) routine GetSQLDatabases routine 2nd creating
GetString Display records
displaying 2nd 3rd GetString method 2nd GetUserInfo method 2nd
grant access level (object permissions) grant state (statement permissions)
Grid pane (View Designer)
properties
grids data
sorting, setting 2nd grids.
[See also data grids]
2nd
Group By property Group Name text box
Group tab
Standard Report Wizard
Groupbox object
properties
GroupBox object
properties
groupings
reports 2nd
groups
creating for Windows NT/2000 Names list 2nd 2nd 3rd 4th 5th 6th
[ Team LiB ]
Page 628
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
handlers.
[See event handlers]
handling exceptions
code
headers customer orders
information, displaying 2nd Hello World method, testing 2nd
help
.NET Framework Developer's Guide
hidden fields (HTML)
definition How-To 1.1 form, opening 2nd
how-to's
database, design view 2nd
HTML
(Hypertext Markup Language)
code
repRegions Repeater control repTerritories Repeater control
controls
and Web server controls, comparing 2nd
hidden fields
definition
http[colon, no spaces]//localhost/WebService1/Service1.asmx?WSDL
XML Web Services, SOAP definition (code) 2nd 3rd 4th 5th HyperLink columns
HyperLink control
properties
Hyperlink control
properties
Hyperlink object
properties
HyperLink object
properties 2nd
Hyperlink object
properties 2nd
HyperLink object
properties
Hyperlink object
properties 2nd 3rd 4th 5th 6th 7th 8th
hyperlinking
in data grids, from rows to detail pages 2nd 3rd 4th 5th 6th 7th
hyperlinks
action options 2nd BorderColor property BottomLineStyle property detail pages 2nd
EnableTightHorizontal property on-screen reports 2nd 3rd 4th 5th 6th fields as hyperlinks 2nd 3rd Web site fields, adding real-time 2nd 2nd
Page 629
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
regional descriptions, displaying Hypertext Markup Language.
[See HTML]
[ Team LiB ]
Page 630
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] icons
Server Explorer Server Roles toolbox 2nd
IC ustomer interface
code
properties
code Identity property
IDs
CustomerID column (Customers table) CustomerID column (Orders table) RegionID, displaying SID (encrypted security ID) IF statement 2nd 2nd
If[ellipsis dots] Then block
code image data type (SQL Server)
implementing
intertaces 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th Implements ICustomer.[Property/Method Name] In-Line function 2nd
indexes
compound constraints
creating
with Property Pages dialog box 2nd
data grid pages
updating (code) 2nd defining 2nd 3rd 4th 5th 6th 7th 8th 9th functions 2nd performance 2nd 2nd
Indexes/Keys command (View menu)
indices
Items (index) collection SelectedIndices (index) collection
information
retrieving from data grids 2nd
infrastructures
XML Web Services 2nd 3rd
inheritance
definition inheritance permission keywords of classes 2nd
initializing local variables
in T-SQL 2nd
Web pages
code 2nd 3rd
inner joins
records 2nd 3rd 4th 5th 6th records, finding inner joins (tables)
Page 631
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
insert object permission
inserting
records
instances of classes
definition int data type (SQL Server)
integrity
referential (database tables) 2nd 3rd
interfaces classes
defining creating
C ustomerInterface9_1.vb
code 2nd delete method, declaring (code) ReadOnly keyword, code save method, declaring (code)
IC ustomer
code properties (code) implementing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 2nd 3rd
methods, adding properties, adding XML Web Services
international phone number extensions
code 2nd
interpreting
null valuees
InvalidC ustomerIDException
declaring (code)
InvalidPhoneNumberException
code Invoke button IsPostBack property 2nd
IsValid method declaring
code IsValid property
ItemC ommand event
Repeater control events, programming Items (index) collection
Items collection
data, adding
[ Team LiB ]
Page 632
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] JET databases
opening (code) JET database engine 2nd
joining
taables 2nd
joins inner
records 2nd 3rd 4th 5th records, finding reords inner (tables)
left outer
code records, finding 2nd records, finding
right outer
records, finding 2nd
[ Team LiB ]
Page 633
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
key values, storing (code) 2nd 3rd 4th
keys Delete
clicking, effects
primary
defining 2nd 3rd 4th 5th 6th 7th 8th 9th keys.
[See primary keys]2nd [See also foreign keys]
keywords
class inheritance permissions 2nd Default member override MustInherit 2nd abstract classes MustOverride Nothing NotInheritable NotOverrideable Overrideable Overrides 2nd 2nd
ReadOnly
code
[ Team LiB ]
Page 634
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] Label control
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th settings 2nd 3rd 4th settings for frmHowto_3 2nd 3rd 4th
property settings 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
Label object
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th property property settings 2nd Text property
Label, TextBox, and C ommand button
control property settings 2nd
Label, TextBox, ListBox, and C ommand button
property settings 2nd
labels lblSQLString
SQL statements, storing (code) 2nd
mailing
appearance control 2nd creating 2nd 3rd fields 2nd sorting 2nd printing 2nd 3rd 4th 5th 6th 7th 8th
SQL statements
displaying 2nd loading (code) 2nd
UDFs (user-defined functions)
assigning (code) languages. 2nd 3rd
[See also XML]2nd [See also HTML]3rd [See also WSDL]
LANs
(local area networks)
lblSQLString label SQL statements
storing (code) 2nd left (<) left arrow button
left outer joins
code records, finding 2nd Length property
Letter Button controls click events
code 2nd Letter Button result sets, filling (code) 2nd 3rd 4th
letters
data, displaying in DataGrid control 2nd
levels of access
deny (object permissions) grant (object permissions) revoke (object permissions)
librariees
DTSPackage Object Library
Page 635
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
libraries
accessing COM type, registering SQLDMO Object Library
type
referencing with ADO (ActiveX Data Objects) 2nd 3rd
licensing
Crystal Reports
LIKE statement
data, generating (code) 2nd
lines
wavy blue (code)
linking
Web pages
list boxes 1stBackupDevices
populating (code) 2nd 3rd 4th
1stDatabases
populating (code) 2nd 3rd 4th 5th
1stUnSelected
reloading (code) 2nd
1stUnselected
reloading (code) 2nd
categories
loading (code) 2nd 3rd 4th 5th
data
loading 2nd
data-bound multi-select
data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th
databases
loading (code) 2nd DataSource property DisplayMember property loading (code) 2nd 3rd 4th 5th
lstSQLServers
code
multi-select
on Web Forms 2nd
populating
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
reloading
code 2nd 3rd 2nd reloading (code)
repopulating (code) Selected Products ListBox control
SelectedIndexC hanged event
code 2nd 3rd 4th 5th
SQL Servers
loading (code) 2nd 3rd 4th 5th 6th 7th 8th 9th
text boxes
binding 2nd binding and viewing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Unselected Products ListBox control ValueMember property
Page 636
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ListAvailableSQLServer method error notice
ListBox control
loading populating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th properties 2nd 3rd 4th 5th setting to bind DataSet control 2nd settings 2nd 3rd 4th property settings 2nd 3rd 4th 5th 6th 7th
ListBox controls
properties 2nd
ListBox object
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th property ListBox Web server control ListBox Windows Forms control
ListBox1 frmHowTo1_1
data sets, filling (code)
listing columns in databases
code 2nd 3rd 4th
customer information
code
SQL Servers
in SQL-DMO 2nd
tables in databases
code 2nd 3rd 4th 5th 6th 7th 8th
lists
based on Customers table database, refreshing 2nd look of in ValidationSummary control
Names
groups and users 2nd region descriptions, displaying RegionID, displaying Tables in Report list 2nd
territories, displaying 2nd 3rd lists.
[See also bound list boxes]
2nd
Load event
code Load List button 2nd 3rd
LoadIndividual routine
creating 2nd creating (code) 2nd 3rd
loading categories
into list boxes (code) 2nd 3rd 4th 5th
C omboBox control
code 2nd 3rd
data
into list boxes 2nd
data tables
code 2nd 3rd
database list boxes
code 2nd 3rd 4th
Page 637
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
DataGrid control
code 2nd 3rd loading DataGrid object (code) 2nd
datasets
code 2nd
DropDown control
code 2nd 3rd 4th 5th
forms
code 2nd 3rd 4th
list boxes
code 2nd 3rd 4th 5th ListBox control ProductID detail information (code) 2nd
records
into text boxes (code) 2nd 3rd 4th 5th 6th
repRegion Repeater control
code
repTerritories Repeater control
code
schemas
into data tables 2nd
SQL Servers
code 2nd 3rd 4th 5th 6th 7th 8th 9th
SQL statements
code 2nd
Table control
code 2nd 3rd 4th 5th
Web pages
code 2nd
LoadList routine
creating (code) 2nd
LoadProducts routine calling
code
LoadSelectedProducts routine
creating 2nd LoadSQLServers routine 2nd LoadSQLString routine LoadTables( ) subroutine
LoadUnSelectedProducts routine
creating LoadUnSelectedProducts subroutine LoadUnUnselectedProducts subroutine LoadXML (XMLDocument class) local area networks.
[See LANs]
local databases
ADO (ActiveX Data Objects) 2nd
local variables declaring
in T-SQL 2nd
initializing
in T-SQL 2nd Locate File button
locating records
Page 638
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
code 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th
with DataTable object
login forms
XML Web Services authentication
logins databases
using Windows NT Integrated Security standard, creating 2nd 3rd 4th 5th Windows NT/2000 2nd 3rd 4th 5th 6th
lookup tables
data, adding 2nd 2nd information, managing updating 2nd data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st
22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th loosely coupled messages, definition
lstSQLServers list box
code
[ Tea m LiB ]
Page 639
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M ] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
m (adding to code) Mail Labels reports
mailing labels
appearance control 2nd creating 2nd 3rd fields 2nd sorting 2nd Mailing Labels Expert
Main forms
frmMain
management state
on clients server-side solutions 2nd 3rd 4th 5th Session object 2nd 3rd 4th
managers Enterprise Manager
Backup/Restore Wizard SQL Server authentication mode manipulating data 2nd
many-to-many relationship (tables)
mapping
Table Mappings collection 2nd markup languages.
[See also XML]2nd [See also HTML]
MaximumStringLengthExceededException
class declaration, code
mbAddNew variable resetting
code 2nd
mdtProducts DataTable object rows
finding (code)
members of classes
definition
message boxes
displaying
messages displaying
in validation controls loosely coupled, definition
methodds
AddNew BeginEdit MustOverride keyword RejectChanges
methods
AcceptChanges AcceptChanges method Add adding to interfaces 2nd 3rd AddNew
Page 640
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
AddObjectForTransfer Application object AttachDBWithSingleFile 2nd AttributeCount Backup object BackupDevice object BackupDevices object BeginLoadData
C lear
code Close Command object CommandBuilder object Connection object CustomTask object data, handling 2nd 3rd 2nd
DataAdapter object 2nd 3rd DataAdapter Update database updates DataBind Databind DataColumn object DataReader object datareader.Read( ) DataRow object DataSet object DataTable object 2nd 3rd 4th 5th 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
DataTable.Columns object DataTable.Rows object 2nd
DefineValidC hars
declaring (code) Delete 2nd
delete
declaring (code)
Delete
implementing implementing (code) testing (code) descriptions 2nd DetachDB 2nd Dispose EndCurrentEdit EndEdit Execute ExecuteReader Export FillSchema 2nd GetString 2nd GetUserInfo 2nd Hello World, testing 2nd Implements ICustomer.[Property/Method Name] 2nd 2nd
IsValid
declaring (code) ListAvailableSQLServer error notice NodeType
Page 641
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
of objects
executing stored procedures 2nd
overloaded
code overloading 2nd
Option Strict overrideable Package object Page.Validate PrinterToPrinter QueryResults object Read 2nd
ReadBackupHeader ReadValuesFromDataRow code 2nd 2nd
RefreshReport RejectChanges RemoveAt Restore object Save 2nd
save
declaring (code)
Save
implementing implementing (code) testing (code) 2nd 3rd 4th 5th 6th 7th
signature
definition SQLBackup SQLRestore SQLServer object Step object Task object TestUserPassword 2nd 3rd
TextBoxC hange
text boxes, writing values (code) 2nd
ThrowException
declaring (code) ToString property information output (code) update Update 2nd 3rd
UpdateCommand Validate
ValidateC ustomerID
code Value 2nd
WebMethod
passwords, validating (code) usernames, validating (code) 2nd 2nd
WriteC hangesToDB
code 2nd XML Web Services calling 2nd XML Web Services Description XMLDocument
Page 642
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XMLDocument class XMLNode XMLNode class XMLTextWriter 2nd
mFax variable event handlers
code Microsoft Office 200x minus sign (-) mixed-mode authentication
models
XML DOM (Document Object Model) models. 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
[See also object models]
modes authentication
Windows NT/2000 AUTO 2nd 3rd 4th 5th 6th 7th 8th
edit
data grids, setting to (code) EXPLICIT mixed-mode authentication RAW modGeneralRoutines.vb 2nd 3rd 4th
connection strings
creating (code) 2nd 3rd 4th connection strings, creating (code) 2nd 3rd 4th 5th
modifiers
Public access 2nd VB .NET properties
modifying
tables 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th ALTER TABLE statement 2nd modPublicVariables.vb public variables, declaring (code)
modSQLDMORoutines.vb
backup device names, retrieving (code) connection strings, creating (code) 2nd database names, retrieving (code) 2nd 3rd
SQL Servers
loading (code) 2nd money data type (SQL Server)
multi-select list boxes
on Web Forms MustInherit keyword abstract classes MustOverride keyword 2nd 2nd
[ Tea m LiB ]
Page 643
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
Name property
names
of backup devices, retrieving (code) of databases, retrieving (code) 2nd 3rd
Names list
groups and users 2nd
namespaces .NET
bound list boxes, creating 2nd 3rd 4th 5th XML (Extensible Markup Language) System.XML System.XML.Schema System.XML.Xpath System.XML.XSL Visual Basic XML Web Services 2nd namespaces. 2nd
[See also SQL-NS]
naming
objects
reports
with rptReportName Web Forms nchar data type (SQL Server)
networks LANs
(local area networks) New command (File menu) New Connection button New Database Role command (shortcut menu) New Database User command (shortcut menu) New Group command (Action menu) New Group dialog box 2nd
New Login command (Actions menu) New Login command (context menu) New Login command (shortcut menu) New Prject dialog box New Role dialog box NodeType method 2nd 3rd 4th
Northwind connections
creating 2nd Unassigned Products Only check box
Northwind database customers
demographics, tracking Orders table Web site fields, adding 2nd
Northwind SQL Server database
Customers table list CustOrdersHist stored procedure, T-SQL code Nothing keyword NotInheritable keyword
Page 644
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
NotOverrideable keyword ntext data type (SQL Server)
NULL
columns records
null values
Allow Nulls null values, interpreting number sign (#)
numbers phone
validating (code) 2nd 3rd numeric data type (SQL Server) nvarchar data type (SQL Server)
[ Team LiB ]
Page 645
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] object C omboBox
properties
DataGrid
properties
Label
properties Object Browser
object models ADO
(ActiveX Data Objects) 2nd
ADODB
(ActiveX Data Objects 2.7 object model) 2nd 3rd
object permissions
delete deny access level execute grant access level insert revoke access level select update object permissions (SQL Server security) 2nd 3rd 4th 5th 6th
object-based constructors
for CCustomerID class (code) 2nd
objects
ADO.NET 2nd 3rd 4th 5th 6th 7th 8th 9th
Application
methods properties Backup 2nd methods properties
BackupDevice
methods properties
BackupDevices
methods properties BindingContext 2nd BindingManagerBase 2nd
Button
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th
C heckBox
properties 2nd 3rd
C omboBox
properties 2nd 3rd 4th property settings 2nd Command 2nd 3rd
actions, executing with SQL statements 2nd methods
Page 646
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
properties TextBox control, populating with stored procedures 2nd
C ommand Button
properties 2nd 3rd 4th 5th 6th
C ommandBuilder
methods properties CommandBuilider
C ompareValidator
properties Connection 2nd
ADO (ActiveX Data Objects) 2nd 3rd 4th 5th methods properties constructors creating 2nd with SQL syntax
C rystalReportViewer
property settings 2nd
C ustomTask
methods properties data, handling DataAdapter methods 2nd 3rd 2nd 3rd
properties 2nd 3rd DataColumn methods properties DataDefinition
DataGrid
loading (code) 2nd 2nd products, filling and binding (code)
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st records, canceling editing/adding (code) setting to edit mode (code) special instructions (code) DataReader data, retrieving 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th list boxes, loading (code) methods properties DataRow methods 2nd 2nd 3rd
properties 2nd DataRowView DataSet data, editing methods passing (code) properties 2nd 3rd 4th 5th 6th 7th 8th rows, adding rows, deleting DataTable ComboBox control, loading (code) creating (code) 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
2nd 3rd 4th 5th 6th
Page 647
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
list boxes, loading (code) methods objects 2nd
2nd 3rd 4th 5th 2nd 3rd
properties 2nd 3rd 4th 5th records, locating 2nd 3rd 4th 5th 6th 7th 8th 9th SQL Server, retrieving results 2nd 3rd 4th 5th 6th tracking (code) DataTable object 2nd 3rd 4th 5th
2nd 3rd
DataTable.C olumns
methods properties
DataTable.Rows
methods 2nd properties 2nd DataView records, filtering 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th records, sorting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th RowFilter property, setting (code) 2nd
DateTimePicker
properties definition
DOC UMENT
properties 2nd 3rd 4th 5th
DropDown
properties 2nd 3rd DTSPackage Object Library Errors collection/Error ExportOptions 2nd DestinationOptions ExportDestinationType ExportFormatType FormatOptions Friend
Groupbox
properties
GroupBox
properties
Hyperlink
properties
HyperLink
properties 2nd
Hyperlink
properties 2nd
HyperLink
properties
Hyperlink
properties 2nd 3rd 4th 5th 6th 7th 8th
Label
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th property settings 2nd Text property
ListBox
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
mdtProducts DataTable
rows, finding (code)
Page 648
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
methods
for executing stored procedures 2nd
OldDBC ommand
CommandText property
OleDataAdapter
properties 2nd 3rd 4th 5th OleDb and SQLClient, comparing OleDbCommandBuilder OleDbDataAdapter properties 2nd 3rd on forms, changes to 2nd
Package
methods properties
Panel
properties 2nd 3rd Parameter PrimaryKey
PrintOptions
properties Private
properties
for executing stored procedures 2nd Protected Protected Friend Public QueryResults methods properties
Radio Button
properties
RadioButton
properties
RangeValidator
properties ReadOnly Recordset 2nd
ADO (ActiveX Data Objects) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
RegularExpressionValidator
properties
Repeater
properties
RequiredFieldValidator
properties Restore 2nd 2nd
methods
properties 2nd
Session
.NET Framework Developer's Guide Nothing keyword values, storing (code)
SQL Server
creating (code) creating with ADO (ActiveX Data Objects) 2nd 3rd 4th SQL-DMO 2nd 3rd 4th 5th 6th 7th 8th (SQL-Distributed Management Objects)
Page 649
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
databases, backing up and verifying 2nd
SQL-DTD
tables, copying 2nd
SQL-DTS
data, exporting SQLDMO Object Library
SQLServer
methods properties
state management
values, storing Step methods properties Stream
Table
properties
TableC ell
properties
TableRow
properties Task methods properties
TextArea
properties 2nd TextBox 2nd
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd
ValidationSummary
properties
values
storing
Windows forms
using in Web forms WriteOnly XML DOM (Document Object Model) objects. 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
[See also SQL Server database objects]2nd [See also ADO]3rd [See also RDO]4th [See also DAO]
objectscommand buttons
properties
objets
naming
OldDBC ommand object
CommandText property
OLE DB (ADO) data provider
choosing 2nd 3rd 4th OLE DB (ADO) dialog box
OleDataAdapter controls
for frmHowTo1_9b forms 2nd 3rd
OleDataAdapter object
properties 2nd 3rd 4th 5th
OleDb classes
performance improvement 2nd
OleDb objects
and SQLClient objects, comparing
OleDbC ommand
Page 650
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
(data control) OleDbCommandBuilder object
OleDbC onnection
(data control)
OleDbDataAdapter
(data control) ? (question mark) controls 2nd OleDbDataAdapter object properties 2nd 3rd
on-screen reports
fields as hyperlinks 2nd 3rd Web site fields, adding 2nd
on-screen reports, creating with hyperlinks 2nd 3rd 4th 5th 6th
on-the-fly batch updates
creating in ADO.NET 2nd 3rd 4th 5th 6th executing in ADO.NET 2nd 3rd 4th 5th 6th one-to-many relationship (tables) one-to-one relationship (tables) Open a Recordset button OpenAndDisplayADOConnection routine OpenFileDialog control 2nd
opening ADO connections
code 2nd
forms
code 2nd 3rd 4th 2nd How-To 1.1 form
JET databases
code 2nd Property Pages dialog box
recordsets
code 2nd 3rd 4th OpenNorthwindADOConnection subroutine
operators BETWEEN
syntax 2nd Option Strict (overloaded methods) Or property
order information
controls to display 2nd
OrderID
values 2nd
orders
details, drilling down to
information
displaying (code) Orders table CustomerID column 2nd 2nd 3rd 4th
organizing reports
groupings 2nd Output property
overloaded methods
code
overloading
Page 651
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
methods 2nd
Option Strict Overrideable keyword overrideable methods Overrides keyword 2nd
overriding
member overriding keywords 2nd
[ Tea m LiB ]
Page 652
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] Package object
methods properties
packages DTS
tasks and workflows 2nd
page indexes updating
in data grids (code) Page.IsValid property Page.Validate method
PageIndexC hanged command
code
pages calling
returning to (code) 2nd 3rd
detail
hyperlinks 2nd rows, hyperlinking to 2nd 3rd 4th 5th 6th 7th
tab
controls 2nd
Paging properties
setting for DataGrid control 2nd Paging tab (DataGrid Property Builder)
paging through data grids
code
paging through data
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Panel object
properties 2nd 3rd
panes
Diagram (View Designer)
Grid (View Designer)
properties Results (View Designer) SQL (View Designer) Parameter object
parameterized properties
classes, defining code
parameterized stored procedures
executing in ADO.NET 2nd 3rd 4th 5th 6th 7th 8th
parameters
at symbol (@) 2nd
frmHowTo1_2.vb
code 2nd
passing
UDFs (user-defined functions) XML Web Services, creating 2nd
stored procedures
calling (code) 2nd 3rd
Page 653
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XML Web Services
creating 2nd 3rd 4th 5th 6th 7th descriptions 2nd methods, descriptions 2nd parameters, passing 2nd security tables 2nd
parent records
cascade deletes
passing DataSet object
code
datasets
from XML Web Services 2nd 3rd 4th 5th 6th 7th 8th exceptions (code) 2nd
parameters
UDFs (user-defined functions) XML Web Services, creating 2nd
passwords validating
code 2nd Paste command (pop-up menu) percent sign (%) Perform Backup button
performance
of indexes 2nd
performance improvement
OleDb classes 2nd SQLClient classes 2nd
performing
backups, code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
PerformTask( ) function calling
code 2nd 3rd
permissions
class inheritance permission keywords 2nd
object
delete deny access level execute grant access level insert revoke access level select update object (SQL Server security) 2nd 3rd 4th 5th 6th
statement
deny state grant state revoke state statement (SQL Server security) 2nd 3rd 4th 5th 6th 7th Permissions button 2nd Permissions tab (Database Role Properties dialog box) Permissions tab (Table Properties dialog box) 2nd 2nd
persistence
Table control
persisting
Page 654
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
recordsets 2nd 3rd 4th
recordsets to disks
code 2nd persisting records
phone number extensions
code
international
code
phone numbers validating
code 2nd 3rd
PhoneDatatypes.vb C NumberString class
code 2nd CNumberString class, code DefineValidChars method, declaring (code)
event handlers
code IsValid method, declaring (code)
phone number extensions
code international (code)
StringValue property
code ThrowException method, declaring (code) plus sign (+) 2nd
point-and-click query tool
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
point-and-click SQL Server query tool
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
point-and-click Web form
property settings
pointers
classes
points break
setting in stored procedures 2nd
pop-up menu commands
Copy Generate Dataset Paste Run as Server Control 2nd
populating
1stBackupDevices list box, code 1stDatabases list box, code 2nd 3rd 4th 2nd 3rd 4th 5th
DataGrid control
code 2nd 3rd 4th 5th DropDown controls 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
list boxes
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 2nd repopulating (code)
ListBox controls 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
Selection combo box
code 2nd 3rd TextBox control 2nd
posting
Page 655
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
records
in data grids (code) pound sign (#) 2nd 3rd 4th 5th 6th 7th 8th
primary key field
index functions 2nd
primary keys
CustomerID column (Customers table) 2nd defining 2nd 3rd 4th 5th 6th 7th 8th 9th field in tables PrimaryKey object Print button 2nd
Print tab page objects
properties
printing
labels 2nd 3rd 4th 5th 6th 7th 8th records 2nd 3rd 4th 5th 6th 7th 8th reports 2nd 3rd 4th 5th 6th 7th 8th 9th at run-time code options, setting 2nd SelectionFormula syntax 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
PrintOptions object
properties PrintToPrinter method Private declarations Private object
procedures stored
creating procedures.
[See also stored procedures]2nd [See stored procedures]
2nd
processadmin (fixed server role) ProdAndCatTab table
ProductID
detail information, loading (code) 2nd
products
filling and binding to DataGrid object (code) LoadUnSelectedProducts subroutine LoadUnUnselectedProducts subroutine Selected Products ListBox control
Table control
loading (code) loading;code 2nd 2nd 3rd 4th 5th 6th 2nd
Unassigned Products Only check box Unselected Products ListBox control
programming
Repeater control events stateless (Web pages) clients, state management 2nd 2nd 3rd 4th 5th
server-side solutions, state management Session object 2nd 3rd 4th
Project menu commands
Add Reference 2nd Add Web Reference
projects
XML Web Services
Page 656
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
propertes
controls properties 2nd 3rd 4th 5th Action adding to interfaces Allow Nulls Anchor Application object AutoIncrement AutoPostBack Backup object BackupDevice object BackupDevices object BorderColor BottomLineStyle Button control 2nd 3rd 4th 5th 6th Button object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th buttons 2nd CheckBox object Column Name columns, binding to controls 2nd Combo control 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd 3rd 4th 5th 6th 7th 2nd 3rd
ComboBox control ComboBox object Command button
Command Button control Command Button object command buttons Command Object Command object CommandBuilder object CommandText CommandText, accessing CompareValidator object Connection object
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 2nd 3rd 4th 5th 6th
2nd
C ontactName
code
control settings
Label, TextBox, and Command button 2nd
C ontrol.ViewState
definition controls 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st CrystalReportViewer control 2nd CrystalReportViewer object 2nd
C ustomerID
code CustomTask object data, handling 2nd 3rd
DataAdapter object 2nd 3rd Database DataColumn object DataformatString DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th DataGrid object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd
DataGrid Property Builder
Page 657
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
General tab DataReader object DataRow object DataSet object DataSource DataSource (list boxes) DataTable object 2nd 3rd 4th 5th 2nd 2nd 3rd 4th 5th 6th 7th 8th
DataTable.Columns object DataTable.Rows object DataTextField DataType DataValueField DateTimePicker object 2nd
default
classes, defining declaring (code) in VB 6 (code) Devices DisplayMember DisplayMember (list boxes) DOCUMENT object DropDown control DropDown object 2nd 3rd 2nd 3rd 4th 5th 2nd
enabled
of buttons, toggling (code) 2nd 3rd 4th 5th
Enabled
on Windows forms EnableTightHorizontal ErrorMessage 2nd
General
setting in DataGrid control 2nd Grid pane (View Designer) Groupbox object GroupBox object HyperLink control Hyperlink control Hyperlink object HyperLink object Hyperlink object HyperLink object Hyperlink object 2nd 3rd 4th 5th 6th 7th 8th 2nd 2nd
IC ustomer interface
code Identity Implements ICustomer.[Property/Method Name] IsPostBack 2nd IsValid Label control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd settings for frmHowto_3 Label object Label Object Label object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 2nd 3rd 2nd 3rd 4th 2nd
25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th Length ListBox control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
Page 658
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
ListBox controls 2nd ListBox object ListBox Object ListBox object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th Name of buttons, setting of columns 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th
of Command button of controls 2nd setting of controls, setting of fields
of Label control 2nd 3rd 4th of Label, TextBox, ListBox, and Command button of ListBox control 2nd 3rd 4th setting to bind DataSet control 2nd 2nd
of objects
executing stored procedures 2nd of tables 2nd 3rd 2nd 3rd 4th
of TextBox control
OleDataAdapter object 2nd 3rd 4th 5th OleDbDataAdapter object 2nd 3rd Package object Page.IsValid Panel object 2nd 3rd
parameterized
classes, defining code point-and-click Web Forms PrintOptions object QueryResults object Radio Button object RadioButton object RangeValidator object
read-only
classes, defining 2nd ReadOnly RegularExpressionValidator object Repeater control Repeater object ReplaceDatabase ReportSource 2nd 3rd 4th RequiredFieldValidator object Restore object RowFilter setting for DataView object (code) RowStateFilter SelectedIndices.Count 2nd 2nd
SelectionFormula
setting (code) SelectionMode settings for controls Sort DESC SQLServer object Step object 2nd
Page 659
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
StringValue
code Table control Table object TableCell object TableRow object TabPages Task object
Text
of Label object setting validation controls TextArea object 2nd
TextBox control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th settings for frmHowto_3 TextBox object TextBox Object TextBox object 24th 25th 26th ValidationExpression ValidationSummary object ValueMember ValueMember (list boxes) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 2nd 3rd 4th
2nd 3rd 4th 5th
VB .NET
modifiers Web Form validation controls 2nd 3rd 4th 5th 6th 7th 8th
write-only
classes, defining 2nd WriteOnly XMLDocument XMLDocument class XMLNode XMLNode class XMLTextWriter 2nd Properties command (Action menu) Properties command (context menu) Properties dialog box Windows Only option 2nd
Properties window
CommandText property, accessing 2nd
propertis
Alias Column Criteria Group By Or Output Sort Order Sort Type Table Property Builder dialog box
property declarations of C C ustomer class
code
property information output of ToString method
Page 660
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
code 2nd
Property Pages dialog box
indexes, creating opening Protected Friend object Protected object providers. 2nd
[See data providers]
public (fixed database role) Public access modifiers 2nd Public object
public variables
declaring (code) PushButton button 2nd
[ Tea m LiB ]
Page 661
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] queries bulk
creating and executing (code) 2nd 3rd
point-and-click query tool
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th
point-and-click SQL Server query tool
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th
records
retrieving 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
SQL
value ranges 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th wildcards 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
subqueries
SQL statements, loading and executing (code) subqueries (T-SQL) 2nd 3rd 4th 5th 6th Query Builder 2nd 3rd SQL statements, building 2nd
query strings
definition QueryResults object methods properties question mark (?)
quotation marks
double ("")
[ Team LiB ]
Page 662
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R] [S] [T] [U] [V] [W] [X] Radio Button object
properties
radio buttons
rbDistinct Radio Button control
RadioButton object
properties
ranges of values
SQL queries 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th RangeValidator control
RangeValidator object
properties RAW mode rbDistinct Radio Button control
RDO
(Remote Data Objects) Read method 2nd
Read XML File button
read-only properties
classes, defining 2nd ReadBackupHeader method
reading XML documents
code 2nd into datasets (code) with XMLReader 2nd 3rd 4th 5th 6th 7th 8th 2nd 3rd
with XMLTextReader (code)
ReadOnly keyword
code ReadOnly object ReadOnly property ReadValuesFromDataRow method code 2nd 2nd
real data type (SQL Server) real-time hyperlinks 2nd
reattaching
databases
record sets
ADODB.CursorTypeEnum.adOpenForwardOnly cursor type
records
adding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th buttons to data tables (code) 2nd 2nd
to dsCustomerIndividual dataset (code) adding to data tables (code) 2nd 3rd
canceling editing/adding in DataGrid object (code) Cascade Delete Related Records cascade deletes Delete Record, creating deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th buttons code 2nd 3rd 2nd 3rd
exceptions, catching (code)
Page 663
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
in data grids (code) displaying 2nd 3rd in DISTINCT clause 2nd DISTINCT clause editing 2nd 3rd 4th filtering with DataView object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 2nd 3rd 4th 5th 6th
finding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th inner joins 2nd 3rd 4th 5th 6th 7th inserting joins left outer joins 2nd
loading
into text boxes (code) locating (code) 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th 6th
locating with DataTable object NULL persisting
posting
in data grids (code) 2nd 3rd 4th 5th 6th printing 2nd 3rd 4th 5th 6th 7th 8th retrieving 2nd 3rd 4th 5th 6th 7th 8th 9th 10th right outer joins 2nd saving before closing (code) sorting with DataView object 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
sources
searching stored procedures updating 2nd 3rd 4th Recordset object 2nd
ADO (ActiveX Data Objects) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
records
displaying 2nd 3rd editing 2nd 3rd 4th updating 2nd 3rd 4th
recordsets
persisting 2nd 3rd 4th
recordsets
Dynamic type cursor
fields
updating Forward Only type cursor
opening
code 2nd 3rd 4th persisting 2nd 3rd 4th
persisting to disks
code 2nd
retrieving
code 2nd 3rd 4th 2nd red X (Windows NT/2000 accounts)
Red/Blue border style
reports 2nd
references for SQL APIs (Application Programming Interfaces)
setting 2nd 3rd
Web
viewing 2nd
Page 664
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XML Web Services 2nd 3rd
referencing type libraries
with ADO (ActiveX Data Objects) 2nd 3rd referential integrity (database tables) RefreshIndividual routine 2nd 3rd
calling
code 2nd 3rd
RefreshIndividual subroutine
calls, code to add 2nd
refreshing
database lists 2nd
DataGrid control
code 2nd
datasets
code 2nd RefreshReport method
regenerating data
code 2nd RegionID, displaying
regions
DataItem.RegionURL column descriptions, displaying
repRegion Repeater control
loading (code)
repRegions Repeater control
HTML code 2nd
repTerritories Repeater control
code 2nd 2nd HTML code
loading (code) territories, displaying 2nd 3rd
registering
COM type libraries Regular ExpressionValidator control
RegularExpressionValidator object
properties RejectChanges method 2nd
relationships tables
many-to-many one-to-many one-to-one relationships between tables, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd
relationships of databases
Create Relationships dialog box 2nd
reloading 1stUnSelected list box
code
1stUnselected list box
code
list boxes
code 2nd 3rd 4th 5th
reloading list boxes
code 2nd
Page 665
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Remote Data Objects. RemoveAt method
[See RDO]
removing
temporary users reoirtsLFormula Editor
Repeater control data
displaying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th
events
programming
lists
buttons hyperlinks territories (regional), displaying 2nd 3rd properties
repRegion
loading (code)
repRegions
HTML code
repTerritories
code HTML code loading (code) templates 2nd 3rd
URLs (uniform resource locators), creating 2nd
Repeater object
properties Repeater Web server control ReplaceDatabase property
replacing SaveRecord routine
code 2nd 3rd
repopulating list boxes
code repopulating list boxes (code)
Report design
fields, adding Report Designer Report document 2nd
Name property, setting
reports
printing 2nd reports, exporting 2nd 3rd 4th
Report Expert
Crosstab reports Drill Down reports Form Letter reports Form reports
Formula Editor
displaying 2nd Mail Labels reports
reports
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th Standard reports SubReport reports
Page 666
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
tables 2nd
tabs
viewing
Report menu commands
Report Options Report Options command (Report menu)
Report Options dialog box
reports, customizing 2nd
ReportDocument
reports, assigning 2nd
reports
assigning with ReportDocument 2nd calculated fields, adding 2nd 3rd 4th 5th creating with Report Expert Crosstab customizing 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th
Details section
fields 2nd displaying 2nd 3rd 4th 5th 6th 7th displaying in Design view 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th
displaying with Crystal Report Viewer Drill Down
exporting 2nd 3rd 4th 5th 6th 7th 8th 9th code 2nd
ExportOptions object 2nd DestinationOptions ExportDestinationType ExportFormatType FormatOptions Form Form Letter
Formula Editor
displaying 2nd Formula fields
formulas
adding groupings 2nd
hyperlinks
action options 2nd
labels
printing 2nd 3rd 4th 5th 6th 7th 8th Mail Labels
mailing labels
creating 2nd 3rd modifying
naming
with rptReportName
OLE DB (ADO) data provider
choosing 2nd
on-screen
creating with hyperlinks 2nd 3rd 4th 5th 6th fields as hyperlinks 2nd 3rd Web site fields, adding options, setting 2nd printing 2nd 3rd 4th 5th 6th 7th 8th 9th code 2nd
Page 667
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
printing at run-time 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th real-time hyperlinks 2nd
records
printing 2nd 3rd 4th 5th 6th 7th 8th Red/Blue border style 2nd
ReportSource property 2nd 3rd SelectionFormula syntax 2nd
sort order
controlling at run-time 2nd Standard stringly typed strongly typed ReportSource property 2nd SubReport Tables in Report list user flexibility 2nd users controlling data viewed 2nd reports. 2nd
[See also C rystal Reports]
ReportSource property 2nd 3rd 4th
repRegion Repeater control loading
code
repRegions Repeater control
HTML code
repTerritories Repeater control
code HTML code
loading
code 2nd RequiredFieldValidator control
RequiredFieldValidator object
properties
resetting mbAddNew variable
code 2nd
resources
.NET Framework Developer's Guide Restore object methods 2nd 2nd
properties 2nd
restoring
SQL Server databases 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
result sets
Letter Button, filling (code) 2nd 3rd 4th
results of tables
displaying Results pane (View Designer)
retrieving
backup device names (code)
data
from SQL Server 2000 database 2nd 3rd 4th 5th 6th 7th with DataReader object 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
database names
code 2nd 3rd
datasets
from XML Web Services (code)
Page 668
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
information
from data grids 2nd records 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
recordsets
code 2nd 3rd 4th
SQL Server results
with DataTable object 2nd 3rd 4th 5th 6th
return values
ProdAndCatTab table 2nd
returning scalar types
UDFs (user-defined functions) Table data type 2nd
table types
UDFs (user-defined functions) 2nd
to calling pages
code 2nd revoke access level (object permissions) revoke state (statement permissions) right (>) arrow button
right outer joins
records, finding 2nd
rights
sharing on databases
roles
application roles (SQL Server security) 2nd 3rd 4th 5th bulkadmin (fixed server role) custom database roles (SQL Server security) 2nd 3rd 4th 5th 6th db_accessadmin (fixed database role) db_backupoperator (fixed database role) db_datareader (fixed database role) db_datawriter (fixed database role) db_ddladmin (fixed database role) db_denydatareader (fixed database role) db_denydatawriter (fixed database role) db_owner (fixed database role) db_securityadmin (fixed database role) dbcreator (fixed server role) diskadmin (fixed server role) fixed database roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th fixed server roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th processadmin (fixed server role) public (fixed database role) securityadmin (fixed server role) serveradmin (fixed server role) setupadmin (fixed server role) sysadmin (fixed server role)
routinees
GetSQLDatabases
routines
ActivateEditing creating (code) 2nd
ActiveEditing subroutine
calling (code) 2nd attaching to SelectedIndexChanged event BindTheGrid 2nd
Page 669
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BuildCnnStr
calling
code code collapsing dgRegion_CancelCommand dgRegion_DeleteCommand dgRegion_EditCommand dgRegion_UpdateCommand ExecuteABatchCommand expanding 2nd 3rd 4th 5th 6th 7th 8th 9th
GenerateData
calling calling (code) creating 2nd 3rd
GetBackupDevices
creating GetPageNum( ) GetPageRows( ) GetSQLDatabases creating
list boxes
reloading (code) 2nd
LoadIndividual
creating 2nd creating (code) 2nd 3rd
LoadList
creating (code) 2nd
LoadProducts
calling (code) 2nd
LoadSelectedProducts
creating 2nd LoadSQLServers 2nd LoadSQLString LoadTables( ) subroutine
LoadUnSelectedProducts
creating LoadUnSelectedProducts subroutine LoadUnUnselectedProducts subroutine
modGeneralRoutines.vb
connection strings, creating (code) 2nd 3rd 4th
modSQLDMORoutines.vb
database names, retrieving (code) SQL Servers;loading (code) 2nd OpenAndDisplayADOConnection OpenNorthwindADOConnection subroutine RefreshIndividual calling (code) 2nd 3rd 4th 2nd 3rd
RefreshIndividual subroutine
calls, code to add SaveRecord calling (code) creating (code) replacing (code) 2nd 2nd 3rd 2nd 3rd 2nd
SaveRecord subroutine
code
Page 670
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SetData subroutine
SQL Servers
loading (code)
subroutines
errors, throwing 2nd
UseAStoredProcedureWithAParameter
code RowFilter property setting for DataView object (code) 2nd
rows adding
in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
deleting
in data grids (code) 2nd 3rd in DataSet objects 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
finding
code in data grids, hyperlinking to detail pages 2nd 3rd 4th 5th 6th 7th SQL Server database objects 2nd RowStateFilter property
rptReportName reports
naming
rules business
data constraints 2nd Run as Server Control command (pop-up menu) Run Query button
Run Time check box
Create Columns Automatically, unchecking
run-time reports
options, setting 2nd printing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th SelectionFormula syntax 2nd
sort order
controlling 2nd
runtime
bound controls on Web Forms 2nd
[ Tea m LiB ]
Page 671
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S ] [T] [U] [V] [W] [X] Sams Web site
source code for chapters in book Save (XMLDocument class)
Save button
clicking, effects
save exceptions
trapping (code) Save method 2nd
save method declaring
code
Save method
implementing code 2nd 3rd 4th 5th
testing
code SaveRecord routine calling (code) creating (code) replacing (code) 2nd 2nd 3rd 2nd 3rd
SaveRecord subroutine
code
saving data
code 2nd 2nd command buttons to servers 2nd
records
before closing (code) tables Web Forms 2nd
saving to servers data
code saving. 2nd
[See also persisting]
scalar types returning
UDFs (user-defined functions) Scaler function 2nd
schemas
loading into data tables 2nd
XSD
(XML Schema Definition) Search button
search forms
calling 2nd
custom properties
creating (code) 2nd 3rd 4th 5th
searching
record sources tables 2nd 3rd 4th
security
Page 672
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SID (encrypted security ID) Windows NT Integrated Security users, logging into databases XML Web Services, testing 2nd
security tables
Web Services, creating with parameters 2nd security.
[See also SQL Server security]
securityadmin (fixed server role)
SecurityServices.asmx.vb
DataSet object, passing (code) passwords, validating (code) usernames, validating (code) SecurityWebServices Web site SELECT command text, code select object permission SELECT statement ALL clause
data
displaying (code) DISTINCT clause
updating
code 2nd
SELEC T string
columns Selected Products ListBox control
SelectedIndexC hanged event
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, adding routines, attaching SelectedIndices (index) collection SelectedIndices.Count property
Selection combo box populating
code 2nd 3rd
SelectionFormula reports
printing options, setting 2nd
syntax
reports, printing 2nd
SelectionFormula property setting
code SelectionMode property
Server Explorer
Create Database dialog box Customers table databases 2nd 2nd
icon on screen Visual Studio .NET 2nd Server Role Properties dialog box Server Roles icon 2nd 2nd
server-side solutions
state management 2nd 3rd 4th 5th Session object 2nd 3rd 4th serveradmin (fixed server role)
servers
Page 673
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
bulkadmin (fixed server role)
changes
updating (code) 2nd 3rd 4th
data
saving to (code) 2nd
data grids
records, deleting (code) records, posting (code) DataGrid Web server control DataList Web server control 2nd 3rd 4th 5th 6th 2nd 3rd 4th 5th 6th
DataTable object
tracking (code) 2nd 3rd 4th 5th 6th dbcreator (fixed server role) diskadmin (fixed server role) fixed server roles (SQL Server security) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Northwind SQL Server database
Customers table list processadmin (fixed server role) Repeater Web server control securityadmin (fixed server role) serveradmin (fixed server role) setupadmin (fixed server role)
SQL Server
bigint data type binary data type bit data type char data type cursor data type data types 2nd 3rd 4th 5th
datetime data type decimal data type fixed database roles float data type image data type int data type money data type nchar data type ntext data type numeric data type nvarchar data type real data type smalldatetime data type smallint data type smallmoney data type sql_variant data type table data type text data type timestamp data type tinyint data type uniqueidentifier data type varbinary data type varchar data type 2nd
SQL Server database
constraints, defining 2nd 3rd 4th 5th 6th creating 2nd 3rd 4th 5th 6th default values, defining 2nd 3rd 4th 5th 6th
Page 674
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
fields, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd 3rd 4th 5th 6th 7th 8th 9th
indexes, defining
primary keys, defining
stored procedures, creating 2nd 3rd 4th 5th tables, defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
tables, defining relationships 2nd 3rd 4th 5th 6th 7th 8th 9th views, creating 2nd 3rd 4th 5th 6th 7th 8th
SQL Server database objects
column properties 2nd 3rd columns 2nd creating rows 2nd
table properties 2nd 3rd tables 2nd
SQL Servers
loading (code) sysadmin (fixed server role) Table Web server control objects, creating 2nd 2nd 3rd
updating
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
Web pages
break points servers.
[See also SQL Server]2nd [See also Web servers]3rd [See also SQL Server]
Session object
Nothing keyword state management 2nd 3rd 4th
values
storing (code)
Session objects
.NET Framework Developer's Guide
session variables
tracking (code) 2nd 3rd
sessions
states SetData subroutine
setting DialogResult
code 2nd
setting to edit mode
data grids (code) setupadmin (fixed server role)
sharing
rights on databases
shortcut menu commands
New Database Role New Database User New Login SID (encrypted security ID) signatures of methods, definition
single tier applications
ADO (ActiveX Data Objects) 2nd smalldatetime data type (SQL Server) smallint data type (SQL Server) smallmoney data type (SQL Server)
SOAP
Page 675
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
XML Web Services
definition (code) 2nd 3rd 4th 5th
Solution Explorer
Web references, viewing 2nd
solutions
XML Web Services
sort order
controlling at run-time 2nd Sort Order property Sort property DESC Sort Type property
sorting
columns
data
in DataGrid control 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
data grids
code mailing labels 2nd
records
with DataView object setting in data grids 2nd setting on data grids 2nd source code for chapters in book, Web site 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th
sources
of records, searching
sources of data
choosing
sp_tables stored procedure
testing 2nd
SQL auto-generated
VB .NET tools, writing ADO.NET code 2nd 3rd BACKUP DATABASE statement BACKUP LOG statement CREATE DATABASE statement CREATE DEFAULT statement CREATE FUNCTION statement CREATE PROCEDURE statement CREATE RULE statement CREATE TABLE statement CREATE VIEW statement
DTS
(Data Transformation Services)
strings
creating (code) 2nd 3rd 4th
syntax
objects, creating
SQL APIs
(Application Programming Interfaces) 2nd 3rd references, setting 2nd 3rd
SQL databases
backing up verifying SQL Namespace.
[See SQL-NS]
SQL pane (View Designer)
Page 676
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SQL queries
value ranges 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th wildcards 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
SQL Server authentication mode
Enterprise Manager
batch updates
executing 2nd 3rd 4th 5th bigint data type binary data type bit data type bulkadmin (fixed server role) char data type cursor data type data types 2nd 3rd 4th 5th
databases
backing up 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th restoring 2nd 3rd 4th 5th 6th 7th 8th 9th 10th tables, copying between verifying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
datetime data type db_accessadmin (fixed database role) db_backupoperator (fixed database role) db_datareader (fixed database role) db_datawriter (fixed database role) db_ddladmin (fixed database role) db_denydatareader (fixed database role) db_denydatawriter (fixed database role) db_owner (fixed database role) db_securityadmin (fixed database role) dbcreator (fixed server role) decimal data type
Detach/Attach SQL Server Database dialog box
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th diskadmin (fixed server role)
DMF
(Distributed Management Framework) APIs (Application Programming Interfaces) 2nd 3rd float data type image data type int data type money data type nchar data type ntext data type numeric data type nvarchar data type
objects
creating with ADO (ActiveX Data Objects) 2nd 3rd 4th
point-and-click SQL Server query tool
creating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th processadmin (fixed server role) public (fixed database role) real data type
results
retrieving with DataTable object securityadmin (fixed server role) 2nd 3rd 4th 5th 6th
Page 677
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
serveradmin (fixed server role) setupadmin (fixed server role) smalldatetime data type smallint data type smallmoney data type sql_variant data type
stored procedures
executing (code) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th executing with ADO (ActiveX Data Objects) 2nd 3rd 4th sysadmin (fixed server role) T-SQL commands 2nd table data type text data type timestamp data type tinyint data type trusted connections
UDFs (user-defined functions)
calling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, formatting 2nd
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th creating (code) 2nd 3rd
parameters, passing scalar types, returning 2nd table types, returning 2nd uniqueidentifier data type varbinary data type varchar data type
views
flexibility Windows NT Integrated Security users, logging into databases SQL Server 2000
database
data, retrieving 2nd 3rd 4th 5th 6th 7th fixed database roles SQL Server 7.0 SQL Server Authentication button 2nd
SQL Server database constraints
defining 2nd 3rd 4th 5th 6th creating 2nd 3rd 4th 5th 6th
default values
defining 2nd 3rd 4th 5th 6th detaching (code)
fields
defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
indexes
defining 2nd 3rd 4th 5th 6th 7th 8th 9th
Northwind
CustOrdersHist stored procedure, T-SQL code
primary keys
defining 2nd 3rd 4th 5th 6th 7th 8th 9th
stored procedures
creating 2nd 3rd 4th 5th
tables
defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
Page 678
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
relationships, defining 2nd 3rd 4th 5th 6th 7th 8th 9th
views
creating 2nd 3rd 4th 5th 6th 7th 8th
SQL Server database objects
column properties 2nd 3rd columns 2nd creating rows 2nd
table properties 2nd 3rd tables 2nd
SQL Server databases attaching
code 2nd SQL Server Login Properties dialog box 2nd
SQL Server objects creating
code SQL Server security 2nd application roles 2nd 3rd 4th 5th authentication, mixed-mode custom database roles 2nd 3rd 4th
2nd 3rd 4th 5th 6th
database user accounts, creating 2nd 3rd 4th 5th 6th fixed database roles fixed server roles 2nd 3rd 4th 5th 6th 7th 8th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th
object permissions 2nd 3rd 4th 5th 6th standard logins, creating 2nd 3rd 4th 5th statement permissions 2nd 3rd 4th 5th 6th 7th
Windows NT/2000
authentication mode 2nd 3rd 4th 5th 6th 7th 8th groups, creating 2nd 3rd 4th 5th 6th logins, creating 2nd 3rd 4th 5th 6th users, adding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
SQL Servers backup devices
names, retrieving (code) 2nd
SQL servers
database names, retrieving (code) 2nd 3rd
SQL Servers listing
in SQL-DMO 2nd
loading
code 2nd 3rd 4th 5th 6th 7th loading (code)
SQL statements
actions, executing 2nd building with Query Builder creating displaying in labels 2nd
executing
code 2nd 2nd executing (code)
loading
code 2nd 3rd
storing
code 2nd 2nd storing (code)
Page 679
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
SQL strings
building (code)
creating
code 2nd SQL-Distributed Management Objects.
[See SQL-DMO]
SQL-DMO
(SQL-Distributed Management Objects) 2nd 3rd collections 2nd
databases
backing up connecting to 2nd Detach/Attach SQL Server Database dialog box, creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th
dialog boxes
connecting to databases 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th objects 2nd 3rd 4th 5th 6th 7th 8th 9th 2nd
databases, backing up and verifying
SQL APIs (Application Programming Interfaces)
references, setting 2nd 3rd
SQL Server
DMF APIs (Application Programming Interfaces) 2nd 3rd
SQL Server databases
backing up 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th restoring 2nd 3rd 4th 5th 6th 7th 8th 9th 10th tables, copying between verifying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th
2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
SQL Servers
listing 2nd
SQL-DTD objects
tables, copying SQL-DTS 2nd (Data Transformation Services) 2nd
data
exporting
objects
data, exporting
SQL-NS
(SQL Namespace) SQL.
[See also T-SQL]
sql_variant data type (SQL Server) SQLBackup method
SQLC lient classes
performance improvement 2nd
SQLC lient objects
and OleDb objects, comparing
SqlC ommand
(data control)
SqlC onnection
(data control)
SqlDataAdapter
(data control) ? (question mark) SQLDMO Object Library SQLRestore method
SQLServer object
Page 680
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
methods properties square brackets ([ ]) standard logins, creating 2nd 3rd 4th 5th
Standard Report Expert dialog box
tabs 2nd
Standard Report Wizard
Chart tab Data tab Fields tab Filter tab Group tab Style tab tabs 2nd 3rd 4th Top N tab Total tab Standard reports
state management
on clients 2nd server-side solutions 2nd 3rd 4th 5th Session object 2nd 3rd 4th
state management objects
values, storing stateless programming (Web pages)
clients
state management 2nd
server-side solutions
state management 2nd 3rd 4th 5th Session object 2nd 3rd 4th
statement permissions
deny state grant state revoke state statement permissions (SQL Server security) 2nd 3rd 4th 5th 6th 7th
statements
ALTER TABLE 2nd BACKUP DATABASE BACKUP LOG BEGIN
BETWEEN
data, generating (code) 2nd 3rd
C atch
in Try[ellipsis dots]Catch[ellipsis dots]End Try block CREATE DATABASE CREATE DEFAULT CREATE FUNCTION CREATE PROCEDURE CREATE RULE CREATE TABLE 2nd 3rd 4th CREATE VIEW DECLARE DROP TABLE 2nd END EXIST IF
LIKE
Page 681
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
data, generating (code) SELECT ALL clause data, displaying (code) DISTINCT clause updating (code) 2nd 2nd
SQL
actions, executing 2nd building with Query Builder creating displaying in labels 2nd executing (code) loading (code) storing (code) 2nd 3rd 4th
2nd 3rd 2nd 3rd 4th
update
executing
states
application database support deny (statement permissions) grant (statement permissions) revoke (statement permissions) session Step object methods properties Stored Procedure with Parameter button
stored procedures
break points, setting 2nd
calling
code 2nd 3rd creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
C ustOrdersHist
T-SQL code
executing
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 2nd objects, properties and methods
parameterized, executing in ADO.NET 2nd 3rd 4th 5th 6th 7th 8th records
sp-tables
testing 2nd T-SQL (Transact-SQL) TextBox control, populating 2nd
stored procedures (SQL Server)
executing with ADO (ActiveX Data Objects) 2nd 3rd 4th
storing key values
code 2nd 3rd 4th
SQL statements
code values to Session object (code) Stream object String Collection Editor 2nd 2nd 2nd 3rd 4th
strings connection
Page 682
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
BuildCnnStr( ) function creating (code) 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd
establishing (code) text, displaying
2nd
LoadSQLString routine
query
definition
SELEC T
columns
SQL
building (code) creating (code) strings. 2nd 2nd 3rd 4th 5th 6th
[See also connection strings]
StringValue property
code
strongly typed datasets VB .NET tools
ADO.NET code, writing 2nd 3rd strongly typed reports 2nd ReportSource property 2nd
strSQL SQL statements
executing (code) 2nd
Style tab
Standard Report Wizard
styles
Red/Blue border 2nd
subqueries SQL statements
loading and executing (code) T-SQL 2nd 3rd 4th 5th 6th SubReport reports
subroutines ActiveEditing
calling (code) 2nd errors, throwing 2nd LoadTables( ) LoadUnSelectedProducts LoadUnUnselectedProducts OpenNorthwindADOConnection
RefreshIndividual
calls, code to add 2nd
SaveRecord
code SetData
syntax SelectionFormula
reports, printing 2nd
SQL
objects, creating
variables
assigning sysadmin (fixed server role) System.XML namespace System.XML.Schema namespace System.XML.Xpath namespace
Page 683
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
System.XML.XSL namespace
systems
exceptions sysxlogins table
[ Tea m LiB ]
Page 684
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X] T-SQL
(Transact-SQL) CustOrdersHist stored procedure, code
Server objects
creating;code 2nd
T-SQL (Transact-SQL)
stored procedures, creating
T-SQL commands
BETWEEN operator 2nd built-in functions 2nd creating 2nd functions 2nd 3rd 4th 5th
local variables
declaring 2nd initializing 2nd
records
finding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th inner joins joins left outer joins 2nd
right outer joins 2nd records, retrieving 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
SQL queries
value ranges 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th wildcards 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th SQL Server
SQL Server UDFs (user-defined functions)
calling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, formatting 2nd
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th parameters, passing scalar types, returning 2nd table types, returning 2nd subqueries 2nd 3rd 4th 5th 6th
tables
ALTER TABLE statement 2nd CREATE TABLE statement 2nd 3rd creating 2nd 3rd 4th 5th 6th creating, modifying, deleting DROP TABLE statement 2nd variables 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
tab pages
controls 2nd
Table control data
displaying 2nd 3rd 4th 5th 6th 7th 8th 9th
loading
code 2nd 3rd 4th 5th persistence properties
Table controls
tables, displaying 2nd
Page 685
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Table data type creating and returning table data type (SQL Server) Table Designer Table function Table Mappings collection 2nd
Table object
properties Table Properties dialog box Permissions tab 2nd Table property 2nd
table types returning
UDFs (user-defined functions) Table Web server control objects, creating 2nd 2nd 3rd 2nd
TableC ell object
properties
TableRow object
properties
tables 1stLookupTables
pointing to items (code) Alias property ALTER TABLE statement 2nd Column property 2nd
columns
adding data, entering listing in databases (code) sorting sorting (code) 2nd 2nd 3rd
copying
between SQL Server databases code 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th
CREATE TABLE statement 2nd 3rd creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th Criteria property customer demographics, tracking
C ustomers
CustomerID column 2nd Server Explorer Customers table list Customers, CustomerCustomerDemo, and CustomerDemographics
data
adding data (code) binding (code) creating 2nd data, adding (code) loading (code) 2nd 3rd 2nd 3rd 4th 5th 6th 7th 8th
2nd 3rd 2nd 3rd 2nd
records, adding (code) records, locating (code) schemas, loading 2nd
text boxes, assigning values (code) DataItem.RegionURL column
2nd
defining 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
Page 686
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
deleting 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th
displaying
with Table control 2nd DROP TABLE statement 2nd EXIST statement expressions 2nd fields properties formulas 2nd Group By property IF statement in datasets inner joins joining 2nd
listing in databases
code 2nd 3rd 4th 5th 6th 7th 8th LoadTables( ) subroutine
lookup
data, adding 2nd 2nd information, managing updating 2nd updating, data-driven techniques 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th many-to-many relationship modifying 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 2nd
one-to-many relationship one-to-one relationship Or property Orders
CustomerID column 2nd Output property primary key field ProdAndCatTab 2nd 2nd
properties 2nd 3rd
records
adding to data tables (code) cascade deletes finding 2nd 3rd 4th 5th 6th 7th 8th 9th 10th inner joins 2nd joins left outer joins 2nd 2nd
right outer joins 2nd referential integrity 2nd 3rd
relationships
defining 2nd 3rd 4th 5th 6th 7th 8th 9th Report Expert 2nd
results
displaying
rows
deleting in data grids (code) saving searching 2nd 3rd 4th 2nd 3rd
security
Web Services, creating with parameters 2nd SELECT statement
Page 687
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Sort Order property Sort Type property SQL Server database objects 2nd 3rd 4th 5th sysxlogins Table property tblCustomerPhones, creating tblCustomers 2nd tblPhones View Designer 2nd wrapping Tables in Report list TabPages property 2nd
tabs
of Report Expert, viewing Standard Report Expert dialog box 2nd
Standard Report Wizard 2nd 3rd 4th
tags
element Task object methods properties
tasks
DTS packages 2nd tblCustomerPhones table, creating tblCustomers table tblPhones table techniques. telephone. 2nd
[See also data-driven techniques] [See phone]
templates
ASP.NET Web Service 2nd 3rd data grids
Repeater control
data, displaying 2nd 3rd temporary users, removing
territories repTerritories Repeater control
code HTML code loading (code) territories (regional), displaying 2nd 3rd
testing constructors
code 2nd 3rd 4th
Delete method
code Hello World method 2nd
Save method
code sp_tables stored procedure 2nd XML Web Services 2nd 3rd 4th 5th 6th XML Web Services security 2nd TestUserPassword method 2nd 3rd
text
of connection strings, displaying 2nd
text boxes binding
Page 688
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
to datasets to list boxes 2nd 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 2nd
binding and viewing Confirm Password Description 2nd disabling (code)
2nd 3rd 4th
frmHowTo1_3.vb
datasets, refreshing (code) Group Name 2nd 2nd
records
loading (code) 2nd 3rd 4th 5th 6th 7th 8th Text property, setting toggling (code) 2nd 3rd 4th 5th 6th
values
assigning (code) values, writing (code) text data type (SQL Server) 2nd 2nd
Text property
of Label object setting validation controls TextArea control
TextArea object
properties 2nd
TextBox control
populating 2nd properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th settings 2nd 3rd 4th settings for frmHowto_3 2nd 3rd 4th
property settings 2nd 3rd 4th TextBox object 2nd
properties 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd
TextBoxC hange method
text boxes, writing values (code) 2nd
TextC hanged event
code 2nd 3rd
ThrowException method declaring
code throwing errors 2nd timestamp data type (SQL Server) tinyint data type (SQL Server)
toggling
btnDetach button, code enabled properties of buttons (code) 2nd 3rd 4th 5th
text boxes
code 2nd 3rd 4th 5th 6th
toolbox
icon on screen
tools Administrative Tools
groups and users, adding
VB .NET
ADO.NET code, writing 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th ADO.NET code, writing;XSDs 2nd 3rd
Page 689
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
Top N tab
Standard Report Wizard ToString method property information output (code) 2nd
Total tab
Standard Report Wizard
tracking
customer demographics
DataTable object
code 2nd 3rd 4th 5th 2nd 3rd session variables (code)
Transact-SQL (T-SQL)
stored procedures, creating Transact-SQL. transfer.
[See T-SQL]
[See copy]
trapping exceptions
with Try[ellipsis dots]Catch[ellipsis dots]End Try block save exceptions (code) Trim function trusted connections (SQL Server) 2nd
Try[ellipsis dots]C atch[ellipsis dots]End Try block
Catch statements controls, ignoring exceptions, trapping Try[ellipsis dots]Catch[ellipsis dots]Finally block
Try[ellipsis dots]C atch[ellipsis dots]Finally blocks
exceptions 2nd
type libraries C OM
registering referencing with ADO (ActiveX Data Objects) 2nd 3rd
types scalar
returning for UDFs (user-defined functions) 2nd
table
returning for UDFs (user-defined functions) types. 2nd
[See also data types]
[ Tea m LiB ]
Page 690
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U ] [V] [W] [X] UDFs
(user-defined functions)
assigning
code 2nd calling 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code, formatting 2nd
creating 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th code 2nd 3rd 4th 5th
data
displaying (code) parameters, passing scalar types, returning 2nd
SELEC T statement, updating
code 2nd table types, returning 2nd Unassigned Products Only check box 2nd 3rd
unbound controls
on forms underscore (_) Unicode uniform resource locators.
[See URLs]
uniqueidentifier data type (SQL Server) Unselected Products ListBox control Update command code Update command text, code Update method 2nd 3rd
2nd 3rd 4th
update object permission
update statements
executing UpdateCommand method
updates batch
executing 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th batch (on-the-fly), executing in ADO.NET
updating
changes to servers (code) data 2nd 3rd 4th 5th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
data grids
code
databases
methods, implementing lookup tables 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th
data-driven techniques
22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st 32nd 33rd 34th 35th 36th 37th 38th 39th 40th 41st 42nd 43rd 44th 45th 46th
page indexes
in data grids (code) records 2nd 3rd 4th recordset fields
SELEC T statement
code 2nd
Page 691
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
servers
code 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
URLs
creating 2nd DataItem.RegionURL column Use Distinct button Use UDF button
UseAStoredProcedureWithAParameter routine
code user accounts for databases, creating 2nd 3rd 4th 5th 6th user-defined functions user-defined functions.
[See UDFs]
usernames validating
code 2nd
users
adding to Windows NT/2000 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
data
notifying to edit 2nd
files
exporting 2nd logging into databases Names list 2nd of reports, flexibility 2nd
records
saving before closing (code) 2nd
reports
controlling data viewed temporary, removing Windows NT/2000 domains, displaying 2nd 2nd 2nd
Users Must Enter a User Name and Password to Use This Computer check box
[ Team LiB ]
Page 692
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html [ Team LiB ]
[SYMBOL] [A] [B] [C ] [D] [E] [F ] [G] [H] [I] [J ] [K ] [L] [M] [N] [O] [P] [Q] [R ] [S] [T] [U] [V] [W] [X]
Validate method
ValidateC ustomerID method
code
validating
data 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th data on Web Forms
passwords
code 2nd 2nd 3rd 4th phone numbers (code)
usernames
code 2nd 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd validation code, writing
24th 25th 26th 27th
validation controls
code CompareValidator CustomValidator 2nd
for Web Forms
property settings 2nd 3rd messages, displaying on Web Forms RangeValidator Regular ExpressionValidator RequiredFieldValidator ValidationSummary 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th
validation controls (Web Forms)
property settings 2nd 3rd 4th 5th validation errors for controls 2nd Validation Web server controls 2nd 3rd ValidationExpression property ValidationSummary control lists, look of
ValidationSummary object
properties
validator controls
reaction inconsistencies Value method
value ranges
SQL queries 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th ValueMember property ValueMember property (list boxes)
values
default, defining DeliveryDate 2nd 3rd 4th 5th 6th 2nd 2nd
in text boxes, writing (code) key, storing (code)
2nd 3rd 4th
lookup tables
updating 2nd
null
Allow Nulls null, interpreting OrderID 2nd
Page 693
ABC Amber CHM Converter Trial version, http://www.processtext.com/abcchm.html
return
ProdAndCatTab table storing to Session object (code) varbinary data type (SQL Server) varchar data type (SQL Server) 2nd
variables ampersand ( & )
variables, declaring
assigning
syntax class, declarations (code) DECLARE statement
local
declaring in T-SQL 2nd initializing in T-SQL 2nd
mbAddNew
resetting;code 2nd
mFax
event handlers (code) placing under forms code 2nd
public
declaring (code)
session
tracking (code) 2nd 3rd 4th 5th T-SQL commands 2nd 3rd 4th 5th
VB .NET ADO.NET code, writing
SQL (auto-generated) strongly typed datasets XSDs 2nd 3rd 2nd 3rd 2nd 3rd
classes
default properties defining 2nd 3rd 4th 5th methods;adding to interfaces parameterized properties properties 2nd 3rd 4th properties;adding to interfaces read-only properties 2nd 2nd 3rd
write-only properties 2nd
properties
modifiers property declarations Public access modifiers 2nd
reports
displaying 2nd 3rd 4th 5th 6th 7th exporting 2nd 3rd 4th 5th 6th 7th 8th 9th printing 2nd 3