ComponentOne VSView Reporting Edition

Introduction

Using VSView Reporting Edition

Using the VSReport8 Designer


Overview

VSView Reporting Edition includes two main controls: VSPrinter8 and VSReport8. VSPrinter8 is a stand-alone control that provides printing and print previewing services. You can use it on its own to create custom documents of any type. VSReport8 generates Access-style, data-based banded reports and renders them using VSPrinter8.

VSView Reporting Edition enables you to visualize the data in your applications in the form of rich, presentation-quality reports. You can preview, print, and export these reports on your computer or over the Web.

VSReport8 is an upgrade to VSReport 1.0. Both versions are largely based on the Microsoft Access reporting model. If you use Access, you will feel right at home with VSReport8.

If you like VSView Reporting Edition, you can check out our other products by visiting our web site at www.componentone.com.

ComponentOne has a user-friendly distribution policy. We want every programmer to get copies of our products and try them for as long as they want. Those who like the tools and find them useful can buy licenses at reasonable prices. The only restriction is that unlicensed copies of the software will display a ComponentOne banner when they are loaded, as a friendly reminder that we do expect people to pay for the software if they use it on a regular basis.

We hope you'll like VSView Reporting Edition. If you have suggestions or ideas for new features or new tools, please call us or write.

Corporate Headquarters

ComponentOne LLC
4516 Henry Street
Suite 500
Pittsburgh, PA 15213 USA
412.681.4343
412.681.4384 (Fax)

http://www.componentone.com


Installation

To install VSView Reporting Edition, use the SETUP.EXE utility provided on the installation CD or diskettes. When you are prompted, enter the registration key (found on the CD case or the diskette) exactly as it is printed and click REGISTER to complete the registration.

The following files will be installed into your Windows\Help directory:

VSPrint8.chm | Contains the VSPrinter8 online help topics.
VSRpt8.chm | Contains the VSReport8 online help topics.

The following files will be installed into your Windows\System directory or, if you use Windows NT, into your WinNT\System and WinNT\System32 directories. To use VSReport8 in your Visual Basic projects, you must include these files in the project:

VSRpt8.ocx | Contains the VSReport8 ActiveX control.
VSPrint8.ocx | Contains the VSPrinter8 ActiveX control.

The following folders will be created by the setup utility:

ComponentOne

Directory used to store ComponentOne control information.

ComponentOne\VSReport8

Contains sample projects and a README.TXT file with information about VSReport8.

Installing Demonstration Versions

If you wish to try VSView Reporting Edition and do not have a registration key, use the SETUP.EXE utility provided on the distribution CD. When prompted, leave the registration key box blank, and press FINISH. The only difference between unregistered (evaluation) and registered (purchased) versions of the software is that the registered version will stamp every application you compile so a banner will not appear when your users run the applications.

Uninstalling VSView Reporting Edition

To uninstall VSView Reporting Edition, use the UNSETUP.EXE utility provided on the installation CD or diskettes.


Upgrading from VSReport 1.0

VSReport8 is a major upgrade for VSReport 1.0 users. The control has been entirely re-written to take advantage of great new technologies such as OLEDB and XML. It implements features that users have been requesting for a long time such as subreports, HTML/DHTML/PDF export, and more.

VSReport8 also includes a powerful Reports Designer, so creating and customizing your reports is easier than before.

The architecture of the control was also changed. VSReport 1.0 contained a VSPrinter control and used it to display and print reports. VSReport8 is an invisible control that can be connected to VSPrinter controls using method calls. This new architecture allows the programmer complete access to the VSPrinter control and all its powerful features. It also allows you to use VSReport8 in server applications (without a user-interface) to create HTML or PDF reports without using the VSPrinter control.

To upgrade from VSReport 1.0, follow these steps:

1.

Open the VSReport8 Designer and use the File|Import menu to convert your existing report definition files (*.vsr) into the new format (*.xml). You may combine multiple vsr files into a single xml file.

2.

Open your existing project and replace each instance of the VSReport 1.0 control with two controls: place a VSPrinter8 control where VSReport 1.0 used to be and add a VSReport8 control next to it (VSReport8 is an invisible control).

3.

Change your code as follows:

' replace this code

VSReport1.DatabaseName = App.Path & "\biblio2.mdb"

VSReport1.ReportFileName = App.Path & "\alphabet.vsr"

VSReport1.PrintReport

' with this code

VSReport8.Load = App.Path & "\alphabet.xml", "Alphabet"

VSReport8.Render VSPrinter8

In VSReport8, all data source information is contained in the report definition file, so you don't need to set a DatabaseName property. Each report definition file may contain multiple reports, so the new control uses a Load method instead of the old ReportFileName property. Finally, Render is the method used for rendering a report into a VSPrinter control, replacing the old PrintReport.


Adding the VSReport 8 Components to the Toolbox

VSReport8 generates Access-style, data-based banded reports and renders them using VSPrinter8.

To use the VSReport8 and VSPrinter8 components, they must be added to the Visual Studio Toolbox:

Open the Visual Basic IDE (Microsoft's Integrated Development Environment). Make sure the Toolbox is visible (if necessary, select Toolbox in the View menu).

To set up the VSReport8 components to appear on their own tab, right-click anywhere in the Toolbox and select Add Tab from the context menu. Enter a tab name, for example, “Report 8”, in the dialog box. Select the new tab. Right-click the gray area under that tab and select Components from the context menu. The Components dialog box opens.

In the Components dialog box, find and select ComponentOne VSReport 8.0 Control and ComponentOne VSPrinter 8.0 Control. Click OK.


End-User License Agreement

IMPORTANT-READ CAREFULLY: This End User License Agreement (this "EULA") contains the terms and conditions regarding your use of the SOFTWARE (as defined below). This EULA contains material limitations to your rights in that regard. You should read this EULA carefully and treat it as valuable property.

I. THIS EULA.

1.

Software Covered by this EULA. This EULA governs your use of the ComponentOne, LLC ("C1") software product(s) enclosed or otherwise accompanied herewith (individually and collectively, the "SOFTWARE"). The term "SOFTWARE" includes, to the extent provided by C1: 1) any revisions, updates and/or upgrades thereto; 2) any data, image or executable files, databases, data engines, computer software, or similar items customarily used or distributed with computer software products; 3) anything in any form whatsoever intended to be used with or in conjunction with the SOFTWARE; and 4) any associated media, documentation (including physical, electronic and on-line) and printed materials (the "Documentation").

2.

This EULA is a Legally Binding Agreement Between You and C1. If you are acting as an agent of a company or another legal person, such as an officer or other employee acting for your employer, then "you" and "your" mean your principal, the entity or other legal person for whom you are acting. However, importantly, even if you are acting as an agent for another, you may still be personally liable for violation of federal and State laws, such as copyright infringement.

This EULA is a legally binding agreement between you and C1. You intend to be legally bound to this EULA to the same extent as if C1 and you physically signed this EULA. By installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms and conditions contained in this EULA. If you do not agree to all of the terms and conditions contained in this EULA, you may not install or use the SOFTWARE. If, for whatever reason, installation has begun or has been completed, you should cancel installation or un-install the SOFTWARE, as the case may be. (You may click on the "exit" button or its equivalent to immediately abort installation.) If you do not agree to all of these terms and conditions, then you must promptly return the SOFTWARE to the place of business from which you obtained it in accordance with any return policies of such place of business. Return policies may vary between or among resellers, and you must comply with your particular reseller's return policies as agreed at the point of purchase. If the place of business from which you purchased the SOFTWARE does not honor a complete refund for a period of thirty (30) days from the date of proof of purchase, then you may return the SOFTWARE directly to C1 for a period of thirty (30) days from the date of your purchase. To return the product directly to C1, you must obtain a C1 Return Authorization Number by contacting C1, and you must forward all items purchased, including the proof of purchase, directly to C1. The return must be postage-prepaid, and post-marked within thirty (30) days from the proof of purchase, time being of the essence. The return option to C1 is only available to the original purchaser of an unopened factory packaged item.

II. YOUR LICENSE TO DEVELOP AND TO DISTRIBUTE.

As provided in more detail below, this EULA grants you two licenses: 1) a license to use the SOFTWARE to develop other software products (the "Development License"); and 2) a license to use and/or distribute the Developed Software (the "Distribution License"). Both of these licenses (individually and collectively, the "Licenses") are explained and defined in more detail below.

1.

Definitions. The following terms have the respective meanings as used in this EULA:

"Network Server" means a computer with one or more computer central processing units (CPU's) that operates for the purpose of serving other computers logically or physically connected to it, including, but not limited to, other computers connected to it on an internal network, intranet or the Internet. "Web Server" means a type of Network Server that serves other computers more particularly connected to it over an intranet or the Internet.

"Developed Software" means those computer software products that are developed by or through the use of the SOFTWARE. "Developed Web Server Software" means those Developed Software products that reside logically or physically on at least one Web Server and are operated (meaning the computer software instruction set is carried out) by the Web Server's central processing unit(s) (CPU). "Developed Legacy Software" means those Developed Software products that are not Developed Web Server Software, including, for example, stand-alone applications and applications accessed by a file server only. "Redistributable Files" means the SOFTWARE files or other portions of the SOFTWARE that are provided by C1 and are identified as such in the Documentation for distribution by you with the Developed Software. "Developer" means a human being or any other automated device using the SOFTWARE in accordance with the terms and conditions of this EULA.

"Developer Seat License" means that each Developer using or otherwise accessing the programmatic interface or the SOFTWARE must obtain the right to do so by purchasing a separate End User License. "Network Server CPU License" means that a separate End User License must be purchased for each CPU operating the computer software at issue in the reference.

“Source Code” shall mean computer software code or programs in human readable format, such as a printed listing of such a program written in a high-level computer language. The term "Source Code" includes, but is not limited to, documents and materials in support of the development effort of the SOFTWARE, such as flow charts, pseudo code and program notes.

2.

Your Development License. You are hereby granted a limited, royalty-free, non-exclusive right to use the SOFTWARE to design, develop, and test Developed Software, on the express condition that, and only for so long as, you fully comply with all terms and conditions of this EULA.

The SOFTWARE is licensed to you on a Developer Seat License basis.

The Developer Seat License means that you may perform a single install of the SOFTWARE for use in designing, testing and creating Developed Software by a single Developer on a single computer with a single set of input devices, so long as such computer is used only by one Developer. Conversely, you may not install or use the SOFTWARE on a computer that is a network server or a computer at which the SOFTWARE is used by more than one Developer. You may not network the SOFTWARE or any component part of it, where it is or may be used by more than one Developer unless you purchase an additional Development License for each Developer. You must purchase another separate license to the SOFTWARE in order to add additional developer seats, whether the additional developers are accessing the SOFTWARE in a stand-alone environment or on a computer network. If the SOFTWARE is used to create Developed Web Server Software, then you may perform a single install of the SOFTWARE for use in designing, testing and creating Developed Web Server Software by a single Developer on a single computer or Network Server, either with a single CPU only. An additional Network Server CPU License is required for each additional CPU on the single computer or Network Server, as the case may be, upon which the SOFTWARE and/or the Developed Web Server Software is installed and a separate license for each separate computer. That is, for Developed Web Server Software, if the computer or Network Server operating the SOFTWARE has 2 CPU's, then you would need to purchase one additional Network Server CPU License (beyond the one Developer Seat License granted in this EULA).

In all cases, you may not use C1's name, logo, or trademarks to market your Developed Software without the express written consent of C1; (b) you must include the following C1 copyright notice in your Developed Software documentation and/or in the "About Box" of your Developed Software, and wherever the copyright/rights notice is located in the Developed Software (“Portions Copyright © ComponentOne, LLC 1991-2002. All Rights Reserved.”); (c) agree to indemnify, hold harmless, and defend C1, its suppliers and resellers, from and against any claims or lawsuits, including attorney's fees that may arise from the use or distribution of your Developed Software; (d) you may use the SOFTWARE only to create Developed Software that is significantly different than the SOFTWARE.

3.

Your Distribution License.

a. License to Distribute Developed Legacy Software. Subject to the terms and conditions in this EULA, you are granted the license to use and to distribute Developed Legacy Software on a royalty-free basis, provided that the Developed Legacy Software incorporates the SOFTWARE as an integral part of the Developed Software in machine-language compiled format (customarily an ".exe", or ".dll", etc.). You may not distribute, bundle, wrap or subclass the SOFTWARE as Developed Software which, when used in a "designtime" development environment, exposes the programmatic interface of the SOFTWARE. You may distribute, on a royalty-free basis, Redistributable Files with Developed Legacy Software only.

b. License to Distribute Developed Web Server Software. Subject to the terms and conditions in this EULA, you are granted the license to use and to distribute Developed Web Server Software, provided that you must purchase one Network CPU License for each CPU operating the Developed Web Server Software (and/or Redistributable Files called or otherwise used directly by the Developed Web Server Software). You may purchase an additional Network CPU License by purchasing an additional separate End User License for the SOFTWARE; one Network CPU License is included in this EULA. Notwithstanding the foregoing, however, you may distribute or transfer, free of royalties, the Redistributable Files (and/or any Developed Legacy Software) to the extent that they are used separately on a single CPU on the client/workstation side of the network served by the Web Server.

4.

Specific Product Limitations. Notwithstanding anything in this EULA to the contrary, if the license you have purchased is for any of the following products, then the following additional limitations will apply:

a. C1 ReportDesigner. C1ReportDesigner includes at least: 1) one dynamic link library (c1.win.c1reportdesigner.dll) file known as C1ReportDesigner Component, 2) one executable (ReportDesigner.exe) file known as C1ReportDesigner Application and, 3) the Source Code of the C1ReportDesigner Application. The C1ReportDesigner Component is subject to the general terms and restrictions set forth in this EULA. The C1ReportDesigner Application is an executable file used to design and prepare reports; the C1ReportDesigner Application may be distributed, free of royalties, only in conjunction with the Developed Software.

Subject to the terms and conditions in this EULA, C1 hereby grants you the right to use the C1ReportDesigner Application Source Code. You are hereby also granted the right to modify such Source Code and to create derivative works that are based on the licensed Source Code. You may distribute the derivative works that you develop, solely in object code format and exclusively in conjunction with and/or as a part of the Developed Software. You are expressly not granted the right to distribute, disclose or otherwise make available to any third party the licensed Source Code, any modified version, derivative work, or any portion thereof, in source code format.

C1 shall retain all right, title and interest in and to the licensed Source Code, and all C1 updates, modifications or enhancements thereof. Nothing herein shall be deemed to transfer any ownership or title rights in and to the licensed Source Code from C1 to you.

SOURCE CODE IS LICENSED TO YOU AS IS. C1 DOES NOT AND SHALL NOT PROVIDE YOU WITH ANY TECHNICAL SUPPORT FOR YOUR SOURCE CODE LICENSE.

b. VS View Reporting Edition. VS View Reporting Edition includes at least one executable file listed as “VSRpt7.exe”, known as “Designer.” The file "VSRpt7.exe”, or any upgrade or future versions of the Designer, are subject to the restrictions set forth in this EULA and may not be distributed with your Developed Software or in any other way.

c. VSForum. VSForum is intended to be installed on a Network Server. C1 grants to you the following rights to the SOFTWARE: a) Installation: You may install one copy of the SOFTWARE on a single Network Server; b) Use: When installed and initialized, the SOFTWARE creates a database file which contains the embodiment of a discussion forum (the database hereinafter referred to as the "Forum"). You may use the SOFTWARE to create one Forum on one Network Server only, which server may be connected at any point to an unlimited number of workstations or computers operating on one or more networks. You are specifically NOT LICENSED to create or operate multiple Forums. To create or to operate more than one FORUM, you must purchase one additional SOFTWARE license for each additional Forum.

d. Doc-to-Help. You may use Doc-To-Help to create online help, manuals or other documentation in electronic or printed format (the "Output Documents"). You may distribute and incorporate in such Output Documents those files identified in the documentation as Redistributable Files. Except for those specific Redistributable Files, you MAY NOT distribute the SOFTWARE, in any format, to others.

e. Studio Products. You may not share the component parts of the Studio Products licensed to you with other Developers, nor may you allow the use and/or installation of such components by other Developers.

5.

Updates/Upgrades; Studio Subscription. Subject to the terms and conditions of this EULA, the Licenses are perpetual. Updates and upgrades to the SOFTWARE may be provided by C1 from time-to-time, and, if so provided by C1, are provided upon the terms and conditions offered at that time by C1 in its sole discretion. C1 may provide updates and upgrades to the SOFTWARE for free or for any charge, at any time or never, and through its chosen manner of access and distribution, all in C1's sole and complete discretion.

C1 licenses certain of its separately-licensed products bundled together in a product suite, called the C1 "Studio" product line (the "Studio Products"). The exact separately-licensed products that are bundled into the Studio Products may change from time-to-time in C1's sole discretion. If the SOFTWARE is identified as a C1 "Studio" product, then the SOFTWARE is one of the Studio Products. The SOFTWARE and the Studio Products are revised from time-to-time (meaning, for example, revised with updates, upgrades and, in the case of Studio products, possibly changes to which specific products are included in the bundle). For you to be entitled to receive any such revisions to the SOFTWARE or the Studio Products, as the case may be, you must have a valid SOFTWARE license or a valid Studio subscription. The original purchaser of the SOFTWARE or of a Studio product receives a one-year subscription from the date of purchase of the SOFTWARE. After one year, the Studio subscription and/or the SOFTWARE license must be renewed to continue to be entitled to receive the SOFTWARE and/or the Studio Products revisions as the case may be.

6.

Serial Number. Within the packaging of the SOFTWARE, a unique serial number (the "Serial Number") is included, which allows for the registration of the SOFTWARE. The Serial Number is subject to the restrictions set forth in this EULA and may not be disclosed or distributed either with your Developed Software or in any other way. The disclosure or distribution of the Serial Number shall constitute a breach of this EULA, the effect of which shall be the automatic termination and revocation of all the rights granted herein.

7.

Evaluation Copy. If you are using an "evaluation copy" or similar version, specifically designated as such by C1 on its website or otherwise, then the Licenses are limited as follows: a) you are granted a license to use the SOFTWARE for a period of thirty (30) days counted from the day of installation (the "Evaluation Period"); b) upon completion of the Evaluation Period, you shall either i) delete the SOFTWARE from the computer containing the installation, or you may ii) contact C1 or one of its authorized dealers to purchase a license of the SOFTWARE, which is subject to the terms and limitations contained herein; and c) any Developed Software may not be distributed or used for any commercial purpose.

III. INTELLECTUAL PROPERTY.

1.

Copyright. You agree that all right, title, and interest in and to the SOFTWARE (including, but not limited to, any images, photographs, animations, video, audio, music, text, and “applets” incorporated into the SOFTWARE), and any copies of the SOFTWARE, and any copyrights and other intellectual properties therein or related thereto are owned exclusively by C1, except to the limited extent that C1 may be the rightful license holder of certain third-party technologies incorporated into the SOFTWARE. The SOFTWARE is protected by copyright laws and international treaty provisions. The SOFTWARE is licensed to you, not sold to you. C1 reserves all rights not otherwise expressly and specifically granted to you in this EULA.

2.

Backups. You may either: (a) copy the SOFTWARE solely for backup or archival purposes; or (b) install the SOFTWARE on a single computer, provided you keep the original solely for backup or archival purposes. Notwithstanding the foregoing, you may not copy the Documentation.

3.

General Limitations. You may not reverse engineer, decompile, or disassemble the SOFTWARE, except and only to the extent that applicable law expressly permits such activity notwithstanding this limitation.

4.

Software Transfers. You may not rent or lease the SOFTWARE. You may transfer the SOFTWARE to another computer, provided that it is completely removed from the computer from which it was transferred. You may permanently transfer all of your rights under the EULA, provided that you retain no copies, that you transfer all the SOFTWARE (including all component parts, the media and printed materials, any dates, upgrades, this EULA and, if applicable, the Certificate of Authenticity), and that the recipient agrees to the terms and conditions of this EULA as provided herein. If the SOFTWARE is an update or upgrade, any transfer must include all prior versions of the SOFTWARE.

5.

Termination. Without prejudice to any other rights it may have, C1 may terminate this EULA and the Licenses if you fail to comply with the terms and conditions contained herein. In such an event, you must destroy all copies of the SOFTWARE and all of its component parts.

6.

Export Restrictions. You acknowledge that the SOFTWARE is of U.S. origin. You acknowledge that the license and distribution of the SOFTWARE is subject to the export control laws and regulations of the United States of America, and any amendments thereof, which restrict exports and re-exports of software, technical data, and direct products of technical data, including services and Developed Software. You agree that you will not export or re-export the SOFTWARE or any Developed Software, or any information, documentation and/or printed materials related thereto, directly or indirectly, without first obtaining permission to do so as required from the United States of America Department of Commerce's Bureau of Export Administration ("BXA"), or other appropriate governmental agencies, to any countries, end-users, or for any end-uses that are restricted by U.S. export laws and regulations, and any amendments thereof, which include, but are not limited to, the following:

Restricted Countries: Restricted Countries currently include, but are not necessarily limited to Cuba, Iran, Iraq, Libya, Montenegro, North Korea, Serbia, Sudan, and Syria.

Restricted End-Users: Any End-User whom you know or have reason to know will use SOFTWARE or Developed Software in the design, development, or production of missiles and missile technology, nuclear weapons and weapons technology, or chemical and biological weapons. Any national of any of the Restricted Countries, wherever located, who intends to transmit or transport the SOFTWARE or Developed Software to one of the Restricted Countries.

Restricted End-Uses: Any use of SOFTWARE and Developed Software related to the design, development, or production of missiles and missile technology, nuclear weapons and weapons technology, or chemical and biological weapons.

These restrictions change from time to time. You represent and warrant that neither the BXA nor any other United States federal agency has suspended, revoked or denied your export privileges. C1 acknowledges that it shall use reasonable efforts to supply you with all reasonably necessary information regarding the SOFTWARE and its business to enable you to fully comply with the provisions of this Section. If you have any questions regarding your obligations under United States of America export regulations, you should contact the Bureau of Export Administration, United States Department of Commerce, Exporter Counseling Division, Washington DC. U.S.A. (202) 482-4811, http://www.bxa.doc.gov.

7.

U.S. Government Restricted Rights. The SOFTWARE and documentation are provided with RESTRICTED RIGHTS. For solicitations issued before December 1, 1995, by the United States of America, its agencies and/or instrumentalities (the "Government"), other than the Department of Defense, the use, duplication or disclosure of the software and documentation provided to the Government under this EULA shall be subject to the RESTRICTED RIGHTS as set forth in subparagraphs (c)(1) and (2) of the Commercial Computer Software - Restricted Rights clause at 48 CFR ch.1 52.227-19. For solicitations issued before September 29, 1995, by the Department of Defense, the use, duplication or disclosure of the software and documentation provided under this EULA shall be subject to the RESTRICTED RIGHTS as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at 48 CFR ch.2 252.227-7013. You will comply with any requirements of the Government to obtain such RESTRICTED RIGHTS protection, including without limitation, the placement of any restrictive legends on the SOFTWARE, and any license agreement used in connection with the distribution of the SOFTWARE. Manufacturer is ComponentOne, LLC, 4516 Henry Street, Suite 501, Pittsburgh, Pennsylvania 15213 USA. For solicitations issued by the Government on or after December 1, 1995 and the Department of Defense on or after September 29, 1995, the only rights provided in the software and documentation provided herein shall be those contained in this EULA. Under no circumstances shall C1 be obligated to comply with any Governmental requirements regarding the submission of or the request for exemption from submission of cost or pricing data or cost accounting requirements. For any distribution of the SOFTWARE that would require compliance by C1 with the Government's requirements relating to cost or pricing data or cost accounting requirements, you must obtain an appropriate waiver or exemption from such requirements for the benefit of C1 from the appropriate Government authority before the distribution and/or license of the SOFTWARE to the Government.

IV. WARRANTIES AND REMEDIES.

1.

Limited Warranty. C1 warrants that the original media, if any, are free from defects for ninety (90) days from the date of delivery of the SOFTWARE. EXCEPT AS OTHERWISE PROVIDED IN THE PRECEDING SENTENCE, AND TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, C1 EXPRESSLY DISCLAIMS ANY WARRANTY FOR THE SOFTWARE, DOCUMENTATION AND ANYTHING ELSE PROVIDED BY C1 HEREBY AND C1 PROVIDES THE SAME IN “AS IS” CONDITION WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE AND DOCUMENTATION REMAINS WITH YOU. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS. YOU MAY HAVE OTHERS WHICH VARY FROM STATE TO STATE.

2.

Limited Remedy. C1's entire liability and your exclusive remedy under this EULA shall be, at C1's sole option, either (a) return of the price paid for the SOFTWARE; (b) repair the SOFTWARE through updates distributed online or otherwise in C1's discretion; or (c) replace the SOFTWARE with its reasonable, provided that you return the SOFTWARE in the same manner as provided in Section I.2 for return of the SOFTWARE for non-acceptance of this EULA. Any media for any repaired or replacement SOFTWARE will be warranted for the remainder of the original warranty period or thirty (30) days, whichever is longer. THESE REMEDIES ARE NOT AVAILABLE OUTSIDE OF THE UNITED STATES OF AMERICA. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL C1 BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFIT, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, EVEN IF C1 HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES IN CERTAIN CASES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.

V. MISCELLANEOUS.

1.

This is the Entire Agreement. This EULA (including any addendum or amendment to this EULA included with the SOFTWARE) is the final, complete and exclusive statement of the entire agreement between you and C1 relating to the SOFTWARE. This EULA supersedes any prior and contemporaneous proposals, purchase orders, advertisements, and all other communications in relation to the subject matter of this EULA, whether oral or written. No terms or conditions, other than those contained in this EULA, and no other understanding or agreement which in any way modifies these terms and conditions, shall be binding upon the parties unless entered into in writing executed between the parties, or by other non-oral manner of agreement whereby the parties objectively and definitively act in a manner to be bound (such as by continuing with an installation of the SOFTWARE, "clicking-through" a questionnaire, etc.) Employees, agents and other representatives of C1 are not permitted to orally modify this EULA.

2.

You Indemnify C1. You agree to indemnify, hold harmless, and defend C1 and its suppliers and resellers from and against any and all claims or lawsuits, including attorney's fees, that arise or result from this EULA.

3.

Interpretation of this EULA. If for any reason a court of competent jurisdiction finds any provision of this EULA, or any portion thereof, to be unenforceable, that provision of this EULA will be enforced to the maximum extent permissible so as to effect the intent of the parties, and the remainder of this EULA will continue in full force and effect. Formatives of defined terms shall have the same meaning of the defined term. Failure by either party to enforce any provision of this EULA will not be deemed a waiver of future enforcement of that or any other provision. Except as otherwise required or superseded by law, this EULA is governed by the laws of the Commonwealth of Pennsylvania, without regard to its conflict of laws principles. The parties consent to the personal jurisdiction and venue of the Commonwealth of Pennsylvania, in the County of Allegheny, and agree that any legal proceedings arising out of this EULA shall be conducted solely in such Commonwealth. If the SOFTWARE was acquired outside the United States, then local law may apply.


Redistributable Files

VSView Reporting Edition is runtime royalty-free. You may include copies of the OCX files with as many copies of as many applications you ship. If you work with other developers, you may be interested in ComponentOne's site licenses. Call us for details.

To distribute your application, you will need to create a set up utility. This utility will take care of detecting the files your application needs to run (EXEs, DLLs, OCXs, and others), compressing these files and later copying them to the user's computer, and also dealing with details such as potential version conflicts, component registration, etc. We recommend that you use the Set Up Wizard that ships with Microsoft Visual Basic or a professional program such as Wyse or InstallShield.

The VSReport8 Designer is not a royalty-free component. If you want to distribute it as part of your application, please contact ComponentOne to obtain the appropriate license.

If you haven't yet registered your copy of VSView Reporting Edition and would like to do it now, please use the enclosed order form or visit http://www.componentone.com/.


Technical Support

ComponentOne VSView Reporting Edition is developed and supported by ComponentOne LLC, a company formed by the merger of APEX Software Corporation and VideoSoft. You can obtain technical support using any of the following methods:


ComponentOne Web Site

The ComponentOne Web site at www.componentone.com provides a wealth of information and software downloads for VSView users, including:

•

Descriptions of the various support options available through the ComponentOne Service Team.

•

Answers to frequently asked questions (FAQ's) about our products, organized by functionality. Please consult the FAQ's before contacting us directly, as this can save you time and also introduce you to other useful information pertaining to our products.

•

Free product updates, which provide you with bug fixes and new features.


Internet E-mail

For technical support through the Internet, e-mail us at:

support.vsreports@componentone.com

To help us provide you with the best support, please include the following information when contacting ComponentOne:

•

Your ComponentOne product serial number.

•

The version and name of your operating system.

•

Your development environment and its version.

For more information on technical support, go to:

www.componentone.com/support


Peer-to-Peer Newsgroup

ComponentOne also sponsors peer-to-peer newsgroups for users. ComponentOne does not offer formal technical support in this newsgroup, but instead sponsors it as a forum for users to post and answer each other's questions regarding our products. However, ComponentOne may monitor the newsgroups to ensure accuracy of information and provide comments when necessary. You can access the newsgroup from the ComponentOne Web site at www.componentone.com/newsgroups.


Introduction

VSView Reporting Edition consists of three main components: the VSReport control, the VSPrinter control, and the VSReport Designer application.

VSReport8 Control

VSPrinter8 Control

The VSReport8 Designer

The Overall Picture


VSReport8 Control

The VSReport8 control is an invisible control that reads report definitions stored in XML files, combines them with data from ADO recordsets, and generates reports that can be previewed, printed, or saved to files. The control can export reports in HTML, DHTML, PDF, and Text file formats, and in a form usable by the VSPrinter8 control. The control can be distributed royalty-free with your applications.

The control uses an object model largely based on Microsoft Access reports, and it supports most features found in Access reports, including:

1.

A Microsoft Access-style banded-report model based on Groups, Sections, and Fields. (These objects are fully exposed by the object model, so you can write your own report designers.)

2.

Fields may be bound to simple and binary (object) database fields.

3.

Fields may contain VBScript expressions, including extensions for aggregate expressions (Sum, Max, Average, etc.), and have access to the control's object model.

4.

Reports may contain event handlers, making them independent of the host application.

5.

Reports may contain Subreports

6.

Reports may contain parameterized queries, allowing the user to constrain the data that should be included in the report.

7.

Report definitions may be saved within the control at design time, or loaded at run time from XML report definition files.


VSPrinter8 Control

The VSPrinter8 control provides VSReport8 with printing and previewing capabilities. It can be used to create documents without VSReport8, and has a rich feature set of its own.

To preview a report, you need both controls. VSReport8 reads data from a database and formats it according to the report definition, then sends its output to the VSPrinter8 control.

If you only want to create reports and save them into HTML or PDF files, you don't need to use a visible instance of the VSPrinter control on your form. However, VSReport8 uses VSPrinter internally, so VSPrinter needs to be installed and registered on the user's computer even if you are not using a visible instance of it. The control can be distributed royalty-free with your applications.


The VSReport8 Designer

The VSReport8 Designer is an application that can create, edit, load, and save report definition files. Report definition files are XML files that may contain multiple reports, and can be read directly by the VSReport8 control.

The Designer can import report definitions from Microsoft Access MDB files and from VSReport 1.0 VSR files. Note that importing from MDB files requires Microsoft Access to be present on the computer at the time the files are imported.

The Designer has a user interface similar to the Microsoft Access report designer, including a Wizard used to create new reports.

The primary user of the Designer will be the developer. While it may be beneficial in some applications for the end-user to have access to the designer, it is licensed on a per-seat basis, and thus may require additional licenses for distribution to end-users.

The Designer was written using the VSReport8 and VSPrinter8 controls. It does not use any "undocumented" properties or methods, so anything the Designer does, your applications can do.

To find out how to use the Designer, see the Using the VSReport8 Designer chapter.


The Overall Picture

The diagram below shows the relationship between the components in the VSView Reporting Edition package.

Boxes with a bold border represent code components (controls and applications).

Boxes with a thin border represent files containing information (report definitions, data, finished reports).

Numbered arrows indicate relationships between components, described below:

1.

Use the VSReport8 Designer to create, edit, and save XML report definition files.

2.

The VSReport8 control loads report definitions from the XML files created with the Designer. This can be done at design time using the "Load Report" property page (in this case the XML file is persisted with the control and not needed at run time) , or at run time using the Load method.

3.

The VSReport8 control automatically loads data from the OLEDB data source specified in the report definition file. Alternatively, you can provide your own custom recordset (ADO, DAO, or custom recordsets are supported).

4.

The VSReport8 control formats the data according to the report definition and renders reports to a VSPrinter8 control, which provides printing, previewing, and export services.

5.

The VSPrinter8 control can be used to preview the report, with full document navigation, zooming, panning, and multi-page views. It can also export reports to several file formats, including HTML, PDF, VP (VSPrinter native format), and plain text.

6.

Your custom applications can communicate with the VSReport8 control using a rich object model, so you can easily customize your reports or generate entirely new ones. The VSReport8 Designer is a good example of such an application.

The object model for the VSReport8 control is summarized below. It is largely based on the Microsoft Access model, except that where Access has different types of controls (label control, textbox control, line control, etc.), VSReport8 has a single Field object with properties that can make it look like a label, textbox, line, picture, subreport, etc. The table below lists all objects, along with their main properties and methods.

Report Object: the VSReport8 control.

Render, RenderToFile, Load, Copy, Clear, GetReportInfo, DoEvents, IsBusy,
Cancel, MaxPages, ReportName, Font, OnOpen, OnClose, OnNoData,
OnPage, OnError, Execute, Evaluate

Layout Object: determines how the report will be rendered on the page.

Width, MarginLeft, MarginTop, MarginRight, MarginBottom, Orientation, Columns,
ColumnLayout, PageHeader, PageFooter, Picture, PictureAlign, PictureShow

DataSource Object: manages the source recordset.

ConnectionString, RecordSource, Filter, MaxRecords, Recordset,
FieldInfo, GetRecordSource

Groups Collection: a report may have many groups.

Group Object: controls data sorting and grouping

Name, GroupBy, Sort, KeepTogether, SectionHeader, SectionFooter, Move

Sections Collection: all reports have at least 5 sections.

Section Object: a container for Field objects.

Name, Type, Visible, Height, CanGrow, CanShrink, Repeat,
KeepTogether, ForcePageBreak, BackColor, OnFormat, OnPrint

Fields Collection: a report usually has many Fields.

Field Object: a rectangular area within a section where information is displayed.

Name, Text, Calculated, Value, Format, Left, Top, Width, Height, Visible, Font,
Align, WordWrap, BackColor, ForeColor, BorderColor, BorderStyle, LineSlant,
LineWidth, CanGrow, CanShrink, MarginLeft, MarginRight, MarginTop,
MarginBottom, LineSpacing, Section, ForcePageBreak, HideDuplicates,
RunningSum, Picture, PictureAlign, Subreport, CheckBox, RTF

Every report has at least five sections, indexed as follows:

Section | Description
0 - vsrDetail | This section contains fields that are rendered once for each record in the source recordset.
1 - vsrHeader | The report header section is rendered at the beginning of the report.
2 - vsrFooter | The report footer section is rendered at the end of the report.
3 - vsrPageHeader | The page header section is rendered at the top of every page (except optionally for pages that contain the report header).
4 - vsrPageFooter | The page footer section is rendered at the bottom of every page (except optionally for pages that contain the report footer).

In addition to these five sections, there are two additional sections for each group: a group header and a group footer section. For example, a report with 3 grouping levels will have 11 sections.

Note that sections can be made invisible, but they cannot be added or removed (except by adding or removing groups.)

The diagram below shows how each section is rendered on a typical report:

The first section rendered is the report header. This section usually contains information that identifies the report.

Then comes the page header. If the report has no groups, this section usually contains labels that describe the fields in the detail section.

The next sections are the group headers, detail, and group footers. These are the sections that contain the actual report data. Group headers and footers often contain aggregate functions such as group totals, percentages, maximum and minimum values, and so on. Group headers and footers are inserted whenever the value of the expression specified by the GroupBy property changes from one record to the next.

The detail section contains data for each record. It is possible to hide this section by setting its Visible property to False, and display only group headers and footers. This is a good way to create summary reports.

At the bottom of each page is the page footer section. This section usually contains information such as the page number, total number of pages in the report, and/or the date the report was printed.

Finally, the report footer section is printed before the last page footer. This section is often used to display summary information about the entire report.

You can determine whether or not a section is visible by setting its Visible property to True or False. Group headers can be repeated at the top of every page (whether or not it is the beginning of a group) by setting their Repeat property to True. Page headers and footers can be removed from pages that contain the report header and footer sections by setting the PageHeader and PageFooter properties on the Layout object.


Using VSView Reporting Edition

Although you can use VSView Reporting Edition in many different scenarios, on the desktop and on the Web, the main sequence of steps is always the same:

1: Create a report definition

This can be done directly with the VSReport8 Designer or using the report designer in Microsoft Access and then importing it into the VSReport8 Designer (the Designer is described below). You can also do it using code, either using the object model to add groups and fields or by writing a custom XML file.

You can also use the Designer to preview the report and make sure it looks the way you want.

2: Load the report into the VSReport8 control

This can be done at design time, using the "Load Report" property page, or at run time using the Load method. If you load the report at design time, it will be persisted (saved) with the control and you won't need to distribute the report definition file.

3: Render the report (desktop applications)

If you are writing a desktop application, you can render the report into a VSPrinter control using the Render method. The VSPrinter control will display the report on the screen, and users will be able to preview it with full zooming, panning, etc. Users will also be able to print the report directly from the VSPrinter control.

4: Render the report (web applications)

If you are writing a Web application, you can export the reports into HTML or PDF files using the RenderToFile method, and your users will be able to view them using any browser.

In Intranet scenarios, you can also export VSPrinter files (VP) and use the VSPrinter control hosted on an HTML page as a viewer (requires ActiveX support in the browser).

Creating a Report Definition Using Code

Add Grouping and Sorting Using Code

Typical Usage Scenarios

VBScript Expressions

Advanced Topics


Creating a Report Definition Using Code

The easiest way to create new report definitions is to use the VSReport8 Designer, but you can also create reports from scratch, using code. This approach requires some extra work, but it gives you complete flexibility. You can write your own report designer or ad-hoc report generator.

Note that creating a report definition is not the same as rendering a report. To render a report, you can simply load an existing definition and call the Render method.

The example that follows uses Visual Basic to create a simple tabular report definition based on the NorthWind database. The code is commented and illustrates most important elements of the VSReport8 control object model.

NOTE: Make sure that your Microsoft ODBC Data Source is pointing to the NWIND.MDB and that the name is set as Northwind.

First, add the VSReports and VSPrinter control on the form. Add a command button. Set the following properties:

Name | Type
VSR | VSReport
VP | VSPrinter
CreateReportDefinition | Command Button

Second, we initialize the control using the Clear method to clear its contents and setting the control font (this is the font that will be assigned to new fields):

Private Sub CreateReportDefinition_Click()

Dim f As Field ' variable used to hold new fields

' initialize control

With vsr

.Clear ' clear any existing fields

.FontName = "Tahoma" ' set default font for all controls

.FontSize = 9

End With

Next, we set up the DataSource Object that will retrieve the data we want from the NorthWind database. This is done using the ConnectionString and RecordSource properties, just like you do with the Microsoft ADO DataControl:

' initialize DataSource

With vsr.DataSource

.ConnectionString = "dsn=NorthWind"

.RecordSource = "Employees"

End With

Next, we initialize the Layout object that defines how the report will be laid out on the page. In this case, we'll render the report in Portrait mode and set its Width to 6.5 inches (that's 8.5 minus one inch for margins on each side):

' initialize Layout

With vsr.Layout

.Orientation = vsrPortrait

.Width = 6.5 * 1440 ' 8.5 - margins

End With

Now comes the interesting part. Every report has five basic sections: detail, report header, report footer, page header, and page footer. We'll set up the report header by setting a couple of properties and adding a title field to it.

' create a report header

With vsr.Sections(vsrHeader)

.Height = 1440

.Visible = True

.BackColor = RGB(200, 200, 200) ' solid background

Set f = .Fields.Add("FldTitle", "Employees Report", _

0, 0, 8000, 1440)

f.FontSize = 24

f.FontBold = True

f.ForeColor = RGB(0, 0, 100)

End With

The section object has a Fields collection. The collection's Add method creates a new field and assigns it to the section. The parameters specify the new field's Name, Text, Left, Top, Width, and Height properties. By default, the field has the same font as the control. Since this is a title, it makes sense to change the font and make it larger. Note that the field should be tall enough to accommodate the font size, or nothing will appear in it.

Next, we'll set up the page footer section. This section is more interesting because it contains calculated fields. Calculated fields contain VBScript expressions in their Text property, which are evaluated when the report is rendered. To make a field calculated, set it's Calculated property to True.

' create a page footer

With vsr.Sections(vsrPageFooter)

.Height = 500

.Visible = True

Set f = .Fields.Add("FldFtrLeft", _

"""Employees: Printed on "" & Now", _

0, 0, 4000, 300)

f.Calculated = True

Set f = .Fields.Add("FldFtrRight", _

"""Page "" & Page & "" of "" & Pages", _

4000, 0, 4000, 300)

f.Calculated = True

f.Align = vsrRightTop

f.Width = vsr.Layout.Width - f.Left

Set f = .Fields.Add("FldLine", "", _

0, 0, vsr.Layout.Width, 20)

f.LineSlant = vsrLSNoSlant

f.BorderStyle = vsrBSSolid

f.BorderColor = RGB(0, 0, 100)

End With

The page footer section uses expressions with variables that are not intrinsic to VBScript, but are defined by VSReport8. Page and Pages are variables that contain the current page number and the total page count. The section also uses a field configured to look like a line. This is done using the BorderStyle and LineSlant properties.

Next, we'll set up the page header section. This section gets rendered at the top of every page and will display the field labels. Using a page header section to display field labels is a common technique in tabular reports. The code is simple, but looks a bit messy because of all the field measurements. In a real application, these values would not be hard-wired into the program.

' create a page header with field labels

With vsr.Sections(vsrPageHeader)

.Height = 500

.Visible = True

vsr.FontBold = True

Set f = .Fields.Add("LblID", "ID", 0, 50, 400, 300)

f.Align = vsrRightTop

Set f = .Fields.Add("LblFirstName", "First", _

500, 50, 900, 300)

Set f = .Fields.Add("LblLastName", "Last", _

1500, 50, 900, 300)

Set f = .Fields.Add("LblTitle", "Title", 2500, 50, 1900, 300)

Set f = .Fields.Add("LblTitle", "Notes", 4500, 50, 8000, 300)

vsr.FontBold = False

Set f = .Fields.Add("FldLine", "", _

0, 400, vsr.Layout.Width, 20)

f.LineSlant = vsrLSNoSlant

f.LineWidth = 50

f.BorderStyle = vsrBSSolid

f.BorderColor = RGB(100, 100, 100)

End With

The code above illustrates a powerful technique for handling fonts. Since every field inherits the control font when it is created, we set the control's FontBold property to True before creating the fields, and set it back to False afterwards. As a result, all controls in the page header section have a bold font.

To finalize the report, we will add the detail section. This is the section that shows the actual data. It has one calculated field below each label in the page header section.

' create the detail section

With vsr.Sections(vsrDetail)

.Height = 330

.Visible = True

Set f = .Fields.Add("FldID", "EmployeeID", 0, 0, 400, 300)

f.Calculated = True

Set f = .Fields.Add("FldFirstName", "FirstName", 500, 0, 900, 300)

f.Calculated = True

Set f = .Fields.Add("FldLastName", "LastName", 1500, 0, 900, 300)

f.Calculated = True

Set f = .Fields.Add("FldTitle", "Title", 2500, 0, 1900, 300)

f.Calculated = True

Set f = .Fields.Add("FldNotes", "Notes", 4500, 0, 8000, 300)

f.Width = vsr.Layout.Width - f.Left

f.Calculated = True

f.CanGrow = True

f.FontSize = 6

f.Align = vsrJustTop

Set f = .Fields.Add("FldLine", "", 0, 310, vsr.Layout.Width, 20)

f.LineSlant = vsrLSNoSlant

f.BorderStyle = vsrBSSolid

f.BorderColor = RGB(100, 100, 100)

End With

Note that all fields are calculated, and their Text property corresponds to the names of fields in the source recordset. Setting the Calculated property to True ensures that the Text property is interpreted as a database field name, as opposed to being rendered literally. It is important to adopt a naming convention for report fields that makes them unique, different from recordset field names. If you had two fields named "LastName", an expression such as "Left(LastName,1)" would be ambiguous. In this example we have adopted the convention of beginning all report field names with "Fld".

Note also that the "FldNotes" field has its CanGrow property set to True, and a smaller font than the others. This was done because the "Notes" field in the database contains a lot of text, and we want it all to appear in the report. Rather than make the field very tall and waste space, setting the CanGrow property to True tells the control to expand the field as needed to fit its contents; it also sets the containing section's CanGrow property to True, so the field doesn't spill off the section.

The report definition is done. To render it, all it takes is one line of code:

' render the report into the VSPrinter control

vsr.Render vp

End Sub

This renders the report into a VSPrinter control named vp, that displays the report on the screen. Here's what the report looks like:


Add Grouping and Sorting Using Code

Useful reports don't simply show data, they show it in an organized manner. VSReport8 uses groups to group and sort data. To demonstrate how this works, let's go back to our example and show the employees grouped by country.

The following code creates a group object that sorts and groups records by country. (It should be added to the previous code before the last block.)

' group employees by country, in ascending order

Dim grp As Group

Set grp = vsr.Groups.Add("GrpCountry", "Country", vsrAscending)

Every group has a header and a footer section. These are invisible by default, but we want to make the header section visible and show which country defines the group. The code is similar to what we used before to create the other sections, but this time we'll use a field with a solid background to make things a little different:

With grp.SectionHeader

.Height = 500

.Visible = True

Set f = .Fields.Add("CtlCountry", "Country", _

0, 0, vsr.Layout.Width, 500)

f.Calculated = True

f.Align = vsrLeftMiddle

f.FontBold = True

f.FontSize = 12

f.BorderStyle = vsrBSSolid

f.BorderColor = RGB(0, 0, 150)

f.BackStyle = vsrOpaque

f.BackColor = RGB(150, 150, 220)

f.MarginLeft = 100

End With

To finish the new report, let's add another group to sort the employees within each country by their first name. Since we are only using this group to sort the names, we'll leave the header and footer sections invisible.

' sort employees by first name within each country

vsr.Groups.Add "GrpName", "FirstName", vsrAscending

We're done with our changes. To render the new report, we need to finish the routine with a call to the Render method, as before:

' render the report into the VSPrinter control

vsr.Render vp

End Sub

And here's what the new report looks like:


Typical Usage Scenarios

This section describes how you can use VSView Reporting Edition in typical desktop and web scenarios.


Desktop Scenarios

In typical desktop scenarios, VSReport8 runs on the same computer where the reports will be generated and viewed (the report data itself may still come from a remote server).

These scenarios assume that VSReport8 will be hosted in a Visual Basic or Visual C++ application (other platforms, such as Borland C++ Builder, are supported as well, although not specifically mentioned in this documentation).

Scenario 1: Embedded Reports

Under this scenario, an application generates reports using a fixed set of report definitions that are built into the application. This type of application does not rely on any external report definition files, and end-users have no way to modify the reports.

The main advantage of this type of application is that you don't need to distribute the report definition file, and you can be sure that no one will modify the report format. The disadvantage is that to make any modifications to the report, you must recompile the application.

To create an application with embedded reports, follow these steps:

1.

Use the VSReport8 Designer to create all the reports you will need. (See the Designer documentation below for details on how to do this.)

2.

Add one VSReport8 control for each report definition you want to distribute. You may want to name each control after the report it will render (this will make your code easier to maintain).

3.

Use the Load Report property page to load the report definitions into each respective control. To access the Load Report property page, right click the control and select Properties from the context menu. The property page looks like this:

To load a report, click the "..." button to select the report definition file you created in step 1, then select the report from the drop-down list and click the Load button. The property page will show the name of the report you selected and a count of groups, sections, and fields.

4.

Add a single VSPrinter control to the form and also add a control that will allow the user to pick a report (this could be a menu, a list box, or a group of buttons.)

5.

Add code to render the report selected by the user. For example, if you added a group of buttons in step 4, the code would look like this:

Private Sub btnProductsReport_Click()

vsrProducts.Render vp

End Sub

Where vsrProducts is the name of the VSReport8 control that contains the report selected by the user and vp is the single VSPrinter control on the form.

Scenario 2: Reports Loaded at Run-Time

Under this scenario, an application loads reports definitions from a file at run time. This type of application requires a report definition file and works like a viewer.

The main advantage of this type of application is that if you modify the report format, there's no need to update the application. Simply send the new report definition file to the users and you are done.

To create an application with reports loaded at run-time, follow these steps:

1.

Use the VSReport8 Designer to create all the reports you will need. (See the Designer documentation for details on how to do this.)

2.

Add a VSReport8 and a VSPrinter control to the application.

3.

Add code to read the report definition file and build a list of all reports in it. This can be done as follows:

' get a tab-separated list all reports

' in the definition file

sFile = App.Path & "\MyReports.xml"

sList = vsr.GetReportInfo(sFile, vsrRIList)

vList = Split(sList, vbTab)

' populate list box

cmbReport.Clear

For i = 0 To UBound(vList)

cmbReport.AddItem vList(i)

Next

The code uses the GetReportInfo method to retrieve a tab-separated list of all reports contained in the "MyReports.xml" report definition file (created in step 1), then parses the list and populates a listbox.

4.

Add code to render the report selected by the user. For example:

Private Sub Command1_Click()

' no reentrancy

If vsr.IsBusy Then Exit Sub

' render report

On Error Resume Next

vsr.Render vp

If Err.Number <> 0 Then

MsgBox "Error " & Err.Number & _

vbCrLf & Err.Description

End If

End Sub

Note that the IsBusy property is used to prevent the user from starting the report a second time while it is still being rendered.

Scenario 3: Customizable Reports

This scenario is a variation on the above. It consists of loading the basic report definitions from a file, then writing code to customize the reports according to user selections.

For example, the code below changes the font used in the detail section:

Dim i%, strDetailFont$

strDetailFont = "Arial Narrow"

With vsr.Sections(vsrDetail).Fields

For i = 0 To .Count - 1

.Item(i).FontName = strDetailFont

Next

End With

The code below toggles the display of a group by turning its Sort property on or off and setting the Visible property of the group's header and footer sections:

Dim bShowGroup As Boolean

bShowGroup = True

With vsr.Groups(0)

If bShowGroup Then

.SectionHeader.Visible = True

.SectionFooter.Visible = True

.Sort = vsrAscending

Else

.SectionHeader.Visible = False

.SectionFooter.Visible = False

.Sort = vsrNoSort

End If

End With

These samples illustrate some of the things you can do to customize reports. There are infinite possibilities, because the object model offers access to every aspect of the report. (In fact, you can create whole reports entirely through code).


Web Scenarios

In typical web scenarios, VSReport8 runs on the server machine and creates reports either in batch mode or on demand. The user can select the reports and preview or print them on the client machine, using a web browser.

Scenario 1: Static Web Reports

This scenario is based on a server application that runs periodically and creates a predefined set of reports, saving them to HTML or PDF files. These files are referenced by web pages on your site, and they are downloaded to the client machine like any other web page.

To implement this type of application, follow these steps:

1.

Use the VSReport8 Designer to create all the reports you will need. (See the Designer documentation for details on how to do this.)

2.

Create an application on the server that contains a VSReport8 control. If you don't want to use forms and windows, create the control using the CreateObject function in Visual Basic or CoCreateInstance in Visual C++.

3.

Add a routine that runs periodically and updates all the reports you want to make available to your users. The loop would look like this:

' ** this runs every 6 hours:

' get a tab-separated list all

' reports in the definition file

sFile = App.Path & "\MyReports.xml"

sList = vsr.GetReportInfo(sFile, vsrRIList)

vList = Split(sList, vbTab)

' refresh the reports on the server

For i = 0 To UBound(vList)

vsr.Load sFile, vList(i)

vsr.RenderToFile "Reports\Auto\" & _

vList(i) & ".htm", vsrHTMLPaged

Next

The code uses the GetReportInfo method to retrieve a tab-separated list of all reports contained in the "MyReports.xml" report definition file (created in step 1), then parses the list and exports each report to a paged HTML file. (Paged HTML files contain one HTML page for each page in the original report, and all pages are hyperlinked.)

4.

Edit the "home" HTML page by adding links to the reports that were saved.

You are not restricted to HTML. VSReport8 can also export to PDF files, which can be viewed on any browser with freely available plug-ins. The PDF format is actually superior to HTML in many ways, especially when it comes to producing hard copies of your web reports.

Another option you have is saving the reports into VSPrinter format and using the VSPrinter control as a viewer. To do this, you would host the VSPrinter control on an HTML page and use its URL property to load the report from the server. This solution gets you the same quality you would have with the PDF alternative, without using any plug-ins. The drawback is that only Internet Explorer can host ActiveX controls, so people using other browsers would not be able to see the reports. This makes this option most suitable to Intranet environments.

Scenario 2: Dynamic Web Reports

In this scenario, reports are created on-demand, possibly based on data supplied by the user. This type of solution typically involves using an ASP page that presents a form to the user and collects the information needed to create the report, then creates a VSReport8 control to render the report into a temporary file, and returns a reference to that file.

The example that follows is a simple ASP page that allows users to enter some information and to select the type of report they want. Based on this, the ASP code creates a custom version of the NorthWind Employee Sales by Country report and presents it to the user in the selected format.

The sample uses a temporary file on the server to store the report. In a real application, you would have to generate unique file names and delete them after a certain time, to avoid overwriting reports before the users get a chance to see them. Despite this, the sample illustrates the main techniques involved in delivering reports over the web with VSReport8.

The ASP page starts by including a couple of header files that define control constants, and some standard HTML:

<html>

<head>

<meta http-equiv="Content-Type"

content="text/html; charset=iso-8859-1">

<title>VSReport8 ASP Sample</title>

</head>

<!--#include file="VSPrinterVBS.inc" -->

<!--#include file="VSReportVBS.inc" -->

<style type='text/css'>

body {font:10pt Arial;}

</style>

<body>

<p><font size=5 face=Verdana>

<b>VSReport8 ASP Sample</b></font></p>

<p>

This sample demonstrates how you can use the ComponentOne

<b>VSReport8</b> control to generate custom Web

reports from an ASP page.

</p>

<hr>

Note that this code includes two files, VSPrinterVBS.inc and VSReportVBS.inc, which contain definitions for all constants used by the controls. These files are included in the distribution disk, along with the ASP sample. Although these constants are not strictly necessary (you could type their values directly into the code), they do make the code more readable.

After this introduction, the page contains a form where the user can enter the year for the report, the sales goal for the employees that year, and buttons that generate different types of reports. There are three options: drill-down HTML, PDF, and VSPrinter format. When the user clicks a button, the page is submitted and the ASP script can process the data:

<form>

<p><b>Employee Sales by Country Report</b></p>

<p>Report for Year:

<input type=text name=theYear

value='<%= Request("theYear") %>'></p>

<p>Sales Goal:

<input type=text name=theQuota

value='<%= Request("theQuota") %>'></p>

<p><input type=submit name=docType value=' 1 '>

&nbsp;&nbsp;Click here to create an HTML report.

</p>

<p><input type=submit name=docType value=' 2 '>

&nbsp;&nbsp;Click here to create a PDF report.

You will need Adobe's PDF plug-ins to see the report.

</p>

<input type=submit name=docType value=' 3 '>

&nbsp;&nbsp;Click here to create a VSPrinter report.

You will need the VSPrinter control to see the report.

</p>

</form>

<hr>

Now comes the interesting part of the sample. The first time the page is displayed, it only shows the form. When the page is submitted, the following script gets executed for the second time and generates the report based on the contents of the theYear, theQuota, and docType variables.

<%

' get path to use when saving temp files

thePath = Request.ServerVariables("PATH_TRANSLATED")

i = InstrRev(thePath, "\")

thePath = Left(thePath, i)

' create document and insert it in this page

docType = Request("docType")

Select Case docType

Case " 1 ": CreateDocHTML

Case " 2 ": CreateDocPDF

Case " 3 ": CreateDocVSPrinter

Case Else: Response.Write _

"<p>Click a button to select a report.</p>"

End Select

This code simply interprets the user input and delegates the job to the appropriate function. The main part of the code is the function that creates the report and stores it in a temporary file. Here it is:

' create VSReport8 document and save it on the server

Sub CreateDoc(sFileName)

' create VSReport8 object

set vsr = CreateObject("VSReport8.VSReport")

' load report definition

vsr.Load thePath & "NWind.xml", _

"Employee Sales by Country"

' validate the information submitted by the user

theYear = CLng(Request("theYear"))

theQuota = CLng(Request("theQuota"))

If theYear < 1994 Then theYear = 1994

If theYear > 1996 Then theYear = 1996

' customize the report's RecordSource

sSQL = "SELECT DISTINCTROW " & _

"Employees.Country, Employees.LastName, " & _

"Employees.FirstName, Orders.ShippedDate, Orders.OrderID, " & _

" [Order Subtotals].Subtotal AS SaleAmount " & _

"FROM Employees INNER JOIN (Orders INNER JOIN " & _

" [Order Subtotals] ON Orders.OrderID = " & _

" [Order Subtotals].OrderID) " & _

" ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE Year(Orders.ShippedDate) = " & theYear & ";"

vsr.DataSource.RecordSource = sSQL

' customize the report's event handlers

sScript = "If SalespersonTotal > " & theQuota & " Then " & vbCrLf & _

" ExceededGoalLabel.Visible = True " & vbCrLf & _

" SalespersonLine.Visible = True " & vbCrLf & _

"Else " & vbCrLf & _

" ExceededGoalLabel.Visible = False " & vbCrLf & _

" SalespersonLine.Visible = False " & vbCrLf & _

"End If"

vsr.Sections(vsrGroupHeader2).OnPrint = sScript

' render report to temp file on the server

If Instr(sFileName, ".htm") > 0 Then

vsr.RenderToFile sFileName, vsrHTMLDrillDown

ElseIf Instr(sFileName, ".pdf") > 0 Then

vsr.RenderToFile sFileName, vsrPDF

ElseIf Instr(sFileName, ".vp") > 0 Then

vsr.RenderToFile sFileName, vsrVSPrinter

End If

' we're done with the object

Set vsr = Nothing

End Sub

The function creates a VSReport8 control, loads the report definition, and customizes it by changing the RecordSource and OnPrint properties to incorporate the parameters supplied by the user. Then the function uses the RenderToFile method to render the report into a temporary file on the server. The format used is deduced from the file extension.

We're almost done. Now that the report has been saved into a file on the server, all we have to do is make it available to the user. Here's how you can do that:

Sub CreateDocHTML()

' create HTML report

sFileName = thePath & "temp.htm"

CreateDoc(sFileName)

' read HTML document into a variable and

' delete temporary file

const ForReading = 1

set fso = CreateObject("Scripting.FileSystemObject")

set f = fso.OpenTextFile(sFileName, ForReading)

s = f.ReadAll

f.Close

fso.DeleteFile(sFileName)

Set fso = Nothing

' insert HTML document in output stream

Response.Write "<p>Click headings to collapse/expand groups.</p>"

Response.Write s

End Sub

This function calls CreateDoc to create the HTML report, then reads the whole report file and inserts it directly into the page. This approach is good for short reports such as the one we are using. For longer reports, you would probably want to use the paged HTML file and insert a link to the first page of the report. In this sample, we are using the HMTL drill-down flavor. This allows users to click on group headers to collapse and expand the groups.

Next comes the function used to create and deliver the PDF report. It is similar to the HTML function, but even simpler:

Sub CreateDocPDF()

' create HTML report

sFileName = thePath & "temp.pdf"

CreateDoc(sFileName)

' create link to new PDF file

s = "<p><a href=""http://dell/test/temp.pdf"">"

s = s & "Click here to see the PDF report.</a></p>"

Response.Write s

End Sub

This function inserts a link into the main document. The user can click on the link to see the PDF report (provided he has the necessary Adobe plug-ins installed on his computer).

Finally, here is the function that delivers the report using the VSPrinter control as a viewer:

Sub CreateDocVSPrinter()

' create VSPrinter report

sFileName = thePath & "temp.vp"

CreateDoc(sFileName)

' create VSPrinter control on the client and set its URL property

' to read the newly created document

s = "<object classid='clsid:A8561647-E93C-11D3-AC3B-CE6078F7B616' " & _

"id=vp width=497 height=609>"

Response.Write s

Response.Write "<param name=URL value='temp.vp'>"

Response.Write "<param name=ZoomMode value=3>" ' zmWholePage

Response.Write "</object>"

End Sub

%>

The function inserts a VSPrinter object on the page (using its unique ClassID value), and sets the VSPrinter's URL property to the name of the temporary file. When the VSPrinter control is initialized, it will download the file and show it on the page, where the user will be able to browse and print the report.

That is the end of the ASP code. To finish the page, don't forget to close the body and html tags:

</body>

</html>

That's the end of the ASP sample. It contains about 100 lines of code and 50 of HTML. That's not a lot when you consider that it can create custom reports and deliver them on the web in three different formats.

The picture below shows what the result looks like in the browser, after selecting the HTML output option:


VBScript Expressions

VSReport8 relies on VBScript to evaluate expressions in calculated fields and to handle report events (the difference between report events and control events is discussed below).

VBScript is a full-featured language, and you have access to all its methods and functions when writing VSReport8 expressions. This document does not cover the intrinsic features of the VBScript language, which is documented in many books and web sites, as well as on the Microsoft Developer's Network (MSDN).

VSReport8 extends VBScript by exposing additional objects, variables, and functions. These extensions are described below:


Objects and Variables

1) Data Field Names

Names of fields in the report's source recordset are evaluated and return the current field value. If a field name contains spaces or periods, it must be enclosed in square brackets. For example:

OrderID

[Customer.FirstName]

[Name With Spaces]

2) Report Field Names

Names of Field objects are evaluated and return a reference to the object, so you can access the field's properties). The default property for the Field object is Value, so by itself the field name returns the field's current value. For example:

MyField.BackColor = RGB(200,250,100)

MyField.Font.Size = 14

MyField * 2 ' (same as MyField.Value * 2)

NOTE: if you give a report field the same name as a data field, you won't be able to access the report field.

3) Report Section Names

Names of Section objects are evaluated and return a reference to the object, so you can access the section's properties. The default property for the Section object is Name. For example:

If Page = 1 Then [Page Footer].Visible = False

4) Report Object

Returns a reference to the control object, so you can access the full VSReport8 object model from your scripts and expressions. For example:

"Fields: " & Report.Fields.Count

5) Page Variable

Returns or sets the value of the Page property. This property is initialized by the control when it starts rendering a report, and is incremented at each page break. You may reset it using code. For example:

If Country <> LastCountry Then Page = 1

LastCountry = Country

6) Pages Variable

Returns a token that gets replaced with the total page count when the report finishes rendering. This is a read-only property that is typically used in page header or footer fields. For example:

"Page " & Page & " of " Pages

7) Cancel

Set to True to cancel the report rendering process. For example:

If Page > 100 Then Cancel = True

8) Compatibility Functions

To increase compatibility with code written in Visual Basic and Microsoft Access (VBA), VSReport8 exposes two functions that are not available in VBScript: IIf and Format.

IIf evaluates a boolean expression and returns one of two values depending on the result. For example:

IIf(SalesAmount > 1000, "Yes", "No")

Format converts a value into a string formatted according to instructions contained in a format expression. The value may be a number, date, time, boolean or string. The format is a string built using syntax similar to the format string used in Visual Basic or VBA.

The table below describes the syntax used for the format string:

Value Type

Format String

Description

Number

Percent, %

Formats a number as a percentage, with zero or two decimal places. For example:
Format(0.33, "Percent") = "33%"
Format(0.33, "Percent") = "33%"
Format(0.3333333, "Percent") = "33.33%"

#,###.##0

Formats a number using a mask. The following symbols are recognized:
# digit placeholder
0 digit placeholder, force display
, use thousand separators
( enclose negative values in parenthesis
% format as percentage
For example:
Format(1234.1234, "#,###.##") = "1,234.12"
Format(-1234, "#.00") = "(1234.12)"
Format(.1234, "#.##") = ".12"
Format(.1234, "0.##") = "0.12"
Format(.3, "#.##%") = "30.00%"

Currency

Currency, $

Formats a number as a currency value. For example:
Format(1234, "$") = "$1,234.00"

Boolean

Yes/No

Returns "Yes" or "No".

Date

Long Date

Format(#12/5/1#, "long date") = "December 5, 2001"

Short Date

Format(#12/5/1#, "short date") = "12/5/2001"

Medium Date

Format(#12/5/1#, "medium date") = "05-Dec-01"

q,m,d,w,yyyy

Returns a date part (quarter, month, day of the month, week of the year, year. For example:
Format(#12/5/1#, "q") = "4"

String

@@-@@/@@

Formats a string using a mask. The "@" character is a placeholder for a single character (or for the whole value string if there is a single "@"). Other characters are interpreted as literals. For example:
Format("AC55512", "@@-@@/@@") = "AC-555/12"
Format("AC55512", "@") = "AC55512"

@;Missing

Uses the format string on the left of the semi-colon if the value is not null or an empty string, otherwise returns the part on the right of the semi-colon. For example:
Format("@;Missing", "UK") = "UK"
Format("@;Missing", "") = "Missing"

NOTE: VBScript has its own built-in formatting functions (FormatNumber, FormatCurrency, FormatPercent, FormatDateTime, etc). You may use them instead of the VBA-style Format function described here, if you prefer.

7) Aggregate Functions

Aggregate functions are used to summarize data over the group being rendered. When used in a report header field, these expressions return aggregates over the entire recordset. When used in group headers or footers, they return the aggregate for the group.

All VSReport8 aggregate functions take two arguments:

1.

A string containing a VBScript expression to be aggregated over the group, and

2.

An optional string containing a VBScript expression used as a filter (domain aggregate). The filter expression is evaluated before each value is aggregated. If the filter returns False, the value is skipped and is not included in the aggregate result.

VSReport8 defines the following aggregate functions:

Function | Description
Avg | Average value of the expression within the current group. For example, the expressions below calculate the average sales for the whole group and the average sales for a certain type of product: Avg(SalesAmount) Avg(SalesAmount, ProductType = 3)
Sum | Sum of all values in the group.
Count | Count of records in the group with non-null values. Use an asterisk for the expression to include all records. For example, the expressions below count the number of employees with valid (non-null) addresses and the total number of employees: Count(Employees.Address) Count(*)
Min, Max | Minimum and maximum values for the expression. For example: "Min Sale = " & Max(SaleAmount)
StDev, Var | Standard deviation and variance of the expression in the current group. These values are calculated using the sample (n-1) formulas, as in SQL and Microsoft Excel.
StDevP, VarP | Standard deviation and variance of the expression in the current group. These values are calculated using the population (n) formulas, as in SQL and Microsoft Excel.

The next section explains how to use aggregate functions in detail, including how they work in the context of a report and how to use them efficiently.


Using Aggregate Functions

To use the aggregate functions, add a calculated field to a section header or footer section, and assign the expression to the field's Text property.

For example, the "Employee Sales by Country" report in the sample NWind.xml file contains several aggregate fields. The report groups records by Country and by Employee.

The SalespersonTotal field in the footer section of the Employee group contains the following expression:

Sum([SaleAmount])

Because the field is in the Employee group footer, the expression returns the total sales for the current employee.

The CountryTotal and GrandTotal fields contain exactly the same expression. However, because these fields are in the Country group footer and report footer, the expression returns the total sales for the current country and for the entire recordset.

You may need to refer to a higher-level aggregate from within a group. For example, in the "Employee Sales by Country" report, there is a field that shows sales in the current country as a percentage of the grand total. Since all aggregates calculated within a country group refer to the current country, the report cannot calculate this directly. Instead, the PercentOfGrandTotal field uses the following expression:

[CountryTotal]/[GrandTotal]

CountryTotal and GrandTotal are fields located in the Country and report footer sections. Therefore, CountryTotal holds the total for the current country and GrandTotal holds the total for the whole recordset.

It is important to realize that evaluating aggregate functions is time-consuming, since it requires the control to traverse the recordset. Because of this, you should try to use aggregate functions in a few calculated fields only. Other fields can then read the aggregate value directly from these fields, rather than evaluating the aggregate expression again.

For example, the "Employee Sales by Country" report in the NorthWind database has a detail field that shows each sale as a percentage of the country's total sales. This field contains the following expression:

[SaleAmount]/[CountryTotal]

SaleAmount is a reference to a recordset field, that varies for each detail record. CountryTotal is a reference to a report field that contains an aggregate function. When the control evaluates this expression, it gets the aggregate value directly from the report field, and does not recalculate the aggregate.


Using VBScript to Format Reports

You are not restricted to using VBScript to evaluate expressions in calculated fields. You can also specify scripts that are triggered when the report is rendered, and you can use those to change the formatting of the report.

These scripts are contained in event properties. An event property is similar to a Visual Basic event handler, except that the scripts are executed in the scope of the report rather than in the scope of the application that is displaying the report. For example, you could use an event property to set a field's Font and ForeColor properties depending on its value. This behavior would then be a part of the report itself, and would be preserved regardless of the application used to render it.

Of course, traditional events are also available, and you should use them to implement behavior that affects the application rather than the report. For example, you could write a handler for the OnPage event to update a page count in your application, regardless of which particular report is being rendered.

The table below lists the event properties that are available, and typical uses for them:

Object | Property | Description
Report | OnOpen | Fired when the report starts rendering. Can be used to modify the ConnectionString or RecordSource properties, or to initialize VBScript variables.
 | OnClose | Fired when the report finishes rendering. Can be used to perform clean-up tasks.
 | OnNoData | Fired when a report starts rendering but the source recordset is empty. You can set the Cancel property to True to prevent the report from being generated. You could also show a dialog to alert the user as to the reason why no report is being displayed.
 | OnPage | Fired when a new page starts. Can be used to set the Visible property of sections of fields depending on a set of conditions. The control maintains a Page variable that is incremented automatically when a new page starts.
 | OnError | Fired when an error occurs.
Section | OnFormat | Fired before the fields in a section are evaluated. At this point, the fields in the source recordset reflect the values that will be rendered, but the report fields do not.
 | OnPrint | Fired before the fields in a section are printed. At this point, the fields have already been evaluated and you can do conditional formatting.

The following examples illustrate typical uses for these properties.

Format a Field According to its Value

This is probably the most common use for the OnPrint property. For example, imagine you have a report with a field called "ExtendedPriceCtl", which displays the total value of sales of a particular product. The report is sorted by product name, and you would like to add emphasis to products that sell more than a certain amount. The following code does just that:

Dim sEvent$

sEvent = "If ExtendedPriceCtl > 20000 Then " & vbCrLf &_

" ExtendedPriceCtl.FontBold = True" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = RGB(150,0,0) " & vbCrLf &_

"Else" & vbCrLf &_

" ExtendedPriceCtl.FontBold = False" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = 0" & vbCrLf &_

"End If"

vsr.Sections("ProductGroupHeader").OnPrint = sEvent

The Visual Basic code builds a string containing the VBScript event handler, then assigns it to the section's OnPrint property. When using the VSReport8 Designer you can type the script code directly into the Event Editor window instead of writing the code above.

The control executes the VBScript code whenever the section is about to be printed. The script gets the value of the field and sets the field's FontBold and ForeColor properties according to the value. If the value exceeds $20,000, the field becomes bold and red.

Here's what the report looks like:

Show or Hide a Field Depending on a Value

Instead of changing the field format to highlight its contents, you could set another field's Visible property to True or False to create special effects. For example, if we created a new field called "BoxCtl" and formatted it to look like a green rectangle, then we could change the script as follows:

Dim sEvent$

sEvent = "If ExtendedPriceCtl > 20000 Then " & vbCrLf &_

" ExtendedPriceCtl.FontBold = True" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = RGB(150,0,0) " & vbCrLf &_

" BoxCtl.Visible = True " & vbCrLf &_

"Else" & vbCrLf &_

" ExtendedPriceCtl.FontBold = False" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = 0" & vbCrLf &_

" BoxCtl.Visible = False " & vbCrLf &_

"End If"

vsr.Sections("ProductGroupHeader").OnPrint = sEvent

Prompt Users for Parameters

Instead of using a fixed value of $20,000 as the threshold for highlighting fields, you could have the report prompt the user for a value.

To get the threshold value from the user, you would change the report's RecordSource property to use a parameter query. (For details on how to build parameter queries, see the next topic.)

vsr.DataSource.RecordSource = _

"PARAMETERS [Sales Threshold] Currency 20000; " & _

"[Order Details Extended]"

This setting causes the control to prompt the user for a Sales Threshold value, which gets stored in a global VBScript variable where your events can use it. The default value for the variable is specified as $20,000.

To use the value specified by the user, the script should be changed as follows:

Dim sEvent$

sEvent = "If ExtendedPriceCtl > [Sales Threshold] Then " & vbCrLf &_

" ExtendedPriceCtl.FontBold = True" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = RGB(150,0,0) " & vbCrLf &_

" BoxCtl.Visible = True " & vbCrLf &_

"Else" & vbCrLf &_

" ExtendedPriceCtl.FontBold = False" & vbCrLf &_

" ExtendedPriceCtl.ForeColor = 0" & vbCrLf &_

" BoxCtl.Visible = False " & vbCrLf &_

"End If"

vsr.Sections("ProductGroupHeader").OnPrint = sEvent

Reset the Page Counter

The Page variable is created and automatically updated by the control. It is useful for adding page numbers to page headers or footers.

In some cases, you may want to reset the page counter when a group starts. For example, in a report that groups records by country and has a calculated page footer field with the expression

vsr.Fields("PageFooter").Text = "[Country] & "" "" & [Page]"

It would be good to reset the Page variable for each new country. To do this, assign the following script to the country group header section:

vsr.Sections("CountryGroupHeader").OnPrint = "Page = 1"

Change a Field's Dimensions to Create a Bar Chart

We saved the most sophisticated example for last. Instead of showing a field's value as text, you can change its dimensions to create a chart. (The example described below is included in the NWind.xml sample file that ships with VSReport8; it is called "Sales Chart".)

To create a chart, the first thing you need to do is find out the scale, that is, the measurements that will be used to the maximum and minimum values. The "Sales Chart" report has a field designed to do this. It is a report footer field called SaleAmountMaxFld that has the size of the longest bar we want to appear on the chart, and holds the following expression:

SaleAmountMaxFld.Text = "Max([SaleAmount])"

To draw the actual bars, the report has a detail field called BarFld that is formatted to look like a solid box. The detail section has the following script assigned to its OnPrint event:

vsr.Sections(vsrDetail).OnPrint = & _

"BarFld.Width = SaleAmountMaxFld.Width * (SaleAmountFld / SaleAmountMaxFld)"

This expression calculates the width of the bar based on the width and value of the reference field and on the value of the SaleAmountFld for the current record.

The result is a report that looks like this:


Advanced Topics

Parameter Queries

Unbound Reports

Custom Data Sources

Data Security

Using VSReport8 in VC++


Parameter Queries

A parameter query is a query that displays its own dialog box prompting the user for information, such as criteria for retrieving records or a value for a report field. You can design the query to prompt the user for more than one piece of information; for example, you can design it to retrieve two dates. VSReport8 will then retrieve all records that fall between those two dates.

For example, you can create a monthly earnings report based on a parameter query. When you render the report, VSReport8 displays a dialog box asking for the month that you want the report to cover. You enter a month and VSReport8 prints the appropriate report.

To create a parameter query, you need to edit the SQL statement in the RecordSource property and add a PARAMETERS clause to it. The syntax used to create parameter queries is the same as that used by Microsoft Access.

The easiest way to create a parameter query is to start with a plain SQL statement with one or more items in the WHERE clause, then manually replace the fixed values in the clause with parameters. For example, starting with the plain SQL statement:

strSQL = "SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between #1/1/1994# And #1/1/2001#));"

The next step is to identify the parts of the SQL statement that will be turned into parameters. In this example, the parameters are the dates in the WHERE clause, shown above in boldface. Let's call these parameters Beginning Date and Ending Date. Since these names contain spaces, they need to be enclosed in square brackets:

strSQL = "SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between [Beginning Date] And [Ending Date]));"

Finally, the parameters must be identified in the beginning of the SQL statement with a PARAMETERS clause, that includes the parameter name, type, and default value:

strSQL = "PARAMETERS [Beginning Date] DateTime 1/1/1994, " & _

"[Ending Date] DateTime 1/1/2001;" & _

"SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between [Beginning Date] And [Ending Date]));"

When this statement is executed, the control shows a dialog box prompting the user for Beginning Date and Ending Date values. The values supplied by the user are plugged into the SQL statement and the report is generated only for the period selected by the user.

The dialog box is created on-the-fly by VSReport8. It includes all parameters in the query, and uses controls appropriate to the parameter type. For example, check boxes are used for Boolean parameters, and date-time picker controls are used for Date parameters. Here is what the dialog box looks like for the SQL statement listed above:

The syntax for the PARAMETERS clause consists of a comma-separated list of items, ending with a semi-colon. Each item describes one parameter and includes the following information:

1) Parameter name. If the name contains spaces, it must be enclosed in square brackets (e.g. [Beginning Date]). The parameter name appears in the dialog used to collect the information from the user, and it also appears in the WHERE clause for the SQL statement, where it is replaced with the value entered by the user.

2) Parameter type. The following types are recognized by the control:

Type Name | ADO Type
Date | adDate
DateTime | adDate
Bit, Byte, Short, Long | adInteger
Currency | adCurrency
Single | adSingle
Double | adDouble
Text, String | adBSTR
Boolean, Bool, YesNo | adBoolean

3) Default value. This is the value initially displayed in the dialog box.

The easiest way to build a parameterized query is incrementally. Start with a simple query that works, then add the PARAMETERS clause (don't forget to end the PARAMETERS clause with a semi-colon). Finally, edit the WHERE clause and add the parameter names at the proper place.

You can use the GetRecordSource method to retrieve a proper SQL statement (without the PARAMETERS clause) from a parameter query. This is useful if you want to create your own recordset using data contained in the report.

NOTE: Instead of using a parameter query, you could write code in Visual Basic or in C++ to create a dialog box, get the information from the user, and fix the SQL statement or set the DataSource Object's Filter property as needed. The advantage of using parameter queries is that it places the parameter logic in the report itself, and it is independent of the viewer application. (It also saves you from writing some code.)


Unbound Reports

Unbound reports are reports without an underlying source recordset. This type of report can be useful in two situations:

1.

You create documents that have a fixed format, and only the content of a few fields changes every time you need to render the document. Business forms are a typical example: the forms have a fixed format, and the field values change.

2.

You want to consolidate several summary reports into a single one. In this case, you would create an unbound main report, and you would add bound subreports to it.

As an example of a simple unbound report, let's create a simple Newsletter document without a source recordset. This is done with the VSReport8 Designer, except that you leave the ConnectionString and RecordSource properties blank and add placeholder fields to the report. The placeholder fields are simple labels whose contents will be set by an application.

Assuming you created a report with six placeholder fields named "FldHeadLineXXX" and "FldBodyXXX" (where XXX ranges from 1 to 3), you could use the following Visual Basic code to render the report:

Private Sub MakeNewsLetter_Click()

' load unbound report

vsr.Load App.Path & "\Newsletter.xml", "Newsletter"

' set field values

vsr.Fields("FldHeadline1").Text = "VSReport8 Launched"

vsr.Fields("FldBody1").Text = "Text with the first headline."

vsr.Fields("FldHeadline2").Text = "Competitive Upgrades"

vsr.Fields("FldBody2").Text = "Text with the second headline."

vsr.Fields("FldHeadline3").Text = "VSReport8 Designer"

vsr.Fields("FldBody2").Text = "Text with the third headline."

' done, show the report

vsr.Render vp

' and/or save it to a PDF document file so your subscribers can get to it

vsr.RenderToFile "Newsletter\Latest.pdf", vsrPDF

End Sub

Here's what this issue of our newsletter looks like. Notice that our simple program does not deal with any formatting at all; it simply supplies the report contents. The report definition created with the VSReport8 Designer takes care of all the formatting, including a headline with a logo, page footers, fonts and text positioning. Separating format from content is one of the main advantages of unbound reports.

NOTE: You can also create your own custom recordset object and use it instead of a regular ADO recordset. Custom data-bound reports are described below.


Custom Data Sources

By default, VSReport8 uses the ConnectionString and RecordSource properties to create an ADO recordset that is used as a data source for the report. However, you can also create your own recordsets and assign them directly to the Recordset property. In this case, VSReport8 will use the recordset provided instead of opening its own.

You can use three types of recordset: ADO, DAO, or custom. This documentation refers to these recordsets as "custom recordsets". This doesn't mean the ADO and DAO recordsets are different from regular ones, they are simply provided by the application rather than being created by the VSReport8 control.

NOTE: All recordsets used with VSReport8 must be bookmarkable, because the control needs to be able to save and restore cursor positions in order to detect group breaks and calculate aggregates.

Custom ADO Recordsets

Custom DAO Recordsets

Custom Recordsets

Implementing Custom Recordsets in Visual Basic

Implementing Custom Recordsets in Visual C++ 6.0


Custom ADO Recordsets

The main reason to use your own ADO recordset is in situations where you already have the recordset available, and want to save some time by not creating a new one. You may also want to implement security schemes, customize the recordset properties, or use stored procedures.

To use your own ADO recordset, simply assign it to the Recordset property before you render the report. For example:

Private Sub CreateReport()

' create connection and recordsource strings

Dim sConn$, sRS$

sConn = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _

"Persist Security Info=False;Initial Catalog=pubs"

sRS = "byroyalty(40)" ' << stored procedure

' create ADO recordset object

Dim rs As New ADODB.Recordset

rs.Open "byroyalty(40)", sConn, adOpenKeyset

' load report

vsr.Load "RepDef.xml", "My Report"

' render report

vsr.Datasource.Recordset = rs

vsr.Render vp

' done

rs.Close

Set rs = Nothing

End Sub

The code above opens a recordset using the "byroyalty" stored procedure in the "pubs" database that ships with SQLServer. Note that you could open this recordset using the ConnectionString and RecordSource properties directly.

Note that you can also create and populate custom ADO recordsets on the fly, using code. For example:

Private Function MakeADORS() As ADODB.Recordset

' create empty recordset

Dim rs As New ADODB.Recordset

' add some fields to it

rs.Fields.Append "ID", adInteger

rs.Fields.Append "FirstName", adBSTR, 100

rs.Fields.Append "LastName", adBSTR, 100

' populate new recordset

Dim i%

rs.Open

For i = 0 To 1000

rs.AddNew

rs.Fields("ID") = I

rs.Fields("FirstName") = "John " & I

rs.Fields("LastName") = "Doe " & I

Next

' done, return it

Set MakeADORS = rs

End Sub


Custom DAO Recordsets

You would use custom DAO recordsets for the same reasons you would use custom ADO recordsets, plus you might get slightly better performance and make deployment of your application easier (in case some of your clients don't have MSDAC/OLEDB installed on their computers).

Using custom DAO recordsets is exactly the same as using custom ADO recordsets, except of course for the code that creates the recordset itself. For example:

Private Sub CreateReport()

' create DAO recordset

Dim db As DAO.Database

Dim rs As DAO.Recordset

Dim strRS As String

strRS = vsr.DataSource.GetRecordSource(True)

Set db = OpenDatabase("c:\VB98\NWind.mdb")

Set rs = db.OpenRecordset(strRS, dbOpenDynaset)

' load report

vsr.Load "RepDef.xml", "My Report"

' render report

vsr.Datasource.Recordset = rs

vsr.Render vp

' done

rs.Close

Set rs = Nothing

End Sub


Custom Recordsets

For the ultimate in data source customization, you can implement your own data source object. This option is indicated in situations where:

1.

Your data is already loaded in memory.

2.

Some or all of the data is calculated on demand, and does not even exist until you request it.

3.

The data comes from disparate data sources and you don't have an easy way to create a standard recordset from it.

To implement your own data source object, you need to create a COM object that implements the IVSReportRecordset interface. This interface contains the following methods:

Method | Description
GetFieldCount() As Long | Returns the number of fields.
GetFieldName(Index As Long) As String | Returns the name of the ith field.
GetFieldType(Index As Long) As Long | Returns the type of the ith field.*
GetFieldSize(Index As Long) As Long | Returns the size of the ith field.*
GetFieldValue(Index As Long) As Variant | Returns the value of the ith field in the current record.
BegOfFile() As Boolean | Returns True if the cursor is at the first record.
EndOfFile() As Boolean | Returns True if the cursor is positioned beyond the last record.
MoveFirst() | Moves the cursor to the first record.
MoveLast() | Moves the cursor to the last record.
MovePrevious() | Moves the cursor to the previous record.
MoveNext() | Moves the cursor to the next record.
GetBookmark() As Variant | Returns a marker that uniquely identifies the current record.
SetBookmark(BookMark As Variant) | Moves the cursor to the position identified by the BookMark parameter.
ApplyFilter(Filter As String) | Applies a filter expression to the recordset.**
ApplySort(Sort As String) | Applies a sort expression to the recordset. The expression has the same format as a WHERE clause in a SQL statement.**

* Field types and sizes are not used internally by VSReport8. This information is used only to fill the array returned by the FieldInfo property.

** You don't really have to implement filtering and sorting. If you simply provide do-nothing stubs for these functions, you will still be able to generate reports from your recordsets, except the Filter and Sort properties won't work.


Implementing Custom Recordsets in Visual Basic

To implement a custom recordset in Visual Basic, follow these steps (for a complete example, see the CustomData project in the Samples/VB directory):

1.

Create a new project (or open an existing one) and add a VSReport8 and a VSPrinter8 controls to the main form.

2.

Create a Class Module using the Project|Add Class Module menu. Use the property window to give the class a meaningful name (such as MyReportDataSource).

3.

Open the code window and add the following code to the new class:

Option Explicit

Implements IVSReportRecordset

Private m_sData(5) As String

Private m_lCursor As Long

Private Sub Class_Initialize()

InitData

m_lCursor = 0

End Sub

Private Sub InitData()

m_sData(0) = "Alice Mutton|Meat/Poultry|20 - 1 kg tins|0"

m_sData(1) = "Aniseed Syrup|Condiments|12 - 550 ml bottles|13"

m_sData(2) = "Boston Crab Meat|Seafood|24 - 4 oz tins|123"

m_sData(3) = "Camembert Pierrot|Dairy Products|15 - 300 g rounds|19"

m_sData(4) = "Carnarvon Tigers|Seafood|16 kg pkg.|42"

m_sData(5) = "Chai|Beverages|10 boxes x 20 bags|39"

End Sub

The Implements statement is important. It means this class promises to implement all the methods in the IVSReportRecordset, described above. Without this statement, the class would not qualify as a valid recordset for VSReport8, and trying to assign an instance of it to the Recordset property would raise an error.

The m_sData() and m_lCursor are the variables that will hold the actual data and the cursor position for our new class. They are both initialized in response to the Class_Initialize event. In this example, there are only five records, each consisting of a string with field values separated by pipes ("|").

4.

Select the IVSReportRecordset_GetFieldCount routine on the code editor (note that VB created a stub automatically based on the Implements statement) and add the following implementation:

Private Function IVSReportRecordset_GetFieldCount() As Long

IVSReportRecordset_GetFieldCount = 4

End Function

This function returns the number of fields in the recordset. In this case, each record contains four fields: product name, category name, quantity per unit, and units in stock.

5.

Follow the same steps to implement the remaining field information routines:

Private Function IVSReportRecordset_GetFieldName_

(ByVal Index As Long) As String

Dim s$

Select Case Index

Case 0: s = "ProductName"

Case 1: s = "CategoryName"

Case 2: s = "QuantityPerUnit"

Case 3: s = "UnitsInStock"

Case Else

Err.Raise 666, , "Invalid Index"

End Select

IVSReportRecordset_GetFieldName = s

End Function

This function returns the name of a field based on its index. The field names are important because they are used by VSReport8 when evaluating the expressions contained in calculated report fields.

Private Function IVSReportRecordset_GetFieldType_

(ByVal Index As Long) As Long

IVSReportRecordset_GetFieldType = 8 ' string

End Function

Private Function IVSReportRecordset_GetFieldSize_

(ByVal Index As Long) As Long

IVSReportRecordset_GetFieldSize = 50

End Function

These functions return each field's type and size. They are not used by VSReport8 except to give it back to the user in case he requests it using the FieldInfo property.

Private Function IVSReportRecordset_GetFieldValue

(ByVal Index As Long) As Variant

Dim v

v = Split(m_sData(m_lCursor), "|")

IVSReportRecordset_GetFieldValue = v(Index)

End Function

This function returns the value for a specific field in the current record. In this example, the function splits the current record string at the pipes using VB's Split function and returns the desired value.

6.

Implement the cursor management functions:

Private Sub IVSReportRecordset_MoveFirst()

m_lCursor = 0

End Sub

Private Sub IVSReportRecordset_MoveLast()

m_lCursor = UBound(m_sData)

End Sub

Private Sub IVSReportRecordset_MovePrevious()

If m_lCursor > 0 Then m_lCursor = m_lCursor - 1

End Sub

Private Sub IVSReportRecordset_MoveNext()

If m_lCursor < UBound(m_sData) Then m_lCursor = m_lCursor + 1

End Sub

Private Function IVSReportRecordset_BegOfFile() As Boolean

IVSReportRecordset_BegOfFile = (m_lCursor = 0)

End Function

Private Function IVSReportRecordset_EndOfFile() As Boolean

IVSReportRecordset_EndOfFile = (m_lCursor >= UBound(m_sData))

End Function

These functions move the cursor and inform the caller (VSReport8) whether the cursor has reached the end of the recordset. The functions are simple and generic, you should be able to use them whenever your data is stored in arrays.

Private Function IVSReportRecordset_GetBookmark() As Variant

IVSReportRecordset_GetBookmark = m_lCursor

End Function

Private Sub IVSReportRecordset_SetBookmark(newVal As Variant)

If newVal < 0 Or newVal > UBound(m_sData) Then

Err.Raise 666, , "Invalid Bookmark"

Else

m_lCursor = newVal

End If

End Sub

The bookmark functions allow the caller (VSReport8) to save and restore its current position in the recordset. This is necessary when calculating aggregate expressions.

7.

Implement the filtering and sorting functions:

Private Sub IVSReportRecordset_ApplyFilter(ByVal Filter As String)

Debug.Print "Ignoring filter: "; Filter

End Sub

Private Sub IVSReportRecordset_ApplySort(ByVal Sort As String)

Debug.Print "Ignoring sort: "; Sort

End Sub

As you can see, these are dummy implementations. They don't need to do anything, but they need to be there so the class qualifies as a bona-fide IVSReportRecordset.

8.

Instantiate and use the custom recordset as you would use an ADO or DAO recordset. For example, add a button and the following code to the form:

Private Sub Command2_Click()

' create the custom recordset object

Dim rs As New MyReportDataSource

With VSReport1

.DataSource.Recordset = rs

.Render VSPrinter1

End With

End Sub


Implementing Custom Recordsets in Visual C++ 6.0

To implement a custom recordset in Visual C++ 6.0, follow these steps (for a complete example, see the CustomData project in the Samples/VC directory):

1.

Create a new project with COM support (MFC or ATL) and add the following statement to the "StdAfx.h" file (fix the path as appropriate so VC++ can find the ocx file):

#import "e:\ocx\VSRpt8.ocx" no_namespace

This will create wrapper classes for the VSReport8 objects, including the definition of the IVSReportRecordset interface.

2.

Create a new class that implements the IVSReportRecordset interface. For a complete sample, see the MyReportDataSource.h file in the Samples/VC directory.

3.

Add a VSReport8 and a VSPrinter8 control to your application. In an MFC dialog-based application, you can do this by right-clicking the dialog and selecting the Insert ActiveX Control menu.

4.

Add the class variables needed to communicate with the new controls. In an MFC dialog-based application, you can do this by control-double-clicking each control, then entering a variable name in the dialog. For example, m_Report and m_Printer.

5.

Load a report definition into the m_Report control. You can do this by right clicking the control, selecting the Properties menu, and using the Load Report tab.

6.

To create reports, create an instance of the data source class, assign it to the m_Report control, and render it on the m_Printer control. In an MFC dialog-based application, you can do this with the following code:

#include "DataSource.h" // created by MFC

#include "MyReportDataSource.h" // custom data source

void CCustomDataDlg::OnRenderCustom()

{

// create custom data source

CMyReportDataSource cds;

// assign it to control

CDataSource ds = m_Report.GetDataSource();

ds.SetRecordset(cds.GetUnknown());

// render it

m_Report.Render((IDispatch*)m_Printer.GetControlUnknown());

}


Data Security

Data security is an important issue for most corporations. If you plan to create and distribute a phone-directory report for your company, you want to show employee names and phone extensions. You probably don't want people to change the report definition and create a report that includes people's salaries. Or someone could look at the report definition file, copy a connection string and start browsing (or hacking) your database.

These are legitimate concerns that affect all types of data-based applications, including VSReport8. This section discusses some measures you can take to protect your data.

Use Windows NT Integrated Security

Build a ConnectionString with a User-supplied Password

Application-defined Aliases

Custom Recordsets


Use Windows NT Integrated Security

One of the strengths of Windows NT is the way it handles security. When a user logs on, the system automatically gives him a set of permissions granted by the system administrator. After this, each application or service can query Windows NT to see what resources he can access. Most popular database providers offer this type of security as an option.

Under this type of scenario, all you need to do is make sure that the people with whom you want to share your data have the appropriate permissions to read it. In this case, the ConnectionString in the report definition file doesn't need to contain any passwords. Authorized users will get to see the data, and others will not.


Build a ConnectionString with a User-supplied Password

This is a very simple alternative. Before rendering a report (or when the control reports a "failed to connect" error), you can prompt the user for a password and plug that into the connection string. For example:

' build connection string with placeholder for password

Dim strConn

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

"Data Source=C:\SecureData\People.mdb;" & _

"Password={{THEPASSWORD}};"

' get password from the user

Dim strPwd$

strPwd = InputBox("Please enter your password:")

If Len(strPwd) = 0 Then Exit Sub

' build new connection string and assign it to the control

strConn = Replace(strConn, "{{THEPASSWORD}}", strPwd)

vsr.DataSource.ConnectionString = strConn


Application-defined Aliases

Another possible scenario is one where you want to allow certain users to see the reports, but you don't want to give them any special authorizations or information about where the data is stored.

There are two simple ways to achieve this with VSReport8. One is by using embedded reports. Load the report definition into your application at design time, using the "Load Report" property page, and the report will be embedded in the application. This way, you don't have to distribute a report definition file and no one will have access to the data source information.

The second way would be for your application to define a set of connection string aliases. The report definition file would contain the alias, and your application would replace it with the actual connection string before rendering the reports. The alias would be useless in any other applications (such as the VSReport8 Designer). Depending on how concerned you are with security, you could also perform checks on the RecordSource property to make sure no one is trying to get unauthorized access to certain tables or fields in the database.

The code below shows how you might implement a simple alias scheme:

Private Sub RenderReport(strReportName $)

' load report requested by the user

vsr.Load App.Path & "\MyReports.xml", strReportName

' replace connection string alias

Dim strConn$

Select Case vsr.DataSource.ConnectionString

Case "$$CUSTOMERS"

Case "$$EMPLOYEES"

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

"Data Source=C:\SecureData\People.mdb;" & _

"Password=slekrsldksd;"

Case "$$SALES"

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

"Data Source=C:\SecureData\Numbers.mdb;" & _

"Password=slkkdmssids;"

End Select

' render the report and clear it when done

vsr.Render vp

vsr.Clear

End Sub


Custom Recordsets

You can also assign an arbitrary recordset created by your application to the Recordset object. This way, you can adopt whatever security measures you see fit, and you don't need to bother with the ConnectionString and RecordSource properties at all.

For details, see the Custom Data Sources section.


Using VSReport8 in VC++

Using VSReport8 in Visual C++ is not very different form using it in Visual Basic, thanks to the great COM support built into Visual C++ 6.0.

Before Visual Studio 6, the only practical way to use COM objects in Visual C++ was through MFC. You would insert a COM object into your project, and MFC would create wrapper classes that provided access to all methods, properties, and events. This method had a couple of drawbacks, however. The wrappers created by MFC were automation-based, which is not terribly efficient. They also relied on MFC classes such as CString, and provided no support for optional parameters. Finally, the wrappers included all methods, properties, and events, but omitted custom types and enumerations.

Visual C++ version 6 introduced native COM support via classes that encapsulate COM pointers, strings, variants, and more. Most importantly, the new #import statement can be used to build powerful and efficient wrapper classes that let you write C++ code that is as readable as Visual Basic code.

To use VSReport8 in your C++ projects, add the following #import statements to your stdafx.h file (make sure each #import statement is on a single line, and remember to include the full path to the OCX files):

#import "VSRpt8.ocx" no_namespace

#import "VSPrinter8.ocx" no_namespace exclude("PictureAlignSettings", _

"BorderStyleSettings")

These statements will create wrappers for the VSReport8 and VSPrinter8 controls (the wrapper classes are saved into TLH and TLI files in your current build directory). Once that is done, you can write code such as:

IVSReportPtr spReport; // declare a pointer to a VSReport8 control

spReport.CreateInstance(__uuidof(VSReport)); // create control

spReport->Load(szFileIn, szReport); // load report definition

spReport->RenderToFile(szFileOut, vsrHTMLPaged); // render report

The #import statement handles the control's entire object model, so you also get classes that encapsulate the DataSource and Layout objects, Groups, Sections, Fields, etc. For example, the following code enumerates all fields in a report:

// get field collection

IFieldCollectionPtr spFields = spReport->Fields;

// enumerate all fields

long iField, lFieldCnt = spFields->Count;

for (iField = 0; iField < lFieldCnt; iField++)

{

// get ith field

IFieldPtr spField = spFields->GetItem(iField);

// show the field's name

_bstr_t strName = spField->Name;

strName += "\n";

OutputDebugString((char*)strName);

}

Using the #import statement doesn't mean you can't use MFC and the AppWizard to create your controls and connect events, etc. Both approaches can coexist. If you have an instance of a control that was created by MFC using the MFC wrappers, you can easily convert it into the #import-flavor wrappers using the following construct:

IVSReportPtr spReport = mfcReportControl.GetControlUnknown();

The IVSReportPtr class will take care of querying the new value for the appropriate interface and will do the right thing.

One final note on using the #import statement is related to error-handling. The high-level wrappers have built-in error handling. If something goes wrong they will throw an exception, and if you don't handle it your program will die. So, to be safe, you should always use the high-level wrappers in try/catch blocks. For example:

try {

spReport->Load(strFileIn, strReportName);

spReport->Render(spPrinter);

} catch (...) {

MessageBox("Failed to render the report ");

}

Alternatively, you can use the lower-level wrappers, which return HRESULTS like traditional COM. The lower-level functions have a "raw_" prefix and can be used as follows:

HRESULT hr = spReport->raw_Load(strFileIn, strReportName);

if (!FAILED(hr))

hr = spReport->raw_Render(spPrinter);

if (FAILED(hr))

MessageBox("Failed to render the report ");

This information should be enough to help you get started. If you are unsure about the syntax for a particular method or property, start by looking at the TLH and TLI files generated by the #import statement, or check the VC++ samples on the distribution CD or on our web site (http://www.componentone.com/).


Using the VSReport8 Designer

The VSReport8 Designer is a tool used for creating and editing VSReport8 report definition files. The Designer allows you to create, edit, load, and save files (xml) that can be read by the VSReport8 control. It also allows you to import report definitions from Microsoft Access files (MDB) and VSReport 1.0 (vsr).

To run the Designer, double-click the VSRpt8.exe file. Here's what the designer looks like:

The main Designer window has the following components:

1.

Menu bar: Provides access to the main Designer functions. Use the File menu to load and save report definition files, to import report definitions, and to print reports.

2.

Main toolbar: Provides shortcuts to the most common menu functions: new file, open, import, save, print, undo/redo, cut/copy/paste, create/delete report, and help.

3.

View toolbar: Switches between preview and design modes, activates the design grid, and displays the property and grouping windows.

4.

Toolbox: Provides tools for creating report fields. This toolbar is enabled only in design mode.

5.

Format toolbar: Provides tools for aligning, sizing, and spacing report fields. This toolbar is enabled only in design mode.

6.

Report list: Lists all reports contained in the current report definition file. You can double-click a report name to preview or edit the report. You can also use the list to rename, copy and delete reports.

7.

Preview/Design pane: This is the main working area of the Designer. In preview mode, it displays the current report. In design mode, it shows the report's sections and fields and allows you to change the report definition.

8.

Status bar: The status bar displays information about what the Designer is working on (e.g., loading, saving, printing, rendering, importing, etc).

The following sections explain how you can use the VSReport8 Designer to create, edit, use, and save report definition files.

Creating a Basic Report Definition

Modifying the Report Layout

Changing Field, Section, and Report Properties

Changing the Data Source

Adding Fields to the Report

Grouping and Sorting Data

Previewing and Printing Your Report

Exporting and Publishing Your Report

Saving Your Report Definition

Managing Your Report Definition Files

Importing Microsoft Access Reports


Creating a Basic Report Definition

You can design your report to display your data in a variety of ways on the printed page. Using the VSReport8 Designer <wndreport_designer.htm>, you can design comprehensive lists, summaries, or special subsets of data, like an invoice.

The easiest way to start a new report is to use the Report Wizard. Click the New Report button on the main toolbar, or select the Edit|New Report menu option. The Report Wizard will appear, and will guide you through five easy steps.

1) Select the data source for the new report

Use this page to select the ConnectionString and RecordSource that will be used to retrieve the data for the report.

You can specify the ConnectionString in three ways:

1.

Type the string directly into the editor.

2.

Use the drop down list to select a recently used connection string (the Designer keeps a record of the last eight connection strings).

3.

Click the button with the ellipsis (…) to bring up the standard connection string builder.

You can specify the RecordSource string in two ways:

1.

Click the Table button and a table from the list.

2.

Click the SQL button and type (or paste) a SQL statement into the editor.

3.

2) Select the fields you want to include in the report

This page contains a list of the fields available from the recordset you selected in Step 1, and two lists that define the group and detail fields for the report. Group fields define how the data will be sorted and summarized, and detail fields define what information you want to appear in the report.

You can move fields from one list to another by dragging them. Drag fields into the Detail list to include them in the report, or drag within the list to change their order. Drag fields back into the Available list to remove them from the report.

3) Select the layout for the new report

This page offers you several options to define how the data will be organized on the page. When you select a layout, a thumbnail preview appears on the left to give you an idea of what the layout will look like on the page. There are two groups of layouts, one for reports that have no groups and one for reports with groups. Select the layout that best approximates what you want the final report to look like.

This page also allows you to select the page orientation and whether fields should be adjusted to fit the page width.

The "Labels" layout option is used to print Avery-style labels. If you select this option, you will see a page that prompts you for the type of label you want to print.

4a) Select the style for the new report (not used for the "Labels" layout)

NOTE: If using the "Labels" layout, follow step 4b.

This page allows you to select the fonts and colors that will be used in the new report. Like the previous page, it shows a preview to give you an idea of what each style looks like. Select the one that you like best (and remember, you can refine it and adjust the details later).

4b) Select the type of label you would like (for "Labels" layout only)

This page allows you to select the type of label you want to create. The Designer has over 170 predefined label types for you to choose from. The labels are divided into four groups, depending on whether they use metric or English measurements, and on the type of paper they use (sheets or continuous forms).

If the labels you want to print are not on the list, you can add your own custom types. To do so, you need to create a comma-delimited text file containing the information for the custom labels. This file should be called "LabelDef.txt" and it should be placed in the same directory where the Designer's executable (VSRpt8.exe) is located.

The label definition file should contain one line for each custom label type, and each line should contain the following 15 values, separated by commas. Lines starting with a semi-colon are treated as comments. Invalid label definitions (with missing or invalid data) are ignored.

ID | Label name.
DESCRIPTION | Description (usually includes the label dimensions).
ACROSS | Number of labels across a page.
METRIC | True for metric units, False for English (used to filter the display only).
WIDTH | Label width (all measurements in twips).
HEIGHT | Label height.
XSPACE | Horizontal space between labels.
YSPACE | Vertical space between labels.
MLEFT | Left page margin.
MRIGHT | Right page margin.
MTOP | Top page margin.
LMLEFT | Left label margin.
LMTOP | Top label margin.
CONTINUOUS | True for continuous forms, False for sheet-feed.
PORTRAIT | True for portrait page orientation, False for landscape.

For example, the following is a valid label definition:

Custom1,2 1/2" x 3 3/8",2,0,4860,3360,540,270,990,990,792,547,432,0,1

5) Select a Title for the new report

This last page allows you to select a title for the new report and to decide whether you would like to preview the new report right away or whether you would like to go into edit mode and start improving the design before previewing it.

If you choose to preview the report and click finish, you will immediately see the report in the preview pane of the Designer. It should look like this:


Modifying the Report Layout

The report generated for you by the wizard is a good starting point, but you will usually need to adjust and enhance it to get exactly what you want. You can do this with the Designer.

To start using the designer, click the Design button on the View toolbar or select the View|Design menu. The right pane of the main window will switch from Review mode into Design mode, and it will show the controls and fields that make up the report:

The picture shows how the report is divided into sections (Header, Page Header, etc). The sections contain fields that hold the labels, variables, and expressions that you want in the printed report. In our example, the Header section contains a label with the report title. The Page Header section contains labels that identify the fields in the Detail section, and the Page Footer section contains fields that show the current time, the page number and the total page count for the report.

The sections of the report determine what each page, group, and the beginning and end of the report look like. The table below describes where each section appears in the report and what it is typically used for.

Section | Appears | Typically Contains
Report header | Once per report | The report title and summary information for the whole report. Page header Once per page Labels that describe detail fields, and/or page numbers.
Group header | Once per group | Fields that identify the current group, and possibly aggregate values for the group (e.g. total, percentage of the grand total).
Detail | Once per record | Fields containing data from the source recordset.
Group footer | Once per group | Aggregate values for the group.
Page footer | Once per page | Page number, page count, date printed, report name.
Report footer | Once per report | Summary information for the whole report.

Note that you can't add and delete sections directly. The number of groups determines the number of sections in a report. Every report has exactly five fixed sections (Report Header/Footer, Page Header/Footer, and Detail) plus two sections per group (a Header and a Footer). You can hide sections that you don't want to display by setting their Visible property to False.

To enhance your report, you can add lines, rectangles, and pictures to any section. You can also modify the existing fields and sections by changing their properties with the Property Window, or move and resize them with the mouse.

To resize a section, drag its border to the position where you want it. The rulers on the left and on top of the design window show the size of each section (excluding the page margins). Note that you cannot make the section smaller than the height and width required to contain the fields in it. To reduce the size of a section beyond that, move or resize the fields in it first, then resize the section.

To see how this works, move the mouse to the area between the bottom of the Page Header section and the gray bar on top of the Detail section. The mouse cursor will change to show that you are over the resizing area. Click the mouse and drag the line down until the section is about twice its original height. Release the button and the section will be resized.

Next, click the mouse close to the bottom left corner of the Page Header section, and drag it to the top right corner. You will see a selection rectangle that should cover or touch all fields in the section. Release the mouse button and all fields will be selected. Now drag the entire selection down until it touches the bottom of the section, and release the button. You have just moved the fields and opened up a little more room on the page header section.

The Designer allows you to use the mouse in a way that should be familiar. You can shift-click fields to toggle their selection status, control-drag to copy, click on the corners to resize, and so on. You can also use the tab key to move the selection to the next field (which is handy when fields are close together), the arrow keys to move the selected fields, and the DEL key to delete the selected fields.

When multiple fields are selected, you can use the buttons on the Format toolbar to align, resize, and space them.

If you make any mistakes while moving or editing the fields, use the Undo/Redo buttons on the main toolbar to fix the report.

You can control the design grid using the Show Grid and Snap To Grid buttons on the design toolbar. You can also select the grid units using the View|Options menu.


Changing Field, Section, and Report Properties

Once an object is selected, you can press the Property Window button (or press F4, or use the right mouse button and the context menu) to display and edit its properties. You can also double-click an object to display its properties.

When one or more fields are selected, the property window will show property values that all fields have in common, and will leave the other properties blank. If no fields are selected and you click on a section (or on the bar above a section), the section properties will be displayed. If you click the gray area in the background, the Report properties will be displayed.

To see how this works, double-click the label in the Header section and change its Font and ForeColor properties. You can also change a field's position and dimensions by typing new values for the Left, Top, Width, and Height properties. The property window expresses all measurements in twips (the native unit used by VSReport8), but you can type in values in other units and they will be automatically converted into twips. For example, if you set the field's Height property to "0.5in", the property window will convert it into 720 twips.


Changing the Data Source

The data source is defined by the ConnectionString, RecordSource, and Filter properties. These are regular Report properties and may be set using the Property Window and clicking on the background area where there are no sections.

Or click the DataSource button to get a dialog that allows you to set the ConnectionString and RecordSource properties directly.


Adding Fields to the Report

Use the ToolBox to add fields to your report. Each button creates a field and initializes its properties as follows:

Label field: Creates a field that displays static text.

Bound field: Creates a field that is bound to the source recordset. When you click this button, a menu appears and you can select the recordset field. Bound Fields are not limited to displaying raw data from the database. You can edit their Text property and use any VBScript expression.

Expression Field: Creates a calculated field. When you click this button, the code editor dialog will appear so you can enter the VBScript expression whose value you want to display.

Checkbox Field: Creates a bound field that displays a boolean value as a check box. By default, the checkbox displays a regular checkmark. You can change it into a radio button or crossmark by changing the value of the field's Checkbox property after it has been created.

Unbound Picture field: Creates a field that displays a static picture, such as a logo. When you click this button, a dialog box will appear to prompt you for a picture file to insert in the report. A copy will be made of the picture you select and placed in the same directory as the report file. You must distribute this file with the application unless you embed the report file in the application. When you embed a report file in your application, any unbound picture files are embedded too.

Bound Picture field: Creates a field that displays a picture (or object) stored in the recordset. When you click this button, a menu appears so you can select a picture field in the source recordset (if there is one; not all recordsets contain this type of field).

Line field: Creates a line. Lines are often used as separators.

Rectangle field: Creates a rectangle. Rectangles are often used to highlight groups of fields or to create tables and grids.

Subreport field: Creates a field that displays another report. When you click this button, a menu appears and you can select other reports that are contained in the same report definition file.

Page Break field: Creates a field that inserts a page break.

After you click any of these buttons, drag the mouse over the report and the cursor will change into a cross-hair. Click and drag to define the rectangle that the new field will occupy, then release the button to create the new field. If you change your mind, hit the ESC key or click the arrow button to cancel the operation.

Note that VSReport8 only has one type of Field object. The buttons simply set some properties on the Field object to make it look and act in a certain way.

You can also add fields by copying and pasting existing fields, or by holding down the control key and dragging a field or group of fields to a new position to create a copy.

To see how this works, click the Unbound Picture button and select a picture file. Then move the mouse over the Page Header section and mark a rectangular area above the first label. The picture you selected will appear in the area you marked.


Grouping and Sorting Data

After designing the basic layout, you may decide that grouping the records by certain fields or other criteria would make the report easier to read. Grouping allows you to separate groups of records visually and display introductory and summary data for each group. The group break is based on a grouping expression. This expression is usually based on one or more recordset fields but it can be as complex as you like.

Groups are also used for sorting the data, even if you don't plan to show the Group Header and Footer sections.

To add or edit the groups in the report, click the Sorting and Grouping button or select the View|Grouping Window menu. The Sorting and Grouping dialog will appear. You can use this dialog to create, edit, reorder, and delete groups.

To create a group, use the drop-down list under Group On to select the field you want to use for grouping the data. For complex grouping, you may type an expression instead of a simple field name. For example, you could use "Country" to group by country or "Left(Country, 1)" to group by country initial. To follow along with our report, select "Country" for the Group On expression.

Next, select the type of sorting you want ("Ascending" in our example). You can also specify whether the new group will have visible Header and Footer sections, and whether the group should be rendered together on a page.

NOTE: You cannot use memo or binary (object) fields for grouping and sorting. This is a limitation imposed by OLEDB.

After you enter some data for the first group, a new blank row is appended to the list, so you can keep creating new groups.

Here's what the Sorting and Grouping dialog should look like at this point:

If you add more fields, you can change their order by clicking on the row header (the leftmost gray cell) and dragging the row to a new position. This will automatically adjust the position of the Group Header and Footer sections in the report. To delete a field, press the DEL key.

Once you are done arranging the fields, click OK to dismiss the dialog and see the changes in the Designer. There are two new sections, a Header and a Footer for the new group.

The bar across the top of each section contains some useful tools and information about the section:

On the left of the Group Header, there's a little indented circle. This indicates that the section currently has zero height. You can drag the divider line down to increase the section's Height property. The triangle next to it shows the group's sorting order. You can click this icon to bring up the Grouping and Sorting dialog. After the icons, there are labels that contain the section name and, for group headers, the value of the group's GroupBy property.

Also notice the indented box with a minus sign on the left part of the Detail section's title bar. Clicking this icon collapses and expands the section. This feature is useful when you are designing the report because it allows you to see a group's header and footer on the same screen, without scrolling. Collapsing or expanding a section has no effect on how it is rendered on the page.

If you have been following along, you will see that a Group Header section has been created for the new group. The new section has zero height, so drag its divider line down to open up some room.

To see how groups work, click the Bound Field button, select "Country" from the menu and mark an area in the newly created Group Header Section. Double-click the new field and change its Font property to make the new field stand out a little.


Previewing and Printing Your Report

To preview a report, select it from the Report List on the left pane of the Designer window and click the Preview button, or select the View|Preview menu. The report will be displayed on the right pane, as shown below:

The preview pane has a navigation bar along the bottom, with buttons that let you page through the document and select the zoom mode.

At this point, you can print the report by clicking the Print button or selecting the File|Print menu.


Exporting and Publishing Your Report

Instead of printing the report, you may want to export it into a file and distribute it electronically to your clients or co-workers. The Designer supports several export formats, listed below:

Format | Description
Paged HMTL | Creates one HTML file for each page in the report. The HTML pages contain links that let the user navigate the report.
Drill-Down HTML | Creates a single HTML file with sections that can be collapsed and expanded by the user by clicking on them.
Plain HMTL | Creates a single, plain HTML file.
PDF | Creates a PDF file that can be viewed on any computer equipped with Adobe's Acrobat viewer or browser plug-ins.
VSPrinter | Creates a file using the VSPrinter control's native format. The file can be loaded, viewed, and printed from a VSPrinter control within an application or web page.
Text | Creates a plain text file.

To create an export file, select the File|Export menu and use the File Save dialog to select the type of file you want to create, its name, and location.


Saving Your Report Definition

When you are done creating and viewing your report, use the Save button or the File|Save menu to save the report definition file. The Designer will save the report definition in XML format, which can be read back into the Designer or directly into a VSReport8 control.


Managing Your Report Definition Files

A report definition file may contain several reports. Occasionally, you may want to copy or move a report from one file to another.

To move a report from one file to another, open two instances of the Designer and drag the report from one instance to the other. If you hold down the control key while doing this, the report will be copied. Otherwise, it will be moved.

You can also copy a report within a single file. This will create a new copy of the report, which is a good way to start designing a new report that is similar to an existing one.

Note that the report definition files are saved in XML, so you can also edit and maintain them using any text editor.


Importing Microsoft Access Reports

One of the most powerful features of the VSReport8 Designer is the ability to import reports created with Microsoft Access. This feature requires Access to be installed on the computer. Once the report is imported into the Designer, Access is no longer required.

To import reports from an Access file, click the Import button or select the File|Import menu. A dialog box will prompt you for the name of an Access file (MDB). After you select the file, the Designer automatically scans it and converts all the reports into a new report definition file.

The import process works well and handles most elements of the source reports, with a few exceptions listed below:

1)

Event handler code

Access reports can use VBA, macros, and forms to format the report dynamically. VSReport8 can do the same things, but it only uses VBScript. Because of this, all report code needs to be translated manually.

2)

Form-oriented field types

Access reports may include certain fields that are not handled by the Designer's import procedure. The field types not supported are Chart, CommandButton, ToggleButton, OptionButton, OptionGroup, ComboBox, ListBox, TabCtl, and CustomControl.

3)

Reports that use VBScript reserved words

Because Access does not use VBScript, you may have designed reports that use VBScript reserved words as identifiers for report objects or recordset field names. This causes problems when the VBScript engine tries to evaluate the expression, and will prevent the report from rendering correctly.

Reserved words you shouldn't use as identifiers include Date, Day, Hour, Length, Minute, Month, Second, Time, TimeValue, Value, Weekday, and Year. For a complete list, please refer to a VBScript reference.

4)

Reports that sort dates by quarter (or weekday, month of the year, etc.)

VSReport8 uses the ADO recordset Sort property to sort groups. This property sorts recordsets according to field values only, and does not take expressions. (Note that you can group according to an arbitrary expression, but you can't sort.) An Access report that sorts groups by quarter will sort them by date after it is imported. To fix this, you have two options. Either create a field that contains the value for the expression you want to sort on, or change the SQL statement that creates the recordset and perform the sorting that way.

These limitations affect a relatively small number of reports, but you should preview all reports after importing them, to make sure they still work correctly.

To illustrate how the Designer fares in a real-life example, try importing the NWind.mdb file. It contains 13 reports, listed below with some comments. (The NWind.XML file that ships with VSReport8 already contains all the modifications described below.)

1.

Alphabetical List of Products

No action required.

2.

Catalog

No action required.

3.

Customer Labels

No action required.

4.

Employee Sales by Country

This report contains code which needs to be translated manually. The following code should be assigned to the Group 1 Header Section's OnPrint event:

If SalespersonTotal > 5000 Then

ExceededGoalLabel.Visible = True

SalespersonLine.Visible = True

Else

ExceededGoalLabel.Visible = False

SalespersonLine.Visible = False

End If

5.

Invoice

No action required.

6.

Products by Category

No action required.

7.

Sales by Category

This report contains a Chart control that is not imported. To add a chart to your report, you could use an unbound picture field, then write a VB event handler that would create the chart and assign it to the field as a picture.

8.

Sales by Category Subreport

No action required.

9.

Sales by Year

This report contains code and references to a Form object which need to be translated manually. To replace the Form object, edit the RecordSource property to add a [Show Details] parameter:

PARAMETERS [Beginning Date] DateTime 1/1/1994,

[Ending Date] DateTime 1/1/2001,

[Show Details] Boolean False; ...

Use the new parameter in the report's OnOpen event:

Report.OnOpen = "b = [Show Details]" & _

" Detail.Visible = b" & _

" [Group 0 Footer].Visible = b" & _

" DetailsLabel.Visible = b" & _

" LineNumberLabel2.Visible = b" & _

" Line15.Visible = b" & _

" SalesLabel2.Visible = b" & _

" OrdersShippedLabel2.Visible = b" & _

" ShippedDateLabel2.Visible = b" & _

" Line10.Visible = b"

Finally, two more lines of code need to be translated:

Sections("Detail").OnPrint = _

"PageHeader.Visible = True"

Sections("Group 0 Footer).OnPrint = _

"PageHeader.Visible = False"

10.

Sales by Year Subreport

No action required.

11.

Sales Totals by Amount

This report contains code that needs to be translated manually. The following code should be assigned to the Page Header Section's OnPrint event:

PageTotal = 0

The following code should be assigned to the Detail Section's OnPrint event:

PageTotal = PageTotal + SaleAmount

HiddenPageBreak.Visible = (Counter = 10)

12.

Summary of Sales by Quarter

This report has a group that is sorted by quarter (see item 4 above). To fix this, add a field to the source recordset that contains the value of the ShippedDate quarter, by changing the RecordSource property as follows:

SELECT DISTINCTROW Orders.ShippedDate,

Orders.OrderID,

[Order Subtotals].Subtotal,

DatePart("q",Orders.ShippedDate) As ShippedQuarter

FROM Orders INNER JOIN [Order Subtotals]

ON Orders.OrderID = [Order Subtotals].OrderID

WHERE (((Orders.ShippedDate) Is Not Null));

Change the group's GroupBy property to use the new field, ShippedQuarter.

13.

Summary of Sales by Year

No action required.

Summarizing the information on the table: out of 13 reports imported from the NorthWind database, eight did not require any editing, three required some code translation, one required changes to the SQL statement, and one had a chart control that was not replaced.


VSView Reporting Edition Reference

VSReport Control

Section Object

Field Object

Group Object

SectionCollection Object

FieldCollection Object

GroupCollection Object

DataSource Object

Layout Object


VSReport Control

All of the properties, methods and events for the VSReport control are listed below, and are documented in the following sections. Properties, methods and events that apply only to this control, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*Cancel | Returns or sets whether to cancel generation of the current report.
*DataSource | Returns the current report's DataSource object.
*DoEvents | Returns or sets whether the control should process Windows messages while rendering reports.
*Fields | Returns the current report's Fields collection.
*Font | Returns or sets the default font for new fields.
*Groups | Returns the current report's Groups collection.
*IsBusy | Returns whether a report is currently being generated.
*Layout | Returns the current report's Layout object.
*MaxPages | Returns or sets the maximum number of pages allowed for a report.
*OnClose | Returns or sets the VBScript handler for the OnClose event.
*OnError | Returns or sets the VBScript handler for the OnError event.
*OnNoData | Returns or sets the VBScript handler for the OnNoData event.
*OnOpen | Returns or sets the VBScript handler for the OnOpen event.
*OnPage | Returns or sets the VBScript handler for the OnPage event.
*Page | Returns or sets the current page number.
*ReportName | Returns or sets the name of the report.
*Sections | Returns the current report's Sections collection.
Tag | Stores any extra data needed for your program.

Methods

*Clear | Clears the current report.
*Copy | Copies all the information from an existing report object.
*Evaluate | Evaluates a VBScript expression in the current report context.
*Execute | Executes a VBScript statement in the current report context.
*GetReportInfo | Returns information from a report definition file.
*Load | Loads a report from an XML report definition file.
*Render | Renders a report into a VSPrinter control.
*RenderToFile | Renders a report into a file.

Events

*OnClose | Fired when the control finishes rendering the report.
*OnError | Fired when an error occurs while rendering a report.
*OnFormat | Fired before the Section is formatted.
*OnNoData | Fired when the control starts rendering a report and the source recordset is empty.
*OnOpen | Fired when the control starts rendering the report, before it opens the source recordset.
*OnPage | Fired when the control finishes rendering each page.
*OnPrint | Fired before the Section is printed (after it is formatted).


VSReport Properties

Cancel Property

DataSource Property

DoEvents Property

Fields Property

Font Property

Groups Property

IsBusy Property

Layout Property

MaxPages Property

OnClose Property

OnError Property

OnNoData Property

OnOpen Property

OnPage Property

Page Property

ReportName Property

Sections Property


Cancel Property

Returns or sets whether to cancel generation of the current report.

Syntax

[form!]VSReport.Cancel[ = {True | False} ]

Remarks

Setting this property to True while a report is being generated stops the report generation process. Any pages already created are kept.

This property is typically used to implement a "Cancel" button. For example:

Private Sub Cancel_Click()

If vsr.IsBusy Then

Debug.Print "Cancelling Report"

vsr.Cancel = True

Else

Debug.Print "No report to cancel"

End If

End Sub

You can read the Cancel property to determine whether the report ended normally or was cancelled by the user:

Private Sub vsr_OnClose()

If vsr.Cancel Then

Debug.Print "** The report was Cancelled."

End If

End Sub

In order for the application to process mouse clicks during report generation, the DoEvents property must be set to True.

You can also limit the size of a report using the MaxPages and MaxRecords properties.

Data Type

Boolean

See Also

VSReport Control


DataSource Property

Returns the current report's DataSource object.

Syntax

val% = [form!]VSReport.DataSource

Remarks

The DataSource Object is responsible for providing the data for the report. It encapsulates an ADO recordset and has the following properties:

ConnectionString | Database that contains the report data.
RecordSource | Table or SQL statement used to generate the recordset.
Filter | Condition used to filter records that are added to the recordset.
MaxRecords | Maximum number of records to retrieve (zero means no limit).
Recordset | ADO Recordset object that contains the report data. The Recordset may be retrieved while the report is being generated, and it may be set when handling the OnOpen event.
FieldInfo | Array containing field names, types, and maximum length. This array may be retrieved even if the Recordset is no open, and is useful for designer-type applications.

Data Type

IDataSource

See Also

VSReport Control


DoEvents Property

Returns or sets whether the control should process Windows messages while rendering reports.

Syntax

[form!]VSReport.DoEvents[ = {True | False} ]

Remarks

Setting this property to True (default) allows users to resize forms, click buttons, etc. while reports are being generated. This makes applications more responsive, and is necessary if you want to provide a "Cancel Report" button (otherwise users wouldn't be able to click the button until the report was done). For example:

Private Sub Render_Click()

If vsr.IsBusy Then

Debug.Print "Can't render now, object is busy"

Else

vsr.Render vp

End If

End Sub

Private Sub Cancel_Click()

If vsr.IsBusy Then

Debug.Print "Cancelling Report"

vsr.Cancel = True

Else

Debug.Print "No report to cancel"

End If

End Sub

Note that the code above checks whether the object is busy before starting to render a report. This is necessary because the user could click the "Render" button several times in a row, before the control got a chance to render the whole report. (Calling the Render method while the control is busy would raise an error).

Setting the DoEvents property to True is similar to adding the DoEvents VB statement to loops in your code.

Data Type

Boolean

See Also

VSReport Control


Fields Property

Returns the current report's Fields collection.

Syntax

val% = [form!]VSReport.Fields

Remarks

The Fields collection contains all Field objects defined in the current report. The collection has the following methods and properties:

Item | Returns a Field object, indexed by position or by name.
Count | Returns a count of all Field objects in the collection.
Add | Adds a Field object to the collection (and to the report).
Remove | Removes a Field object from the collection (and from the report).

When you add a field to the report's Fields collection, the field is not assigned to any sections, and it does not become visible until its Section property is set. For example, the code below adds a field to the vsrDetail section:

vsr.Fields.Add "New Field", "Hello", 0, 0, 1000, 300

vsr.Fields("New Field").Section = vsrDetail

Data Type

IFieldCollection

See Also

VSReport Control


Font Property

Returns or sets the default font for new fields.

Syntax

[form!]VSReport.Font[ = Font ]

Remarks

The Font property is not used directly when rendering the report. It is used as the default font for new fields.

For example, the code below adds four fields to the report. The font for the first two fields is 9pt Arial, and for the last two it is 12pt Tahoma:

vsr.Font.Name = "Arial"

vsr.Font.Size = 9

vsr.Fields.Add "New1", "Hello", 0, 0, 1000, 300

vsr.Fields.Add "New2", "World", 1000, 0, 1000, 300

vsr.Font.Name = "Tahoma"

vsr.Font.Size = 12

vsr.Fields.Add "New3", "Hello", 0, 3000, 1000, 300

vsr.Fields.Add "New4", "World", 1000, 3000, 1000, 300

You can change the field's font after it's been created using the field's own Font property:

vsr.Fields("New1").Font.Size = 24

Data Type

Font

See Also

VSReport Control


Groups Property

Returns the current report's Groups collection.

Syntax

val% = [form!]VSReport.Groups

Remarks

The Groups collection contains all Group objects defined in the current report. The collection has the following methods and properties:

Item | Returns a Group object, indexed by position or by name.
Count | Returns a count of all Group objects in the collection.
Add | Adds a Group object to the collection (and to the report).
Remove | Removes a Group object from the collection (and from the report).

Removing a Group object from this collection also removes its associated header and footer sections, as well as any fields in those sections.

Adding a Group object to this collection also adds group header and footer sections to the report.

Data Type

IGroupCollection

See Also

VSReport Control


IsBusy Property

Returns whether a report is currently being generated.

Syntax

val% = [form!]VSReport.IsBusy

Remarks

Use this property to determine whether the control is currently busy generating a report.

This property is especially useful when the DoEvents property is set to True. In this case, the application continues to process user input while the control generates reports, and there is a change that the user might try to start another report before the current one is done.

The code below shows a typical application of the IsBusy property:

Private Sub Render_Click()

If vsr.IsBusy Then

Debug.Print "Can't render now, the control is busy."

Else

vsr.Render vp

End If

End Sub

Private Sub Cancel_Click()

If vsr.IsBusy Then

Debug.Print "Cancelling Report"

vsr.Cancel = True

Else

Debug.Print "No report to cancel"

End If

End Sub

Data Type

Boolean

See Also

VSReport Control


Layout Property

Returns the current report's Layout object.

Syntax

val% = [form!]VSReport.Layout

Remarks

The Layout object defines how the report is rendered on a page. It contains the following properties:

Width | Width of the report, in twips. For multi-column reports, this is the width of each column.
MarginLeft | Left margin, in twips.
MarginTop | Top margin, in twips.
MarginRight | Right margin, in twips.
MarginBottom | Bottom margin, in twips.
Columns | Number of columns in the report.
ColumnLayout | Whether columns grow down or to the right.
Orientation | Whether to use Portrait or Landscape.
PageHeader | Whether the PageHeader section appears on all pages.
PageFooter | Whether the PageFooter section appears on all pages.
Picture | Background picture for the report (watermark-style).
PictureAlign | Alignment for the background picture.
PictureShow | Whether the background picture appears on all pages.

Data Type

ILayout

See Also

VSReport Control


MaxPages Property

Returns or sets the maximum number of pages allowed for a report.

Syntax

[form!]VSReport.MaxPages[ = value As Long ]

Remarks

This property is useful if you want to limit the maximum number of pages in a report. For example, you may write a report designer with a preview window that shows the first five pages of a report.

Setting this property to zero (default) allows reports of any length.

You can also limit the size of reports by setting the MaxRecords property.

Data Type

Long

See Also

VSReport Control


OnClose Property

Returns or sets the VBScript handler for the OnClose event.

Syntax

[form!]VSReport.OnClose[ = value As String ]

Remarks

This property contains a string with a VBScript that gets executed when the report finishes rendering. The control also fires the OnClose event at this time.

The difference between the regular event and the VBScript property is that the handler for the regular event belongs to the application, and should thus be used to support tasks that are independent of the report. For example, to enable or disable buttons depending on whether or not a report is being rendered.

The VBScript handler in the property belongs to the report, and will be executed regardless of the application. For example, a particular report might contain a VBScript handler that resets the page counter when it finishes rendering (this could be useful in a subreport).

Data Type

String

See Also

VSReport Control


OnError Property

Returns or sets the VBScript handler for the OnError event.

Syntax

[form!]VSReport.OnError[ = value As String ]

Remarks

This property contains a string with a VBScript that gets executed when an error occurs while the control is rendering a report. The control also fires the OnError event at this time.

The difference between the regular event and the VBScript property is that the handler for the regular event belongs to the application, and should thus be used to support tasks that are independent of the report. For example, to show an application dialog box when an error occurs.

The VBScript handler in the property belongs to the report, and will be executed regardless of the application. For example, a particular report might contain a VBScript handler that changes the value of a field when an error occurs.

Data Type

String

See Also

VSReport Control


OnNoData Property

Returns or sets the VBScript handler for the OnNoData event.

Syntax

[form!]VSReport.OnNoData[ = value As String ]

Remarks

This property contains a string with a VBScript that gets executed when a report starts rendering and its source recordset is empty. The control also fires the OnNoData event at this time.

The difference between the regular event and the VBScript property is that the handler for the regular event belongs to the application, and should thus be used to support tasks that are independent of the report. For example, to cancel rendering a report with no data.

The VBScript handler in the property belongs to the report, and will be executed regardless of the application. For example, a particular report might contain a VBScript handler that changes the value of a field when the source recordset is empty.

Data Type

String

See Also

VSReport Control


OnOpen Property

Returns or sets the VBScript handler for the OnOpen event.

Syntax

[form!]VSReport.OnOpen[ = value As String ]

Remarks

This property contains a string with a VBScript that gets executed when a report starts rendering and its source recordset is empty. The control also fires the OnOpen event at this time.

The difference between the regular event and the VBScript property is that the handler for the regular event belongs to the application, and should thus be used to support tasks that are independent of the report. For example, to display a message on the main window when rendering starts.

The VBScript handler in the property belongs to the report, and will be executed regardless of the application. For example, a particular report might contain a VBScript handler that resets global variables in the VBScript context when a report starts rendering.

Data Type

String

See Also

VSReport Control


OnPage Property

Returns or sets the VBScript handler for the OnPage event.

Syntax

[form!]VSReport.OnPage[ = value As String ]

Remarks

This property contains a string with a VBScript that gets executed when the control finishes rendering a page. The control also fires the OnPage event at this time.

The difference between the regular event and the VBScript property is that the handler for the regular event belongs to the application, and should thus be used to support tasks that are independent of the report. For example, to update a label showing how many pages have been rendered so far.

The VBScript handler in the property belongs to the report, and will be executed regardless of the application. For example, a particular report might contain a VBScript handler that updates a variable at every page break.

Data Type

String

See Also

VSReport Control


Page Property

Returns or sets the current page number.

Syntax

[form!]VSReport.Page[ = value As Long ]

Remarks

The Page property is a global variable available to VBScript expressions. It is automatically initialized by the control with the value 1 when a reports starts rendering, and it is automatically incremented after each page break.

The Page variable is typically used in page headers or footers, often in combination with the Pages variable, which provides a global page count for the report. For example, the code below creates a field in the page footer section that displays a "Page n of m" counter. (This could also be done using the Designer).

vsr.Sections(vsrPageFooter).Fields.Add "PageCounterFld", _

"=""Page "" & [Page] & "" of "" & [Pages]", _

5000, 0, 5000, 300

vsr.Fields("PageCounterFld").Calculated = True

The Page property is read-write, so you can reset it using scripts. For example, the code below causes the Page variable to be reset to 1 at the beginning of every top-level group:

' assign a VBScript handler to the OnPrint event

' of section "Group 0 Header"

vsr.Sections("Group 0 Header").OnPrint = "Page = 1"

Data Type

Long

See Also

VSReport Control


ReportName Property

Returns or sets the name of the report.

Syntax

[form!]VSReport.ReportName[ = value As String ]

Remarks

The ReportName property identifies the report when it is saved in a report definition file. To retrieve the report from the report definition file, you need to use the Load method and pass this name as a parameter. For example:

' load report from XML file

vsr.Load App.Path & DataFileName, "Employees"

' show report name

Debug.Print vsr.ReportName

Employees

Note that several reports may be saved in a single report definition file. You should ensure that each report has a unique name, or you won't be able to retrieve all reports from the file.

Data Type

String

See Also

VSReport Control

Load Method


Sections Property

Returns the current report's Sections collection.

Syntax

val% = [form!]VSReport.Sections

Remarks

The Sections collection contains all Section objects defined in the current report. The collection has the following methods and properties:

Item | Returns a Section object, indexed by section type.
Count | Returns a count of all Section objects in the collection.

Note that the Sections collection does not have Add or Remove methods. The number of sections in a report is determined by the number of Groups. Every report has five "fixed" sections (detail, report header, report footer, page header, and page footer) plus two sections per group (a group header and a group footer). The table below shows the relationship between the sections and groups for a typical report:

Constant | Value | Description
vsrDetail | 0 | Detail section, repeated for each record in the recordset. Always present.
vsrHeader | 1 | Report header section. Always present.
vsrFooter | 2 | Report footer section. Always present.
vsrPageHeader | 3 | Page header section. Always present.
vsrPageFooter | 4 | Page footer section. Always present.
vsrGroupHeader1 | 5 | First group header. Present in reports with one or more groups.
vsrGroupFooter1 | 6 | First group footer. Present in reports with one or more groups.
vsrGroupHeader2 | 7 | Second group header. Present in reports with two or more groups.
vsrGroupFooter2 | 8 | Second group footer. Present in reports with two or more groups.

Data Type

ISectionCollection

See Also

VSReport Control


VSReport Methods

Clear Method

Copy Method

Evaluate Method

Execute Method

GetReportInfo Method

Load Method

Render Method

RenderToFile Method


Clear Method

Clears the current report.

Syntax

[form!]VSReport.Clear

Remarks

This method removes all groups, group sections, and fields from the current report. It also resets the DataSource and Layout objects. It also clears (but does not remove) the fixed sections that all reports have: vsrDetail, vsrHeader, vsrFooter, vsrPageHeader, and vsrPageFooter.

Use this method if you want to clear a report and start creating a new one from scratch.

See Also

VSReport Control


Copy Method

Copies all the information from an existing report object.

Syntax

[form!]VSReport.Copy SourceReport As IVSReport

Remarks

This method copies a report definition from one control to another. It is useful mainly in applications that provide report design capabilities, when implementing Undo/Redo or Copy/Paste functionality. For example:

Private Sub SaveUndoState()

m_vsrUndo.Copy vsr ' copy report to undo buffer

m_bCanUndo = True ' we can Undo now

End Sub

Private Sub Undo_Click()

If m_bCanUndo Then ' make sure we can undo

vsr.Copy m_vsrUndo ' copy buffer into main report

m_bCanUndo = False ' we can't undo now

End If

End Sub

See Also

VSReport Control


Evaluate Method

Evaluates a VBScript expression in the current report context.

Syntax

[form!]VSReport.Evaluate (Expression As String)

Remarks

Use this method to evaluate expressions as they would be evaluated while generating a report. This can be useful in designer-type applications, to provide an "Immediate Window" where users can test expressions to make sure they are correct.

The Expression parameter contains a string with VBScript instructions to be evaluated by the control. For example:

? vsr.Evaluate("2+2")

4

? vsr.Evaluate(" ""A"" & ""B"" ")

AB

In addition to the standard VBScript instructions, you have access to the Report object (the control) and all its sub-objects. For example:

? vsr.Evaluate("Report.DataSource.RecordSource")

SELECT DISTINCTROW Categories.CategoryName, Categories.Description, Categories.Picture, ...

? vsr.Evaluate("Report.DataSource.Recordset.Fields.Count")

7

? vsr.Evaluate("Report.Fields(0).Name")

Line106

? vsr.Evaluate("Report.Fields(0).BackColor")

16777215

Finally, to simplify the syntax of the expressions, all report field objects and recordset fields can be referenced directly by name. For example:

? vsr.Evaluate("Report.Fields(""Line106"").BackColor")

16777215

? vsr.Evaluate("Line106.BackColor")

16777215

? vsr.Evaluate("CategoryName")

Beverages

If the Expression string contains invalid syntax or causes an evaluation error, the control raises an error.

See Also

VSReport Control


Execute Method

Executes a VBScript statement in the current report context.

Syntax

[form!]VSReport.Execute Statement As String

Remarks

This method is similar to the Evaluate method, except it does not return a value. For example, the following statement would move the field "Line106" one inch to the left:

vsr.Execute("Line106.Left = Line106.Left + 1440")

See Also

VSReport Control


GetReportInfo Method

Returns information from a report definition file.

Syntax

[form!]VSReport.GetReportInfo FileName As String, Info As ReportInfoSettings, [ Index As Variant ]

Remarks

Report definition files are XML files created by applications such as the Report Designer. You can write applications to create report definition files as well; the format is quite simple. The parameters for the GetReportInfo method are described below:

FileName As String

This parameter contains the full name of the XML report definition file.

Info As ReportInfoSettings

This parameter specifies the information you want to retrieve. Valid settings are:

Constant | Value | Description
vsrRICount | 0 | Returns the number of report definitions in the file.
vsrRIName | 1 | Returns the name of a report in the file. Use the Index parameter to specify which report.
vsrRIList | 2 | Returns a tab-separated list of all reports contained in the file.

Index As Variant (optional)

This parameter is used when Info is set to 1 - vsrRIName, to specify which report to retrieve. The index should be between 0 and GetReportInfo(vsrRICount) - 1.

For example, the following code populates a ComboBox control with all the reports in a file:

' count how many reports are in the definition file

s = App.Path & DataFileName

iCnt = vsr.GetReportInfo(s, vsrRICount)

' populate list box

cmbReport.Clear

For i = 0 To iCnt - 1

cmbReport.AddItem vsr.GetReportInfo(s, vsrRIName, i)

Next

The following version is more efficient, because it only needs to go through the report definition file once:

' get a tab-separated list of the reports in the definition file

s = App.Path & DataFileName

sList = vsr.GetReportInfo(s, vsrRIList)

vList = Split(sList, vbTab)

' populate list box

cmbReport.Clear

For i = 0 To UBound(vList)

cmbReport.AddItem vList(i)

Next

Use the Load method to load a report from a report definition file.

See Also

VSReport Control


Load Method

Loads a report from an XML report definition file.

Syntax

[form!]VSReport.Load FileName As String, ReportName As String

Remarks

Report definition files are XML files created by applications such as the Report Designer. You can write applications to create report definition files as well; the format is quite simple.

The parameters for the Load method are described below:

FileName As String

This parameter contains the full name of the XML report definition file.

ReportName As String

This parameter specifies the report you want to retrieve. You can get a list of reports available in the file using the GetReportInfo method. The ReportName parameter is case-insensitive, so you can use "yearly sales" to retrieve a report called "Yearly Sales".

For example, the following code populates a ComboBox control with all the reports in a file:

' get a tab-separated list of the reports

' in the report definition file

s = App.Path & DataFileName

sList = vsr.GetReportInfo(s, vsrRIList)

vList = Split(sList, vbTab)

' populate list box

cmbReport.Clear

For i = 0 To UBound(vList)

cmbReport.AddItem vList(i)

Next

The following code loads and renders a report when the user picks it from the list:

Private Sub cmbReport_Click()

' make sure control is ready

If vsr.IsBusy Then Beep: Exit Sub

' load report from XML file

s = App.Path & DataFileName

vsr.Load s, cmbReport.Text

' render report

vsr.Render vp

End Sub

You can also load reports at design time, using the "Load Report" property page. If you load a report this way, it is saved as part of the control data, and becomes part of your application. In this case, you don't need to distribute any report definition files. If you want to make several reports available to your users, and don't want to distribute a report definition file, use multiple controls on the form, and load a different report into each one at design time.

The control does not have any methods for saving report definition files. However, because the control uses XML as its native format, you can easily write code to generate your own report definition files. This is what the Reports Designer application does.

See Also

VSReport Control


Render Method

Renders a report into a VSPrinter control.

Syntax

[form!]VSReport.Render VSPrinter As Object

Remarks

This method causes the control to render the current report into a VSPrinter control.

The method does not return until the report has been completed (or until an error occurs). To avoid freezing your application while long reports are rendered, set the DoEvents property to True. In this case, you should check the IsBusy property to determine whether the control is busy before telling it to render another report. For example:

Private Sub Form_Load()

vsr.DoEvents = True

End Sub

' this button could be clicked while a report is being rendered

Private Sub Render_Click()

If vsr.IsBusy Then

MsgBox "Please wait until the current report is done."

Else

vsr.Render vp

End If

End Sub

After the report has been rendered into the VSPrinter control, it can be previewed, printed, or saved by the user as any other VSPrinter document.

To render a report directly to a file, use the RenderToFile method instead.

See Also

VSReport Control


RenderToFile Method

Renders a report into a file.

Syntax

[form!]VSReport.RenderToFile FileName As String, Format As FileFormatSettings

Remarks

This method causes the control to render the current report into a file. It is especially useful in server applications that create several reports in batch mode, and don't have a user interface. The parameters for the RenderToFile method are described below:

FileName As String

This parameter contains the name of the file to be created. If the file already exists, it will be overwritten.

Format As FileFormatSettings

This parameter determines the format of the export file. Valid settings are:

Constant | Value | Description
vsrVSPrinter | 0 | VSPrinter format. These files can be loaded into a VSPrinter8 control using VSPrinter's LoadDoc method or URL property.
vsrHTML | 1 | Plain HTML format. This setting creates a single HTML file that can be viewed in any web browser.
vsrHTMLPaged | 2 | Paged HTML format. This setting creates one HTML file for each page in the report, with links to navigate between pages.
vsrHTMLDrillDown | 3 | Drill-down HTML format. This setting creates a single HTML file with collapsible headings. When viewed in the Internet Explorer browser, double-clicking group headers causes them to collapse and expand to show the detail.
vsrPDF | 4 | Adobe's PDF format. This setting creates a PDF file that can be viewed using Adobe Acrobat software.
vsrText | 5 | Plain text.
vsrRTF | 6 | RTF format.

See Also

VSReport Control


VSReport Events

OnClose Event

OnError Event

OnFormat Event

OnNoData Event

OnOpen Event

OnPage Event

OnPrint Event


OnClose Event

Fired when the control finishes rendering the report.

Syntax

Private Sub VSReport_OnClose()

Remarks

You can use this event to provide user feedback. To determine whether the whole report was rendered, or whether it was cancelled by the user, check the value of the Cancel property. For example:

Private Sub vsr_OnClose()

If vsr.Cancel Then

Debug.Print "** The report was Cancelled."

End If

End Sub

See Also

VSReport Control


OnError Event

Fired when an error occurs while rendering a report.

Syntax

Private Sub VSReport_OnError( ByVal Number As Long, ByVal Description As String, Handled As Boolean)

Remarks

The parameters for the OnError event are described below:

Number As Long

This parameter contains a code that identifies the type of error. Possible values for this code are:

Value | Description
1000 | Can't create XML parser (check whether MSXML.DLL is present and registered.)
1001 | Can't open XML report definition file.
1002 | Report definition not found in XML file.
1003 | Can't create ADO objects (check whether MSADO15.DLL is present and registered.)
1004 | Can't open connection (check Connection string).
1005 | Can't open recordset (check RecordSource string).
1006 | Bad or missing data source for subreport.
1007 | Error loading report (check XML syntax).
1008 | Can't open recordset (check Sort and Filter expressions).
1009 | Can't create VSPrinter object (is VSPRINTER8.ocx present and registered?)
1010 | Can't start document (VSReport object is busy).
1011 | Can't start document (VSPrinter object is busy).
1012 | Failed to filter recordset. Check the Filter property for the report and the Text property for any Subreport fields.
1013 | Failed to sort recordset.
1014 | This feature is unavailable to preserve browser security.

Description As String

This parameter contains a description of the error.

Handled As Boolean

The default value for this parameter is False, which indicates that the error has not been handled and that the control should raise an exception. Set it to True to indicate that you have handled the error and the control should ignore it and continue rendering the report.

See Also

VSReport Control


OnFormat Event

Fired before the Section is formatted.

Syntax

Private Sub VSReport_OnFormat( ByVal SectionIndex As Long)

See Also

VSReport Control


OnNoData Event

Fired when the control starts rendering a report and the source recordset is empty.

Syntax

Private Sub VSReport_OnNoData()

Remarks

Use this event to cancel rendering a report when the source recordset is empty. To cancel rendering the empty report, set the Cancel property to True while handling this event. For example:

Private Sub vsr_OnNoData()

vsr.Cancel = True

End Sub

If you don't set the Cancel property to True, the report will be rendered as an unbound report (a self-contained report with no underlying data).

See Also

VSReport Control


OnOpen Event

Fired when the control starts rendering the report, before it opens the source recordset.

Syntax

Private Sub VSReport_OnOpen()

Remarks

You can use this event to provide user feedback or to make changes to the ConnectionString and RecordSource properties.

For example, you may want to implement your own version of parameterized queries by asking the user to provide some information and changing the RecordSource property accordingly.

See Also

VSReport Control


OnPage Event

Fired when the control finishes rendering each page.

Syntax

Private Sub VSReport_OnPage()

Remarks

Use this event to update the user interface on your application to show how many pages have been printed so far.

You can use the Cancel property while handling this event to cancel rendering the report. To limit the number of pages that can be printed, use the MaxPages property instead.

See Also

VSReport Control


OnPrint Event

Fired before the Section is printed (after it is formatted.)

Syntax

Private Sub VSReport_OnPrint( ByVal SectionIndex As Long)

Remarks

You can use this event to build report elements as the report is generated. The event is similar to the Section object's OnPrint property, which contains a VBScript string that gets executed when a section is rendered. The difference between the two is that the traditional event handler is implemented by the application that is rendering the report, and the VBScript event is implemented within the report itself, and is therefore viewer-independent.

For example, the code below generates a chart and assigns it to a field in the report:

Private Sub vsr_OnPrint(ByVal SectionIndex As Long)

' get the field we want to render as a chart

Dim theField As Field

Set theField = vsr.Fields("SalesChart")

' make sure this is the section we want

If theField Is Nothing Then Exit Sub

If SectionIndex <> theField.Section Then Exit Sub

' create chart and copy it to the clipboard

CreateChartOnClipboard

' paste chart into report field

theField.Picture = Clipboard.GetData(vbCFMetafile)

End Sub

See Also

VSReport Control


Section Object

All of the properties for the Section object are listed in the following tables. Properties and methods that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*BackColor | Returns or sets the Section's background color.
*CanGrow | Returns or sets whether the Section height should be automatically increased to fit its contents.
*CanShrink | Returns or sets whether the Section height should be automatically decreased to fit its contents.
*Fields | Returns a collection of all the Fields in this Section.
*ForcePageBreak | Returns or sets whether page breaks should be inserted before and/or after the section is rendered.
*Height | Returns or sets the Section height.
*KeepTogether | Returns or sets whether the Section should be kept together on a page.
*Name | Returns or sets the Section name.
*OnFormat | Returns or sets a string containing VBScript code to be executed before the Section is formatted.
*OnPrint | Returns or sets a string containing VBScript code to be executed before the Section is printed (after it is formatted).
*RenderHeight | Returns the height of the section after it has been modified to accommodate CanGrow/CanShrink fields.
*Repeat | Returns or sets whether the section should be repeated at the top of every page.
*Tag | Returns or sets extra data needed by the calling program.
*Type | Returns the Section type (e.g., vsrPageHeader, vsrDetail).
*Visible | Returns or sets whether the Section will be rendered.


Section Properties

BackColor Property (Section)

CanGrow Property (Section)

CanShrink Property (Section)

Fields Property (Section)

ForcePageBreak Property (Section)

Height Property (Section)

KeepTogether Property (Section)

Name Property (Section)

OnFormat Property

OnPrint Property

RenderHeight Property (Section)

Repeat Property

Tag Property (Section)

Type Property

Visible Property (Section)


BackColor Property (Section)

Returns or sets the Section's background color.

Syntax

section.BackColor[ = colorref& ]

Remarks

Setting this property to a value other than white causes the section's rectangle to be filled with the specified color.

The section's rectangle is determined by the section's Height property and the report's Layout.Width property. The rectangle height is adjusted if the CanGrow or CanShrink properties are set to True.

Data Type

Color

See Also

Section Object


CanGrow Property (Section)

Returns or sets whether the Section height should be automatically increased to fit its contents.

Syntax

section.CanGrow[ = {True | False} ]

Remarks

You can use the CanGrow and CanShrink properties to control the appearance of report sections and fields. For example, if you set both properties to True, a section or field automatically adjusts vertically to print or preview all the data it contains.

Sections grow and shrink vertically across their entire width.

Data Type

Boolean

See Also

Section Object


CanShrink Property (Section)

Returns or sets whether the Section height should be automatically decreased to fit its contents.

Syntax

section.CanShrink[ = {True | False} ]

Remarks

You can use the CanGrow and CanShrink properties to control the appearance of report sections and fields. For example, if you set both properties to True, a section or field automatically adjusts vertically to print or preview all the data it contains.

Sections grow and shrink vertically across their entire width.

Data Type

Boolean

See Also

Section Object


Fields Property (Section)

Returns a collection of all the Fields in this Section.

Syntax

section.Fields[ = IFieldCollection ]

Remarks

The Fields collection contains all Fields objects defined in the current section. The collection has the following methods and properties:

Item | Returns a Field object, indexed by position or by name.
Count | Returns a count of all Field objects in the collection.
Add | Adds a Field object to the collection (and to the report).
Remove | Removes a Field object from the collection (and from the report).

When you add a field to a section's Fields collection, the field is automatically assigned to the section that owns the collection. For example, the code below adds a field to the vsrDetail section:

vsr.Sections(vsrDetail).Fields.Add _

"New Field", "Hello", 0, 0, 1000, 300

Data Type

IFieldCollection

See Also

Section Object


ForcePageBreak Property (Section)

Returns or sets whether page breaks should be inserted before and/or after the section is rendered.

Syntax

section.ForcePageBreak[ = BreakSettings ]

Remarks

The settings for the ForcePageBreak property are described below:

Constant | Value | Description
vsrNone | 0 | No page breaks.
vsrBefore | 1 | A page break is inserted before the section.
vsrAfter | 2 | A page break is inserted after the section.
vsrBeforeAndAfter | 3 | Page breaks are inserted before and after the section.
vsrForcePage | 256 | In multi-column reports, use page breaks instead of column breaks (this value is a flag that may be combined with any of the other settings).

Data Type

BreakSettings (Enumeration)

See Also

Section Object


Height Property (Section)

Returns or sets the Section height.

Syntax

section.Height[ = value As Double ]

Remarks

The Height of a section should be large enough to accommodate all Fields in the section.

The Report Designer automatically adjusts section heights when fields are added, moved, or resized. The code below shows how an application can ensure that the section is tall enough to accommodate all the fields it contains:

' get section object

Dim theSection As VSREPORTLibCtl.Section

Set theSection = vsr.Sections(vsrDetail)

' scan all its fields

For i = 0 To theSection.Fields.Count - 1

' get field bottom

Dim theField As VSREPORTLibCtl.Field

Set theField = theSection.Fields(i)

h = theField.Top + theField.Height

' make sure section is tall enough for the field

If h > theSection.Height Then

theSection.Height = h + 200

End If

Next

Data Type

Double

See Also

Section Object


KeepTogether Property (Section)

Returns or sets whether the Section should be kept together on a page.

Syntax

section.KeepTogether[ = {True | False} ]

Remarks

This property determines whether the section should be kept together on a page. The default value is True.

NOTE: The Group object also has a KeepTogether property that works across sections. It determines whether group headers should be kept together with their first detail section or whether entire groups should be kept together on a page.

Data Type

Boolean

See Also

Section Object


Name Property (Section)

Returns or sets the Section name.

Syntax

section.Name[ = value As String ]

Remarks

The section name can be used as an index into the control's Sections collection. For example:

vsr.Sections("Detail").Height = 1440

Data Type

String

See Also

Section Object


OnFormat Property

Returns or sets a string containing VBScript code to be executed before the Section is formatted.

Syntax

section.OnFormat[ = value As String ]

Remarks

The OnFormat property contains VBScript instructions that get executed before the fields in the section are calculated.

When this script is executed, the recordset already holds the data that will be displayed in the section, but the field values have not been updated yet. Use this event to assign values to fields before they are calculated, so the new values will be taken into account when the control calculates the field's size and position when the CanGrow or CanShrink properties are set to True.

If you want to set field properties based on the field's current value, use the OnPrint property instead.

Data Type

String

See Also

Section Object


OnPrint Property

Returns or sets a string containing VBScript code to be executed before the Section is printed (after it is formatted).

Syntax

section.OnPrint[ = value As String ]

Remarks

The OnPrint property contains VBScript instructions that get executed after the fields in the section have been calculated.

For example, the following code adjusts the width of a field based on the value of another field:

Dim theScript$

theScript = "BarFld.Width = SaleAmountMaxFld.Width * (SaleAmountFld / SaleAmountMaxFld)"

vsr.Sections("Detail").OnPrint = theScript

The BarFld field is a green rectangle. By changing its Width property for each detail section , the report creates a bar chart.

The SaleAmountMaxFld contains an expression that calculates the maximum value for the SaleAmount recordset field. The expression is "=Max([SaleAmount])". The value and width of the SaleAmountMaxFld are used to calculate the width of the bar.

Data Type

String

See Also

Section Object


RenderHeight Property (Section)

Returns the height of the section after it has been modified to accommodate CanGrow/CanShrink fields.

Syntax

section.RenderHeight[ = value As Double ]

Remarks

The Height property specifies the design height of a Section. When the CanGrow or CanShrink properties of the Section are set to true, however, this value is adjusted to account for the size of the fields within the section. The RenderHeight property returns the adjusted height value, which can be used within event handlers to adjust the position of fields within the section.

This value is calculated after the OnFormat script event fires (so any changes the script makes to the field are accounted for), but before the OnPrint event fires. Therefore, you can only use RenderHeight when handling the OnPrint event.

Data Type

Double

See Also

Section Object


Repeat Property

Returns or sets whether the section should be repeated at the top of every page.

Syntax

section.Repeat[ = {True | False} ]

Remarks

Set this value to True to repeat the group header page at the top of every page, before the detail sections.

If you have multiple groups, all group header sections that have the Repeat property set to True will be rendered at the top of each page.

Data Type

Boolean

See Also

Section Object


Tag Property (Section)

Returns or sets extra data needed by the calling program.

Syntax

section.Tag[ = value As Variant ]

Data Type

Variant

See Also

Section Object


Type Property

Returns the Section type (e.g., vsrPageHeader, vsrDetail).

Syntax

val% = section.Type

Remarks

The section type is equivalent to its index in the control's Sections collection. The control defines symbols for these indices to improve readability. The symbols defined are:

Constant | Value | Description
vsrUndefined | -1 | Undefined. When new fields are created using the control's Fields collection, they don't belong to any sections.
vsrDetail | 0 | Detail section: repeated for every record in the source recordset.
vsrHeader | 1 | Report header section: appears once, in the beginning of the report.
vsrFooter | 2 | Report footer section: appears once, in the end of the report.
vsrPageHeader | 3 | Page header section: appears at the top of every page, depending on the setting of the Layout's PageHeader property.
vsrPageFooter | 4 | Page footer section: appears at the bottom of every page, depending on the setting of the Layout's PageFooter property.
vsrGroupHeader1 | 5 | First group header section: appears at the top of every top-level group.
vsrGroupFooter1 | 6 | First group footer section: appears at the bottom of every top-level group.

The Type property allows you to inspect a Section object and determine its type. For example:

Debug.Print theSection.Type

0 ' vsrDetail

Data Type

SectionTypeSettings (Enumeration)

See Also

Section Object


Visible Property (Section)

Returns or sets whether the Section will be rendered.

Syntax

section.Visible[ = {True | False} ]

Data Type

Boolean

See Also

Section Object


Field Object

All of the properties for the Field object are listed in the following tables. Properties that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*Anchor | Gets or sets how the field position and dimensions should be affected when the containing section changes size as a result of CanGrow or CanShrink.
*Align | Returns or sets the Field's alignment.
*BackColor | Returns or sets the Field's background color.
*BackStyle | Returns or sets whether the Field will be rendered with an opaque or transparent background.
*BorderColor | Returns or sets the Field's border color.
*BorderStyle | Returns or sets the Field's border style.
*Calculated | Returns or sets whether the Text property should be interpreted as a literal value or as a calculated expression.
*CanGrow | Returns or sets whether the Field height should be automatically increased to fit the Field's contents.
*CanShrink | Returns or sets whether the Field height should be automatically decreased to fit the Field's contents.
*Checkbox | Returns or sets whether the Field should be displayed as a checkbox.
*Font | Returns or sets the Field's font.
*ForcePageBreak | Returns or sets whether to insert page breaks before or after the field.
*ForeColor | Returns or sets the Field's foreground color.
*Format | Returns or sets how the Field's contents should be formatted.
*Height | Returns or sets the Field size and position.
*HideDuplicates | Returns or sets whether duplicate values in consecutive records should be suppressed.
*Left | Returns or sets the Field size and position.
*LineSlant | Returns or sets whether a line should be drawn across the field (as opposed to a box around the field).
*LineSpacing | Returns or sets the line spacing between text lines in the Field.
*LineWidth | Returns or sets the width of the Field's border or line.
*LinkTarget | Gets or sets an expression that evaluates to a URL to be visited when the field is clicked.
*MarginBottom | Returns or sets the margins between the Field's edges and the text it contains.
*MarginLeft | Returns or sets the margins between the Field's edges and the text it contains.
*MarginRight | Returns or sets the margins between the Field's edges and the text it contains.
*MarginTop | Returns or sets the margins between the Field's edges and the text it contains.
*Name | Returns or sets the Field name.
*Picture | Returns or sets a picture to display on the field (file names are accepted).
*PictureAlign | Returns or sets the picture alignment and scaling (see also the Picture property).
*RenderHeight | Returns the height of the field after the section has been modified to accommodate CanGrow/CanShrink fields.
*RenderTop | Returns the top of the field after the section has been modified to accommodate CanGrow/CanShrink fields.
*RTF | Returns or sets whether the field should render string enclosed in curly brackets as RTF.
*RunningSum | Returns or sets whether to show a running sum for the Field.
*Section | Returns or sets the Section to which the Field belongs.
*Subreport | Returns or sets a reference to another report to be rendered within the field (a Subreport).
*Tag | Returns or sets extra data needed by the calling program.
*Text | Returns or sets the Field's literal text or expression (depending on the Calculated property).
*Top | Returns or sets the Field size and position.
*Value | Returns or sets the Field's calculated value.
*Visible | Returns or sets whether the Field will be rendered.
*Width | Returns or sets the Field size and position.
*WordWrap | Returns or sets whether the Field's contents should be allowed to wrap within the Field rectangle.
*ZOrder | Gets or sets the ZOrder for the field.

Methods

*SetZOrder

Brings a field to the top or sends it to the bottom of the ZOrder.


Field Properties

Anchor Property

Align Property

BackColor Property (Field)

BackStyle Property

BorderColor Property

BorderStyle Property

Calculated Property

CanGrow Property (Field)

CanShrink Property (Field)

CheckBox Property

Font Property (Field)

ForcePageBreak Property (Field)

ForeColor Property

Format Property

Height Property (Field)

HideDuplicates Property

Left Property

LineSlant Property

LineSpacing Property

LineWidth Property

LinkTarget Property

MarginBottom Property (Field)

MarginLeft Property (Field)

MarginRight Property (Field)

MarginTop Property (Field)

Name Property (Field)

Picture Property (Field)

PictureAlign Property (Field)

RenderHeight Property (Field)

RenderTop Property (Field)

RTF Property

RunningSum Property

Section Property

Subreport Property

Tag Property (Field)

Text Property

Top Property

Value Property

Visible Property (Field)

Width Property (Field)

WordWrap Property

ZOrder Property


Anchor Property

Gets or sets how the field position and dimensions should be affected when the containing section changes size as a result of CanGrow or CanShrink.

Syntax

AnchorSettings Field.Anchor

Remarks

When a section grows or shrinks as a result of processing the CanGrow and CanShrink properties, fields usually retain their original position and size (Top and Height properties).

In some cases, you may want to force fields to grow with the section, regardless of their content. For example, you may have vertical lines that should span the height of the section, or horizontal borders that should be positioned with respect to the bottom of the section. You can achieve this with the Anchor property.

Valid AnchorSettings

vsrATop

Default. When the section grows, the distance between the top of the field and the top of the section remains the same.

vsrABottom

When the section grows, the field is pushed down. The distance between the bottom of the field and the bottom of the section remains the same.

vsrATopAndBottom

When the section grows, the field is stretched vertically. The distance between the top of the field and the top of the section remain the same, and so does the distance between the bottom of the field and the bottom of the section.

The diagram below shows the effect of the Anchor property on a field.

BEFORE

========================================================= section top

+----------------+ +----------------+ +----------------+

| vsrATop | | vsrABottom | |vsrATopAndBottom|

+----------------+ +----------------+ +----------------+

========================================================= section bottom

If this section grew as a result of processing the CanGrow property, it would be rendered like this:

AFTER

========================================================= section top

+----------------+ +----------------+

| vsrATop | | |

+----------------+ | |

| |

|vsrATopAndBottom|

| |

+----------------+ | |

| vsrABottom | | |

+----------------+ +----------------+

========================================================== section bottom

See Also

Field Object


Align Property

Returns or sets the Field's alignment.

Syntax

field.Align[ = FieldAlignSettings ]

Remarks

This property determines how text is aligned within the field. Valid settings are described below:

Constant | Value | Description
vsrGeneral | -1 | Align numbers to the right, other values to the left. This is the default value.
vsrLeftTop | 0 | Align to the left and to the top of the field box.
vsrCenterTop | 1 | Align to the center and to the top of the field box.
vsrRightTop | 2 | Align to the right and to the top of the field box.
vsrLeftBottom | 3 | Align to the left and to the bottom of the field box.
vsrCenterBottom | 4 | Align to the center and to the bottom of the field box.
vsrRightBottom | 5 | Align to the right and to the bottom of the field box.
vsrLeftMiddle | 6 | Align to the left and to the middle of the field box.
vsrCenterMiddle | 7 | Align to the center and to the middle of the field box.
vsrRightMiddle | 8 | Align to the right and to the middle of the field box.
vsrJustTop | 9 | Justify and align to the top of the field box.
vsrJustBottom | 10 | Justify and align to the bottom of the field box.
vsrJustMiddle | 11 | Justify and align to the middle of the field box.

NOTE: To control picture alignment, use the PictureAlign property.

Data Type

FieldAlignSettings (Enumeration)

See Also

Field Object


BackColor Property (Field)

Returns or sets the Field's background color.

Syntax

field.BackColor[ = colorref& ]

Remarks

To fill a field with a solid color, set the BackColor to the color you want and set the BackStyle property to vsrOpaque.

NOTE: When you create fields with text and a solid background, text will be positioned very close to the edges of the box. You can control the distance between the text and the box using the MarginLeft and MarginRight properties.

Data Type

Color

See Also

Field Object

BackStyle Property


BackStyle Property

Returns or sets whether the Field will be rendered with an opaque or transparent background.

Syntax

field.BackStyle[ = BackStyleSettings ]

Remarks

Valid settings for the BackStyle property are:

Constant | Value
vsrTransparent | 0
vsrOpaque | 1

Data Type

BackStyleSettings (Enumeration)

See Also

Field Object


BorderColor Property

Returns or sets the Field's border color.

Syntax

field.BorderColor[ = colorref& ]

Remarks

To draw a border around a field, set the following properties:

BorderColor

To define the border color.

BorderStyle

To define the border style (e.g. solid, dashed, etc).

LineWidth

To define the border width (in Twips).

NOTE: When you create fields with text and a border, text will be positioned very close to the border. You can control the distance between the text and the border using the MarginLeft and MarginRight properties.

Data Type

Color

See Also

Field Object

BorderStyle Property


BorderStyle Property

Returns or sets the Field's border style.

Syntax

field.BorderStyle[ = BorderStyleSettings ]

Remarks

To draw a border around a field, set the following properties:

BorderColor

To define the border color.

BorderStyle

To define the border style (e.g. solid, dashed, etc).

LineWidth

To define the border width (in Twips).

Valid settings for the BorderStyle property are described below:

Constant | Value | Description
vsrBSTransparent | 0 | No border.
vsrBSSolid | 1 | Solid border.
vsrBSDash | 2 | Dashed border.
vsrBSDot | 3 | Dotted border
vsrBSDashDot | 4 | Dash-dot border
vsrBSDashDotDot | 5 | Dash-dot-dot border.

NOTE: Due to a GDI limitation, dashed and dotted borders are only drawn when the LineWidth property is set to zero or one. Thicker borders are always solid.

Data Type

BorderStyleSettings (Enumeration)

See Also

Field Object


Calculated Property

Returns or sets whether the Text property should be interpreted as a literal value or as a calculated expression.

Syntax

field.Calculated[ = {True | False} ]

Remarks

If this property is set to False, the value of the Text property is rendered on the report without any further processing. If it is set to True, the value of the Text property is evaluated as a VBScript expression and the result of the expression is rendered on the report.

For example, assuming that the report has a source recordset with fields named Amount and SalesTax:

theField.Text = "Amount * SalesTax"

theField.Calculated = False

Debug.Print Field.Value

Amount * SalesTax

theField.Text = "Amount * SalesTax"

theField.Calculated = True

Debug.Print Field.Value

257.34

Data Type

Boolean

See Also

Field Object


CanGrow Property (Field)

Returns or sets whether the Field height should be automatically increased to fit the Field's contents.

Syntax

field.CanGrow[ = {True | False} ]

Remarks

You can use the CanGrow and CanShrink properties to control the appearance of report fields and sections. When you set both properties to True, the field or section automatically adjusts so any amount of data can be printed. When a field grows or shrinks, the fields below it move down or up the page.

If you set a field's CanGrow property to True, the control automatically sets the CanGrow property of the containing section to True. (However, if you set a control's CanShrink property to True, the control doesn't set the section's CanShrink property to True.)

When you use the CanGrow and CanShrink properties, remember that:

1.

The property settings don't affect the horizontal spacing between fields; they affect only the vertical space the fields occupy.

2.

The height of a large field can prevent fields beside it from shrinking. For example, if several short controls are on the left side of a report's detail section and one tall control, such as an unbound object frame, is on the right side, the controls on the left won't shrink, even if they contain no data.

Data Type

Boolean

See Also

Field Object


CanShrink Property (Field)

Returns or sets whether the Field height should be automatically decreased to fit the Field's contents.

Syntax

field.CanShrink[ = {True | False} ]

Data Type

Boolean

See Also

CanGrow Property (Field)


CheckBox Property

Returns or sets whether the Field should be displayed as a checkbox.

Syntax

field.Checkbox[ = setting ]

Remarks

This property is useful when you wish to display boolean values graphically, rather than using text.

Valid settings for the Checkbox property are described below:

Constant | Value | Description
vsrNoCheckBox | 0 | No checkbox (display as text).
vsrCheckBox | 1 | Checkbox ().
vsrCrossBox | 2 | Crossbox ().
vsrRadioButton | 3 | Radio button ()

Data Type

CheckBoxSettings (Enumeration)

See Also

Field Object


Font Property (Field)

Returns or sets the Field's font.

Syntax

field.Font[ = Font ]

Remarks

If you set a field's Size property to a value that is too large to fit the field box (defined by the Height property), no text will appear in the field.

Data Type

Font

See Also

Field Object


ForcePageBreak Property (Field)

Returns or sets whether to insert page breaks before or after the field.

Syntax

field.ForcePageBreak[ = BreakSettings ]

Remarks

The settings for the ForcePageBreak property are described below:

Constant | Value | Description
vsrNone | 0 | No page breaks.
vsrBefore | 1 | A page break is inserted before the field.
vsrAfter | 2 | A page break is inserted after the field.
vsrBeforeAndAfter | 3 | Page breaks are inserted before and after the field.
vsrForcePage | 256 | In multi-column reports, use page breaks instead of column breaks (this value is a flag that may be combined with any of the other settings).

Data Type

BreakSettings (Enumeration)

See Also

Field Object


ForeColor Property

Returns or sets the Field's foreground color.

Syntax

field.ForeColor[ = colorref& ]

Remarks

Use the ForeColor property to specify the color for text in a field. You can use this property to make fields easy to read or to convey a special meaning. For example, you can change the color of the text in the UnitsInStock field when its value falls below the reorder level. For example:

Dim strOnPrint$

strOnPrint = "If UnitsInStock < ReorderLevel Then " & _

" UnitsInStock.ForeColor = vbRed " & _

"Else" & _

" UnitsInStock.ForeColor = vbBlack"

vsr.Sections(vsrDetail).OnPrint = strOnPrint

Data Type

Color

See Also

Field Object


Format Property

Returns or sets how the Field's contents should be formatted.

Syntax

field.Format[ = value As String ]

Remarks

You can use the Format property to customize the way numbers, dates, times, and text are displayed and printed. For example, if you've created a Price field, you can set its Format property to "Currency". If the field value is set to "4321.678", it would be rendered as $4,321.68.

The Format property affects only how data is displayed. It doesn't affect how data is stored.

You can use the Format property to format numbers (including currency and percentage values), dates, boolean values, and strings. The syntax is similar to the syntax used in Visual Basic's Format function. The table below shows some examples:

Value | Format | Result
#12:45# | Long Time | 12:45:00 PM
#12:45# | Short Time | 12:45
#12/12/97# | Long Date | Friday, December 12, 1997
#12/12/97# | Short Date | 12/12/1997
#12/12/97# | Medium Date | 12-Dec-97
#12/12/97# | q | 4 (quarter)
#12/12/97# | m | 12 (month)
#12/12/97# | d | 12 (day of the month)
#12/12/97# | w | 6 (day of the week)
#12/12/97# | yyyy | 1997 (year)
4321.678 | Currency | $4,321.68
4321.678 | $ | $4,321.68
4321.678 | General Number | 4321.678
0.678 | Percent | 67.80%
4321.678 | #,###.# | 4,321.7 (mask)
1 | Yes/No | True
"True" | Yes/No | True
True | Yes/No | True
0 | Yes/No | False
"North" | > | "NORTH"
"North" | < | "north"
"123456" | @@-@@-@@ | "12-34-56"

NOTE: The Format function is built into Visual Basic, but not into VBScript. To use the VBScript formatting functions (e.g., FormatNumber, FormatDateTime, DatePart, etc), add them directly to the field's Text property, and leave the Format property blank. For example:

theField.Text = "DatePart(""q"", HiredDate)"

theField.Calculated = True

Data Type

String

See Also

Field Object


Height Property (Field)

Returns or sets the Field size and position.

Syntax

field.Height[ = value As Double ]

Remarks

Every Field object has a rectangle, or "field box", where the field contents are rendered. The field box is defined by the Left, Top, Width, and Height properties. These properties are expressed in Twips, and the position is relative to the field's containing section.

The field's Height property should be set to a value larger than or equal to the height of the field's Font, or no text will appear in the field.

If the field's CanGrow or CanShrink properties are set to True, the control will automatically adjust the Height property to fit the field's contents. In this case, the control will also adjust the Top property of fields below the current field to preserve the vertical distance between fields.

Data Type

Double

See Also

Field Object


HideDuplicates Property

Returns or sets whether duplicate values in consecutive records should be suppressed.

Syntax

field.HideDuplicates[ = {True | False} ]

Remarks

You can use the HideDuplicates property to hide a field on a report when its value is the same as in the preceding record. For example, on a report listing suppliers and their products, each supplier's name can appear once for each group of products, rather than once for each product.

Data Type

Boolean

See Also

Field Object


Left Property

Returns or sets the Field size and position.

Syntax

field.Left[ = value As Double ]

Remarks

A field's location is the distance measured from its left or top border to the left or top edge of the section containing the field. Setting the Left or Top property to 0 places the control's edge at the very left or top of the section. The Left or Top properties are expressed in Twips.

Data Type

Double

See Also

Field Object


LineSlant Property

Returns or sets whether a line should be drawn across the field (as opposed to a box around the field).

Syntax

field.LineSlant[ = LineSlantSettings ]

Remarks

The settings for the LineSlant property are described below:

Constant | Value | Description
vsrLSNoLine | 0 | Regular field (not a line).
vsrLSNoSlant | 1 | Render field as a vertical line (if Height > Width) or as a horizontal line (if Width > Height).
vsrLSDown | 2 | Render field as a line between the left-top and right-bottom corners of the field box.
vsrLSUp | 3 | Render field as a line between the left-bottom and right-top corners of the field box.

The color, style, and thickness of the line are determined by the BorderColor, BorderStyle, and LineWidth properties.

Data Type

LineSlantSettings (Enumeration)

See Also

Field Object


LineSpacing Property

Returns or sets the line spacing between text lines in the Field.

Syntax

field.LineSpacing[ = value As Double ]

Remarks

The line spacing is measured in Twips.

Setting this property to zero causes the control to use the default line spacing, which corresponds to the height of the field's Font.

Data Type

Double

See Also

Field Object


LineWidth Property

Returns or sets the width of the Field's border or line.

Syntax

field.LineWidth[ = value As Double ]

Remarks

To draw a border around a field, set the following properties:

BorderColor

To define the border color.

BorderStyle

To define the border style (e.g. solid, dashed, etc).

LineWidth

To define the border width (in Twips).

To draw lines, set the LineSlant property.

NOTE: Due to a GDI limitation, dashed and dotted borders are only drawn when the LineWidth property is set to zero or one. Thicker borders are always solid.

Data Type

Double

See Also

Field Object


LinkTarget Property

Gets or sets an expression that evaluates to a URL to be visited when the field is clicked.

Syntax

string Field.LinkTarget

Remarks

If not empty, this should be an expression that evaluates to a URL. After the report is generated, clicking on the field will cause the report viewer to navigate to the URL. The report viewer can be a web browser (for HTML reports), Adobe Acrobat (for PDF reports), or other viewer applications based on the VSPrinter control.

The field will be displayed as usual, based on the contents of its Text and Picture properties.

The LinkTarget expression is always evaluated, regardless of the setting of the Calculated property (which only applies to the display text). This allows you to bind the LinkTarget to a field in the data source.

For example:

// set up a static link

Field f = c1r.Fields["companyInfoLink"];

f.Calculated = false;

f.Text = "click here for more info on our company";

f.LinkTarget = "http://myrealty.com";

// set up a databound link

Field f = c1r.Fields["propertyInfoLink"];

f.Calculated = false;

f.Text = "click here for more info on this property";

f.LinkTarget = "\"http://myrealty.com/moreinfo?id=\" & propertyID";

See Also

Field Object


MarginBottom Property (Field)

Returns or sets the margins between the Field's edges and the text it contains.

Syntax

field.MarginBottom[ = value As Double ]

Remarks

The MarginLeft, MarginTop, MarginRight, and MarginBottom properties determine the amount of space between each size of the field's rendering box and its contents. These measurements are expressed in Twips.

These properties are useful when you want to render fields with thick borders and don't want the borders too close to the field's text.

Data Type

Double


MarginLeft Property (Field)

Returns or sets the margins between the Field's edges and the text it contains.

Syntax

field.MarginLeft[ = value As Double ]

Remarks

The MarginLeft, MarginTop, MarginRight, and MarginBottom properties determine the amount of space between each size of the field's rendering box and its contents. These measurements are expressed in Twips.

These properties are useful when you want to render fields with thick borders and don't want the borders too close to the field's text.

Data Type

Double

See Also

Field Object


MarginRight Property (Field)

Returns or sets the margins between the Field's edges and the text it contains.

Syntax

field.MarginRight[ = value As Double ]

Remarks

The MarginLeft, MarginTop, MarginRight, and MarginBottom properties determine the amount of space between each size of the field's rendering box and its contents. These measurements are expressed in Twips.

These properties are useful when you want to render fields with thick borders and don't want the borders too close to the field's text.

Data Type

Double

See Also

Field Object


MarginTop Property (Field)

Returns or sets the margins between the Field's edges and the text it contains.

Syntax

field.MarginTop[ = value As Double ]

Remarks

The MarginLeft, MarginTop, MarginRight, and MarginBottom properties determine the amount of space between each size of the field's rendering box and its contents. These measurements are expressed in Twips.

These properties are useful when you want to render fields with thick borders and don't want the borders too close to the field's text.

Data Type

Double

See Also

Field Object


Name Property (Field)

Returns or sets the Field name.

Syntax

field.Name[ = value As String ]

Remarks

The field name can be used as an index into the control's Fields collection. For example:

vsr.Fields("FirstNameField").Height = 1440

It is also used to identify the field in a VBScript expression. For example:

vsr.Sections(vsrDetail).OnPrint = "FirstNameField.Height = 1440"

NOTE: You should adopt a naming scheme for fields that prevents duplicate names, or names that are identical to recordset field names. Although legal (the control will accept them), duplicate names will prevent you from accessing the field from VBScript code.

Data Type

String

See Also

Field Object


Picture Property (Field)

Returns or sets a picture to display on the field (file names are accepted).

Syntax

field.Picture[ = value As Variant ]

Remarks

Use the Picture property to create picture fields in your report. There are two types of picture fields:

Unbound Pictures:

These are static pictures such as a company logo. To create an unbound picture field, assign a Picture object or picture file name to the field's Picture property. For example:

theField.Picture = PictureBoxLogo.Picture

theField.Picture = "c:\mycorp\pictures\logo.gif"

Bound Pictures:

These are pictures loaded from the database. To create a bound picture field, assign the name of the recordset field that contains the picture to the field's Picture property. For example:

vsr.DataSource.ConnectionString = "dsn=NorthWind"

vsr.DataSource.RecordSource = "Employees"

theField.Picture = "Photo"

Use the PictureAlign property to determine how the picture is scaled and aligned to fit the field's render box.

Data Type

Variant

See Also

Field Object


PictureAlign Property (Field)

Returns or sets the picture alignment and scaling (see also the Picture property).

Syntax

field.PictureAlign[ = PictureAlignSettings ]

Remarks

The PictureAlign property determines how a picture is scaled and aligned to fit the field's render box.

The settings for the PictureAlign property are described below:

Constant | Value | Description
vsrPALeftTop | 0 | Align to the left and to the top, clipping if necessary.
vsrPACenterTop | 1 | Align to the center and to the top, clipping if necessary.
vsrPARightTop | 2 | Align to the right and to the top, clipping if necessary.
vsrPALeftBottom | 3 | Align to the left and to the bottom, clipping if necessary.
vsrPACenterBottom | 4 | Align to the center and to the bottom, clipping if necessary.
vsrPARightBottom | 5 | Align to the right and to the bottom, clipping if necessary.
vsrPALeftMiddle | 6 | Align to the left and to the middle, clipping if necessary.
vsrPACenterMiddle | 7 | Align to the center and to the middle, clipping if necessary.
vsrPARightMiddle | 8 | Align to the right and to the middle, clipping if necessary.
vsrPAClip | 9 | Align to the left and to the top, clipping if necessary.
vsrPAZoom | 10 | Scale the picture to use as much of the render box as possible, while preserving the picture's aspect ratio.
vsrPAStretch | 11 | Stretch the picture to fill the render box. This setting is useful for background images.
vsrPATile | 12 | Tile the picture to fill the render box. This setting is useful for background images.

Data Type

PictureAlignSettings (Enumeration)

See Also

Field Object


RenderHeight Property (Field)

Returns the height of the field after the section has been modified to accommodate CanGrow/CanShrink fields.

Syntax

field.RenderHeight[ = value As Double ]

Remarks

The Height property specifies the design height of a Field. When the CanGrow or CanShrink properties of the Field are set to true, however, this value is adjusted to account for the contents of the field. The RenderHeight property returns the adjusted height value, which can be used within event handlers to adjust the position of other fields within the section.

This value is calculated after the OnFormat script event fires (so any changes the script takes to the field are accounted for), but before the OnPrint event fires. Therefore, you can only use RenderHeight when handling the OnPrint event.

Data Type

Double

See Also

Field Object


RenderTop Property (Field)

Returns the top of the field after the section has been modified to accommodate CanGrow/CanShrink fields.

Syntax

field.RenderTop[ = value As Double ]

Remarks

The Top property specifies the top position of a Field within its Section. When the CanGrow or CanShrink properties of fields above a give field are set to true, the field is pushed" or "pulled" by the other fields and its position is adjusted to preserve the layout of the section. The RenderTop property returns the adjusted position, which can be used within event handlers to adjust the position of other fields within the section.

This value is calculated after the OnFormat script event fires (so any changes the script makes to the field are accounted for), but before the OnPrint event fires. Therefore, you can only use RenderHeight when handling the OnPrint event.

Data Type

Double

See Also

Field Object


RTF Property

Returns or sets whether the field should render string enclosed in curly brackets as RTF.

Syntax

field.RTF[ = {True | False} ]

Remarks

If you set this property to True, any fields containing text enclosed in curly brackets will be rendered as RTF. This allows you to add complex formatting within a field. For example, the following code creates a field with some bold and italic characters:

myField.RTF = True

myField.Text = "{This is \b Really \b0\i Really \i0 important}"

NOTE: Fields containing RTF text are not exported to HTML files. They are exported to RTF files.

See Also

Field Object


RunningSum Property

Returns or sets whether to show a running sum for the Field.

Syntax

field.RunningSum[ = RunningSumSettings ]

Remarks

You can use the RunningSum property to calculate record-by-record or group-by-group totals in a report. The RunningSum property specifies whether a calculated field on a report displays a running total and lets you set the range over which values are accumulated.

For example, you can group data by month and show the sum of each month's sales in the group footer section. You can show the running sum of accumulated sales over the entire report (sales for January in the January footer, sales for January plus February in the February footer, and so on) by adding a text box to the footer that shows the sum of sales and setting its RunningSum property to vsrSumOverAll.

The settings for the RunningSum property are described below:

Constant | Value | Description
vsrNoRunningSum | 0 | Do not treat field as a running sum.
vsrSumOverGroup | 1 | Calculate running sum over each group.
vsrSumOverAll | 2 | Calculate running sum over each the whole report.

Data Type

RunningSumSettings (Enumeration)

See Also

Field Object


Section Property

Returns or sets the Section to which the Field belongs.

Syntax

field.Section[ = SectionTypeSettings ]

Remarks

You can read this property to determine which section the field belongs to, or set the property to move the field to a new section.

For example, the code below moves all fields on the page header section to the page footer section:

Dim i%, iSec%

For i = 0 to vsr.Fields.Count - 1

iSec = vsr.Fields(i).Section

If iSec = vsrPageHeader Then

vsr.Fields(i).Section = vsrPageFooter

End If

Next

Data Type

SectionTypeSettings (Enumeration)

See Also

Field Object


Subreport Property

Returns or sets a reference to another report to be rendered within the field (a Subreport).

Syntax

field.Subreport[ = IVSReport ]

Remarks

A subreport is a report that is inserted in another report. Subreports are useful when you want to combine several reports into one. For example, you may have a main report that integrates several subreports into a single main report. Or you can use the main report to show detailed information and use subreports to show summary data at the beginning of each group.

For some real-world examples, check the "Sales By Category" and "Sales By Year" reports in the NWIND.XML sample that ships with the control.

To define a field as a subreport, you should start by loading the subreport, then assign the subreport control to the field's Subreport property. For example:

Dim sSub = "Sales By Category Subreport"

vsrSub.Load "NWIND.XML", sSub

Set vsr.Fields(sSub).Subreport = vsrSub

Next, you should link the subreport to the main report using the subreport field's Text property (this is analogous to setting the LinkChildFields/LinkMasterFields properties in a Microsoft Access subreport). The Text property in a subreport field is used as a filter. It specifies which records in the source recordset should be used to render the subreport based on the current record for the main report. Continuing the example above, this would be done as follows:

vsr.Fields(sSub).Calculated = True

vsr.Fields(sSub).Text = "CategoryName = '" & [CategoryName] & "'"

When the main report is being rendered and reaches the subreport field, the above expression is evaluated and the result is a filter condition such as

CategoryName = 'Beverages'

This filter condition is applied to the subreport's source recordset, and when the subreport is rendered only the relevant records are listed.

Subreport fields usually have the CanGrow property set to True, so the subreport field can expand to include all its records.

Data Type

IVSReport

See Also

Field Object


Tag Property (Field)

Returns or sets extra data needed by the calling program.

Syntax

field.Tag[ = value As Variant ]

Data Type

Variant

See Also

Field Object


Text Property

Returns or sets the Field's literal text or expression (depending on the Calculated property).

Syntax

field.Text[ = value As String ]

Remarks

The Text property contains the text that will be rendered on the report. This value may be rendered literally (without any translation) or it may be evaluated as a VBScript expression, depending on the setting of the Calculated property.

For example, assuming that the report has a source recordset with fields named Amount and SalesTax:

theField.Text = "Amount * SalesTax"

theField.Calculated = False

Debug.Print Field.Value

Amount * SalesTax

theField.Text = "Amount * SalesTax"

theField.Calculated = True

Debug.Print Field.Value

257.34

Data Type

String

See Also

Field Object

Calculated Property


Top Property

Returns or sets the Field size and position.

Syntax

field.Top[ = value As Double ]

Remarks

A field's location is the distance measured from its left or top border to the left or top edge of the section containing the field. Setting the Left or Top property to 0 places the control's edge at the very left or top of the section. The Left or Top properties are expressed in Twips.

Data Type

Double

See Also

Field Object


Value Property

Returns or sets the Field's calculated value.

Syntax

field.Value[ = value As Variant ]

Remarks

When a field's Calculated property is set to True, the control evaluates the expression stored in the Text property and stores the result in the Value property, which gets rendered into the report.

This is the field's default property, so when you use a field name in an VBScript expression, you are actually referring to the field's Value property. For example :

Dim sScript$

sScript = "If MyField > 100 Then " & "MyField.ForeColor = vbRed"

is equivalent to:

Dim sScript$

sScript = "If MyField.Value > 100 Then " & "MyField.ForeColor = vbRed"

Data Type

Variant

See Also

Field Object


Visible Property (Field)

Returns or sets whether the Field will be rendered.

Syntax

field.Visible[ = {True | False} ]

Data Type

Boolean

See Also

Field Object


Width Property (Field)

Returns or sets the Field size and position.

Syntax

field.Width[ = value As Double ]

Remarks

Every Field object has a rectangle, or "field box", where the field contents are rendered. The field box is defined by the Left, Top, Width, and Height properties. These properties are expressed in Twips, and the position is relative to the field's containing section.

Data Type

Double

See Also

Field Object


WordWrap Property

Returns or sets whether the Field's contents should be allowed to wrap within the Field rectangle.

Syntax

field.WordWrap[ = {True | False} ]

Data Type

Boolean

See Also

Field Object


ZOrder Property

Gets or sets the ZOrder for the field.

Syntax

Property ZOrder As Long

Data Type

Long

See Also

Field Object


Field Methods


SetZOrder Method

Brings a field to the top or sends it to the bottom of the ZOrder.

Syntax

field.SetZOrder Top As Boolean

Remarks

The parameters for the SetZOrder method are described below:

Top As Boolean

This parameter determines whether a field is sent to the top or bottom of the ZOrder.

See Also

Field Object


Group Object

All of the properties and methods for the Group object are listed in the following tables. Properties and methods that apply only to this control, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*GroupBy | Returns or sets the expression used to break records into groups.
*KeepTogether | Returns or sets whether the group should be kept together on a page.
*Name | Returns or sets the Group name.
*SectionFooter | Returns the Section used as this group's footer.
*SectionHeader | Returns the Section used as this group's header.
*Sort | Returns or sets the expression used to sort this group.
*Tag | Returns or sets extra data needed by the calling program.

Methods

*Move

Moves a group to a new position in the Groups collection, optionally adjusting its Sections and Fields.


Group Properties

GroupBy Property

KeepTogether Property (Group)

Name Property (Group)

SectionFooter Property

SectionHeader Property

Sort Property

Tag Property (Group)


GroupBy Property

Returns or sets the expression used to break records into groups.

Syntax

group.GroupBy[ = value As String ]

Remarks

The GroupBy property contains a VBScript expression that is evaluated for every record in the source recordset. A new group is started whenever the value of this expression changes. For example,

vsr.Groups(0).GroupBy = "CategoryName"

vsr.Groups(0).Sort = vsrAscending

vsr.Groups(1).GroupBy = "ProductName"

vsr.Groups(1).Sort = vsrAscending

The code above would group records by category name, then by product name. Note that the GroupBy property inserts group breaks. To sort the records, you should also use the Sort property.

The expression used for grouping is not limited to field names, it can contain any VBScript functions. For example:

vsr.Groups(0).GroupBy = "Left([ProductName],1)"

vsr.Groups(1).GroupBy = "DatePart([ShippedDate],'q')"

The code above would group records by the first letter of the product name, then by the quarter of the shipped date.

Data Type

String

See Also

Group Object


KeepTogether Property (Group)

Returns or sets whether the group should be kept together on a page.

Syntax

group.KeepTogether[ = KeepTogetherSettings ]

Remarks

The settings for the KeepTogether property are described below:

Constant | Value | Description
vsrKeepNothing | 0 | Do not try to keep the group together.
vsrKeepWholeGroup | 1 | Keep the group header, detail, and footer together on a page.
vsrKeepFirstDetail | 2 | Keep the group header and first detail section together on a page.

Data Type

KeepTogetherSettings (Enumeration)

See Also

Group Object


Name Property (Group)

Returns or sets the Group name.

Syntax

group.Name[ = value As String ]

Remarks

The group name can be used as an index into the control's Groups collection. For example:

vsr.Groups("Initial").GroupBy = "Left([ProductName],1)"

Data Type

String

See Also

Group Object


SectionFooter Property

Returns the Section used as this group's footer.

Syntax

val = group.SectionFooter

Data Type

ISection

See Also

Group Object


SectionHeader Property

Returns the Section used as this group's header.

Syntax

val = group.SectionHeader

Data Type

ISection

See Also

Group Object


Sort Property

Returns or sets the expression used to sort this group.

Syntax

group.Sort[ = GroupSortSettings ]

Remarks

The settings for the Sort property are described below:

Constant | Value | Description
vsrNoSort | 0 | Do not sort records for this group.
vsrAscending | 1 | Sort records in ascending order.
vsrDescending | 2 | Sort records in descending order.

Data Type

GroupSortSettings (Enumeration)

See Also

Group Object


Tag Property (Group)

Returns or sets extra data needed by the calling program.

Syntax

group.Tag[ = value As Variant ]

Data Type

Variant

See Also

Group Object


Group Methods


Move Method

Moves a group to a new position in the Groups collection, optionally adjusting its Sections and Fields.

Syntax

group.Move NewPosition As Long, AdjustSections As Boolean

Remarks

This method is useful in designer-type applications, when you want to allow users to change the grouping order.

The parameters for the Move method are described below:

NewPosition As Long

This parameter contains the new position for the group (index into the Groups collection).

AdjustSections As Boolean

This parameter determines whether only the group should be moved or whether its header and footer sections, along with all the fields in those sections, should also be moved.

See Also

Group Object


SectionCollection Object

All of the properties for the SectionCollection object are listed in the following table. Properties, events, and methods that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*Count | Returns the number of Section objects in the collection.
*Item | Returns a Section object.


SectionCollection Properties


Count Property (SectionCollection)

Returns the number of Section objects in the collection.

Syntax

sections.Count[ = value As Long ]

Remarks

The Sections property does not have Add or Remove methods. That is because the number of sections is determined by then number of groups. To add or remove sections from the report, you need to add or remove groups.

Data Type

Long

See Also

SectionCollection Object


Item Property (SectionCollection)

Returns a Section object.

Syntax

sections.Item(Index As Variant)[ = ISection ]

Remarks

The Index parameter may be an integer between zero and Sections.Count - 1, or it may be a string containing a section name.

Data Type

ISection

See Also

SectionCollection Object


FieldCollection Object

All of the properties and methods for the FieldCollection object are listed in the following tables. Properties and methods that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*Count | Returns the number of fields in a field collection.
*Item | Returns a field from a field collection.

Methods

*Add | Adds a Field to a Fields collection.
*Remove | Removes a Field from a Fields collection.


FieldCollection Properties


Count Property (FieldCollection)

Returns the number of fields in a field collection.

Syntax

fields.Count[ = value As Long ]

Data Type

Long

See Also

FieldCollection Object


Item Property (FieldCollection)

Returns a field from a field collection.

Syntax

fields.Item(Index As Variant)[ = IField ]

Remarks

The Index parameter may be an integer between zero and Fields.Count - 1, or it may be a string containing a field name.

Data Type

IField

See Also

FieldCollection Object


FieldCollection Methods


Add Method (FieldCollection)

Adds a Field to a Fields collection.

Syntax

fields.Add Name As String, Text As String, Left As Double, Top As Double, Width As Double, Height As Double

Remarks

The parameters for the Add method are described below:

Name As String

This parameter contains the name of the new field. You should try to use a consistent naming scheme and avoid using duplicate names for report fields and database fields. Using repeated names may cause your VBScript expressions to yield unexpected results.

Text As String

This parameter contains the value for the new field's Text property. This value may be treated as a literal or as a VBScript expression, depending on the setting of the field's Calculated property. By default, Calculated is set to False and the text is rendered as-is.

Left, Top, Width, Height As Double

These parameters define the position of the field with respect to its containing section.

NOTE: If you add a field to a section's Fields collection, the new field is automatically assigned to that section. If you add a field to the control's Fields collection, the new field is not assigned to any sections. In this case, you must set the field's Section property or it will not be rendered in the report.

For example:

vsr.Fields.Add "NewField", "Hello World", 100, 100, 2000, 300

vsr.Fields("NewField").Section = vsrDetail

The Add method returns a reference to the newly added field, so the above code could also be written as:

Dim theField As Field

Set theField = vsr.Fields.Add("NewField", "Hello World", 100, 100, 2000, 300)

theField.Section = vsrDetail

See Also

FieldCollection Object


Remove Method (FieldCollection)

Removes a Field from a Fields collection.

Syntax

fields.Remove Index As Variant

Remarks

The Index parameter may be an integer between zero and Fields.Count - 1, or it may be a string containing a field name.

See Also

FieldCollection Object


GroupCollection Object

All of the properties and methods for the GroupCollection object are listed in the following tables. Properties and methods that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*Count | Returns the number of Group objects in the collection.
*Item | Returns a Group object.

Methods

*Add | Adds a Group to the Groups collection, and its header/footer Sections to the Sections collection.
*Remove | Removes a Group from the Groups collection, and its header/footer Sections from the Sections collection.


GroupCollection Properties


Count Property (GroupCollection)

Returns the number of Group objects in the collection.

Syntax

groups.Count[ = value As Long ]

Data Type

Long

See Also

GroupCollection Object


Item Property (GroupCollection)

Returns a Group object.

Syntax

group.Item(Index As Variant)[ = IGroup ]

Remarks

The Index parameter may be an integer between zero and Groups.Count - 1, or it may be a string containing a group name.

Data Type

IGroup

See Also

GroupCollection Object


GroupCollection Methods


Add Method (GroupCollection)

Adds a Group to the Groups collection, and its header/footer Sections to the Sections collection.

Syntax

[form!]Groups.Add Name As String, GroupBy As String, Sort As GroupSortSettings

Remarks

The parameters for the Add method are described below:

Name As String

This parameter contains the name of the new group.

GroupBy As String

This parameter contains the value of the GroupBy property for the new group.

Sort As GroupSortSettings

This parameter contains the value of the Sort property for the new group.

NOTE: When you add a group to a report, the control automatically adds two new sections, the group header and group footer sections for the new group.

For example:

Debug.Print vsr.Sections.Count

7

vsr.Groups.Add "NewGroup", "Left([ProductName],1)", vsrAscending

Debug.Print vsr.Sections.Count

9

See Also

GroupCollection Object


Remove Method (GroupCollection)

Removes a Group from the Groups collection, and its header/footer Sections from the Sections collection.

Syntax

groups.Remove Index As Variant

Remarks

The Index parameter may be an integer between zero and Groups.Count - 1, or it may be a string containing a group name.

See Also

GroupCollection Object


DataSource Object

All of the properties for the DataSource object are listed in the following tables. Properties, events, and methods that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*ConnectionString | Sets or returns a string that specifies the data source for the report.
*FieldInfo | Returns a variant array containing all field names, types, and size for the current report data source.
*Filter | Sets or returns an expression used to filter the source recordset.
*MaxRecords | Sets or returns the maximum number of records to be retrieved from the database.
*Recordset | Sets or returns a Recordset object used as the report data source.
*RecordSource | Sets or returns a string that specifies the source recordset for the report.

Methods

*GetRecordSource

Processes the PARAMETERS clause in the RecordSource string and returns the result.


DataSource Properties

ConnectionString Property

FieldInfo Property

Filter Property

MaxRecords Property

Recordset Property

RecordSource Property


ConnectionString Property

Sets or returns a string that specifies the data source for the report.

Syntax

dataSource.ConnectionString[ = value As String ]

Remarks

Use the ConnectionString property to specify a data source by passing a detailed connection string containing a series of argument = value statements separated by semicolons.

ADO supports five arguments for the ConnectionString property; any other arguments pass directly to the provider without any processing by ADO. The arguments ADO supports are as follows.

Argument | Description
Provider | Specifies the name of a provider to use for the connection.
File Name | Specifies the name of a provider-specific file.
Remote Provider | Specifies the name of a provider to use when opening a client-side connection. (Remote Data Service only.)
Remote Server | Specifies the path name of the server to use when opening a client-side connection. (Remote Data Service only.)
URL | Specifies the connection string as an absolute URL identifying a resource, such as a file or directory.

This property is identical to the ConnectionString property in the Microsoft ADO Data Control. The Reports Designer uses a "Data Link" dialog to let users create and edit the ConnectionString. The following are typical connection strings:

' ODBC connection

' NorthWind is the name of an ODBC data source

strConn = "dsn=NorthWind"

' Access file

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _

"Data Source=D:\MyData\NWIND.MDB;"

' SQL Server

strConn = "Provider=SQLOLEDB.1;" & _

"Integrated Security=SSPI;" & _

"Persist Security Info=False;" & _

"User ID=Bill;" & _

"Initial Catalog=Northwind;" & _

"Data Source=BILLSERVER"

NOTE: The VBScript expressions in calculated fields and event handler scripts have access to the VSReports7 object model. For security reasons, the ConnectionString property is protected and cannot be accessed through VBScript. For example, the expression "Report.DataSource.ConnectionString" returns an empty string. The reason for this is that an application may set this property using code, and assign it a connection string that contains a password. Without this protection, a malicious user could change the report definition and display the connection string on the report (including the password).

Data Type

String

See Also

DataSource Object


FieldInfo Property

Returns a variant array containing all field names, types, and size for the current report data source.

Syntax

dataSource.FieldInfo[ = value As Variant ]

Remarks

This property is useful in designer-type applications that need to retrieve information about the fields available in the source recordset.

The difference between retrieving this information directly from the recordset or from the FieldInfo property is that the source recordset is open only while the report is rendering, while the FieldInfo is available at all times.

The array returned contains one row for each field. Each row contains three columns, with the field name, ADO data type, and size (in bytes).

The example below shows a simple use for the FieldInfo property:

Dim v, i%

v = vsr.DataSource.FieldInfo

Debug.Print "** Fields in '"; vsr.ReportName; "'"

Debug.Print "Field#", "Name", "Type", "Size"

For i = 0 To UBound(v, 1)

Debug.Print "Field "; i,

Debug.Print v(i, 0), v(i, 1), v(i, 2)

Next

** Fields in 'Alphabetical List of Products'

Field# Name Type Size

Field 0 ProductID 3 4

Field 1 ProductName 202 40

Field 2 SupplierID 3 4

Field 3 CategoryID 3 4

Field 4 QuantityPerUnit 202 20

Field 5 UnitPrice 6 8

Field 6 UnitsInStock 2 2

Field 7 UnitsOnOrder 2 2

Field 8 ReorderLevel 2 2

Field 9 Discontinued 11 2

Field 10 CategoryName 202 15

The Report Designer uses this property extensively, to build field-pick lists and to automatically size report fields created by the New Report Wizard.

To use the FieldInfo property in Visual C++ programs, you need to use the system APIs designed to manipulate SAFEARRAY structures. The example below shows how that works:

// import interfaces for VSReports7 control

#import "VSRpt8.ocx" no_namespace

// use FieldInfo to get field information for a given report

BOOL ListFields(IVSReportPtr spReport)

{

USES_CONVERSION;

// get data source

if (spReport == NULL) return FALSE;

IDataSourcePtr spDS = spReport->DataSource;

if (spDS == NULL) return FALSE;

// get FieldInfo array

CComVariant v = spDS->FieldInfo;

if (V_VT(&v) != (VT_ARRAY | VT_VARIANT)) return FALSE;

ATLASSERT(v.parray->cDims == 2);

// scan FieldInfo array and display the information

long pIndex[2];

for (long i = 0;; i++) {

// reading array row I

pIndex[0] = i;

// get field name

pIndex[1] = 0;

CComVariant vName;

CComBSTR strName;

if (FAILED(SafeArrayGetElement(v.parray, pIndex, &vName))) break;

if (vName.vt == VT_BSTR) strName = V_BSTR(&vName);

// get field type

pIndex[1] = 1;

CComVariant vType;

if (FAILED(SafeArrayGetElement(v.parray, pIndex, &vType))) break;

// get field size

pIndex[1] = 2;

CComVariant vSize;

if (FAILED(SafeArrayGetElement(v.parray, pIndex, &vSize))) break;

// show the information

ATLTRACE("Field %d %s %d %d\n",

i, W2T(strName), V_I4(&vType), V_I4(&vSize));

}

// done

return TRUE;

}

The #import statement is very important. It loads all interfaces and constants defined by the control. The CComVariant, CComBSTR, USES_CONVERSION, and ATLTRACE symbols are defined by ATL. Other class libraries have similar constructs and classes (for example, MFC had COleVariant, CString, and TRACE).

Data Type

Variant

See Also

DataSource Object


Filter Property

Sets or returns an expression used to filter the source recordset.

Syntax

dataSource.Filter[ = value As String ]

Remarks

Use the Filter property to restrict the records that you want to include in a report without modifying the RecordSource property.

For example, you may have created a Sales Report and would like to generate a report for a specific year. In this case, you could use the Filter property as shown below:

vsr.Load strReportFile, "Sales Report"

vsr.DataSource.Filter = "ShippedDate >= #1/1/1995# " & "AND " & _

"ShippedDate <= #1/1/1996#"

vsr.Render vp

The Filter string is made up of clauses in the form FieldName-Operator-Value (for example, "LastName = 'Smith'"). You can create compound clauses by concatenating individual clauses with AND (for example, "LastName = 'Smith' AND FirstName = 'John'") or OR (for example, "LastName = 'Smith' OR LastName = 'Jones'"). Use the following guidelines for criteria strings:

1.

FieldName must be a valid field name from the Recordset. If the field name contains spaces, you must enclose the name in square brackets.

2.

Operator must be one of the following: <, >, <=, >=, <>, =, or LIKE.

3.

Value is the value with which you will compare the field values (for example, 'Smith', #8/24/95#, 12.345, or $50.00). Use single quotes with strings and pound signs (#) with dates. For numbers, you can use decimal points, dollar signs, and scientific notation. If Operator is LIKE, Value can use wildcards. Only the asterisk (*) and percent sign (%) wild cards are allowed, and they must be the last character in the string. Value cannot be null.

NOTE: To include single quotation marks (') in the filter Value, use two single quotation marks to represent one. For example, to filter on O'Malley, the criteria string should be "col1 = 'O''Malley'". To include single quotation marks at both the beginning and the end of the filter value, enclose the string with pound signs (#). For example, to filter on '1', the criteria string should be "col1 = #'1'#".

If you want to allow users to select parameters for the report, consider using Parameter Queries instead of filters. A parameter query is a query that when run displays its own dialog box prompting the user for criteria for retrieving records. For details, see the RecordSource property.

Data Type

String

See Also

DataSource Object


MaxRecords Property

Sets or returns the maximum number of records to be retrieved from the database.

Syntax

dataSource.MaxRecords[ = value As Long ]

Remarks

This property is useful if you want to limit the size of a report. For example, you may write a report designer with a preview window that shows only the first 500 records from the database.

Setting this property to zero causes the control to retrieve all records.

You can also limit the size of reports by setting the MaxPages property.

Data Type

Long

See Also

DataSource Object


Recordset Property

Sets or returns a Recordset object used as the report data source.

Syntax

dataSource.Recordset[ = object ]

Remarks

Normally, VSReport8 creates an ADO recordset based on the value of the ConnectionString and RecordSource properties. In this case, the recordset is handled internally by the control and you don't need to use the Recordset property in any way.

In some situations, however, you may prefer to provide a recordset directly to the control. You can do this by assigning the custom recordset to the Recordset property. In this case, VSReport8 uses the recordset you provided instead of creating one.

You can assign three types of recordset to the Recordset property: ADO, DAO, or custom.

ADO and DAO recordsets are standard objects that contain data extracted from traditional databases.

Custom recordsets are COM objects that you can implement to provide access to data that does not necessarily come from a traditional database. For example, your data may be stored in memory or it may be calculated dynamically.

In order to communicate with VSReport8, custom recordset objects must implement the IVSReportRecordset interface. For details on how to create a custom data source object, see the Custom Data Sources section of the documentation.

Data Type

Object

See Also

DataSource Object


RecordSource Property

Sets or returns a string that specifies the source recordset for the report.

Syntax

dataSource.RecordSource[ = value As String ]

Remarks

The string can be either a table name, a query (or stored procedure), or an SQL statement.

Table Names

Using table names and queries is straightforward. For example, the NorthWind database that ships with Microsoft Visual Studio contains the following tables: Categories, Orders, Shippers, Customers, Employees, Order Details, Products, and Suppliers. When the ConnectionString property is set to the NorthWind database, setting RecordSource to any of these values will retrieve the corresponding table. For example:

vsr.DataSource.ConnectionString = "DSN=NorthWind"

vsr.DataSource.RecordSource = "Employees"

SQL Statements

Using SQL statements is just as simple, but creating the SQL statement can be complicated. For this task, you will normally use a query-building tool that generates the SQL statement for you. Among others, you can use Microsoft Access or ComponentOne's TrueDBQuery. For example:

Dim strSQL$

strSQL = "SELECT DISTINCTROW * FROM Categories " & _

"INNER JOIN Products " & "

"ON Categories.CategoryID = Products.CategoryID " & _

"WHERE ((Products.Discontinued)=No);"

vsr.DataSource.ConnectionString = "DSN=NorthWind"

vsr.DataSource.RecordSource = strSQL

Parameter Queries

When using SQL statements, you have the option of creating Parameter Queries, which prompt the user for criteria used to select the records. The syntax used to create parameter queries is based on SQL, and is the same as that used by Microsoft Access.

The easiest way to create a parameter query is to start with a plain SQL statement with one or more items in the WHERE clause, then manually replace the fixed values in the clause with parameters. For example, starting with the plain SQL statement:

strSQL = "SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between #1/1/1994# And #1/1/2001#));"

The next step is to identify the parts of the SQL statement that will be turned into parameters. In this example, the parameters are the dates in the WHERE clause, shown above in boldface. Let's call these parameters Beginning Date and Ending Date. Since these names contain spaces, they need to be enclosed in square brackets:

strSQL = "SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between [Beginning Date] And [Ending Date]));"

Finally, the parameters must be identified in the beginning of the SQL statement with a PARAMETERS clause, that includes the parameter name, type, and default value:

strSQL = "PARAMETERS [Beginning Date] DateTime 1/1/1994, " & _

"[Ending Date] DateTime 1/1/2001;" & _

"SELECT DISTINCTROW * FROM Employees " & _

"INNER JOIN (Orders INNER JOIN [Order Subtotals] " & _

"ON Orders.OrderID = [Order Subtotals].OrderID) " & _

"ON Employees.EmployeeID = Orders.EmployeeID " & _

"WHERE (((Orders.ShippedDate) " & _

"Between [Beginning Date] And [Ending Date]));"

When this statement is executed, the control shows a dialog box prompting the user for Beginning Date and Ending Date values. The values supplied by the user are plugged into the SQL statement and the report is generated only for the period selected by the user.

The syntax for the PARAMETERS clause consists of a comma-separated list of items, ending with a semi-colon. Each item describes one parameter, and includes the following information:

1.

Parameter name.

If the name contains spaces, it must be enclosed in square brackets (e.g. [Beginning Date]). The parameter name appears in the dialog used to collect the information from the user, and it also appears in the WHERE clause of the SQL statement, where it is replaced with the value entered by the user.

2.

Parameter type.

The following types are recognized by the control:

Type Name | ADO Type
Date | adDate
DateTime | adDate
Bit | adInteger
Byte | adInteger
Short | adInteger
Long | adInteger
Currency | adCurrency
Single | adSingle
Double | adDouble
Text | adBSTR
String | adBSTR
Boolean | adBoolean
Bool | adBoolean
YesNo | adBoolean

3.

Default value.

This is the value initially displayed in the dialog box.

Note that you could also write code in Visual Basic or in C++ to create a dialog box, get the information from the user, and fix the SQL statement or set the Filter property as needed. The advantage of using Parameter Queries is that it places the parameter logic in the report itself, and is independent of the viewer application.

Data Type

String

See Also

DataSource Object


DataSource Methods


GetRecordSource Method

Processes the PARAMETERS clause in the RecordSource string and returns the result.

Syntax

strVal = dataSource.GetRecordSource(Prompt As Boolean)

Remarks

This property is related to the RecordSource property. The RecordSource property sets or returns a string that specifies the source recordset for the report, and it may contain a PARAMETERS clause that causes VSReport to prompt the user for information. If you wanted to use the value of the RecordSource property to open a recordset directly from your program, you would have to parse the PARAMETERS clause yourself.

The GetRecordSource method handles the PARAMETERS clause and returns a string (SQL statement or table name) that can be used to open a recordset directly.

If the Prompt parameter is set to True, user will be prompted for the parameters before the method returns. If Prompt is set to False, the default values will be used. For example, the code below uses the GetRecordSource method to build a DAO recordset for a report:

' get recordsource string

Dim strRS As String

strRS = vsr.DataSource.GetRecordSource(True)

' open DAO recordset

Dim db As DAO.Database

Dim rs As DAO.Recordset

Set db = OpenDatabase("c:\Program Files\VS\VB98\NWind.mdb")

Set rs = db.OpenRecordset(strRS, dbOpenDynaset)

' assign DAO recordset to vsr control

vsr.DataSource.Recordset = rs

See Also

DataSource Object


Layout Object

All of the properties for the Layout object are listed in the following tables. Properties that apply only to this object, or that require special consideration when used with it, are marked with an asterisk (*). These are documented in later sections. For documentation on the remaining properties, see the Visual Basic documentation.

Properties

*ColumnLayout | Returns or sets the layout for the columns (down or across).
*Columns | Returns or sets the number of detail columns.
*MarginBottom | Sets or returns the margins around each page.
*MarginLeft | Sets or returns the margins around each page.
*MarginRight | Sets or returns the margins around each page.
*MarginTop | Sets or returns the margins around each page.
*Orientation | Returns or sets the page orientation.
*PageFooter | Returns or sets where the Page Footer section is displayed.
*PageHeader | Returns or sets where the Page Header section is displayed.
*PaperSize | Returns or sets the paper size for the report.
*Picture | Returns or sets a background picture for the report body.
*PictureAlign | Returns or sets how the background picture is aligned.
*PictureShow | Returns or sets where the background picture is displayed.
*Width | Sets or returns the width of the report's detail section, in twips.


Layout Properties

ColumnLayout Property

Columns Property

MarginBottom Property (Layout)

MarginLeft Property (Layout)

MarginRight Property (Layout)

MarginTop Property (Layout)

Orientation Property

PageFooter Property

PageHeader Property

PaperSize Property

Picture Property (Layout)

PictureAlign Property (Layout)

PictureShow Property

Width Property (Layout)


ColumnLayout Property

Returns or sets the layout for the columns (down or across).

Syntax

layout.ColumnLayout[ = ColumnLayoutSettings ]

Remarks

This property is used in conjunction with the Columns property to create multi-column reports.

The settings for the ColumnLayout property are described below:

Constant | Value | Description
vsrCLDown | 0 | Columns are laid out down the page, then across.
vsrCLAcross | 1 | Columns are laid out across the page, then down.

Data Type

ColumnLayoutSettings (Enumeration)

See Also

Layout Object

Columns Property


Columns Property

Returns or sets the number of detail columns.

Syntax

layout.Columns[ = value As Long ]

Remarks

Use this property to create multi-column reports.

In multi-column reports, header and footer sections span the full width of the report. Only the detail section is rendered in multiple columns. Use the Width property to specify the width of each column, and the ColumnLayout property to specify whether columns should be laid out across the page or down the page.

Multi-column reports are useful for printing reports on mailing labels and other types of multi-column pre-printed forms. They are also useful for creating compact reports where detail information is laid out across the page.

Data Type

Long

See Also

Layout Object


MarginBottom Property (Layout)

Sets or returns the margins around each page.

Syntax

layout.MarginBottom[ = value As Double ]

Remarks

The margins are measured in Twips, from the edges of the paper. You can select the paper size and orientation using the PaperSize and Orientation properties.

Data Type

Double

See Also

Layout Object


MarginLeft Property (Layout)

Sets or returns the margins around each page.

Syntax

layout.MarginLeft[ = value As Double ]

Remarks

The margins are measured in Twips, from the edges of the paper. You can select the paper size and orientation using the PaperSize and Orientation properties.

Data Type

Double

See Also

Layout Object


MarginRight Property (Layout)

Sets or returns the margins around each page.

Syntax

layout.MarginRight[ = value As Double ]

Remarks

The margins are measured in Twips, from the edges of the paper. You can select the paper size and orientation using the PaperSize and Orientation properties.

Data Type

Double

See Also

Layout Object


MarginTop Property (Layout)

Sets or returns the margins around each page.

Syntax

layout.MarginTop[ = value As Double ]

Remarks

The margins are measured in Twips, from the edges of the paper. You can select the paper size and orientation using the PaperSize and Orientation properties.

Data Type

Double

See Also

Layout Object


Orientation Property

Returns or sets the page orientation.

Syntax

layout.Orientation[ = ReportOrientationSettings ]

Remarks

The settings for the Orientation property are described below:

Constant | Value | Description
vsrAutoOrient | 0 | Set the orientation automatically, based on the current PaperSize and report Width.
vsrPortrait | 1 | Use Portrait orientation (tall).
vsrLandscape | 2 | Use Landscape orientation (wide).

Data Type

ReportOrientationSettings (Enumeration)

See Also

Layout Object


PageFooter Property

Returns or sets where the Page Footer section is displayed.

Syntax

layout.PageFooter[ = PageHdrFtrSettings ]

Remarks

You can use the PageHeader and PageFooter properties to specify whether a report's page header or page footer is printed on the same page as a report header or report footer. For example, you might not want to print a page header containing the page number on the first page of a report if the report header is a cover sheet.

The settings for the PageFooter property are described below:

Constant | Value | Description
vsrAllPages | 0 | The page footer is printed on all pages of a report.
vsrNotWithReportHdr | 1 | The page footer isn't printed on the same page as the report header.
vsrNotWithReportFtr | 2 | The page footer isn't printed on the same page as the report footer.
vsrNotWithReportHdrFtr | 3 | The page footer isn't printed on a page that has either a report header or a report footer.

Data Type

PageHdrFtrSettings (Enumeration)

See Also

Layout Object


PageHeader Property

Returns or sets where the Page Header section is displayed.

Syntax

layout.PageHeader[ = PageHdrFtrSettings ]

Remarks

You can use the PageHeader and PageFooter properties to specify whether a report's page header or page footer is printed on the same page as a report header or report footer. For example, you might not want to print a page header containing the page number on the first page of a report if the report header is a cover sheet.

The settings for the PageHeader property are described below:

Constant | Value | Description
vsrAllPages | 0 | The page header is printed on all pages of a report.
vsrNotWithReportHdr | 1 | The page header isn't printed on the same page as the report header.
vsrNotWithReportFtr | 2 | The page header isn't printed on the same page as the report footer.
vsrNotWithReportHdrFtr | 3 | The page header isn't printed on a page that has either a report header or a report footer.

Data Type

PageHdrFtrSettings (Enumeration)

See Also

Layout Object


PaperSize Property

Returns or sets the paper size for the report.

Syntax

layout.PaperSize[ = ReportPaperSizeSettings ]

Remarks

Valid settings for the PaperSize property are:

Value | Constant | Value | Constant
0 | vsrPSDefault | 36 | vsrPSEnvItaly
1 | vsrPSLetter | 37 | vsrPSEnvMonarch
2 | vsrPSLetterSmall | 38 | vsrPSEnvPersonal
3 | vsrPSTabloid | 39 | vsrPSFanfoldUS
4 | vsrPSLedger | 40 | vsrPSFanfoldStdGerman
5 | vsrPSLegal | 41 | vsrPSFanfoldLglGerman
6 | vsrPSStatement | 42 | vsrPSISOB4
7 | vsrPSExecutive | 43 | vsrPSJapanesePostcard
8 | vsrPSA3 | 44 | vsrPS9x11
9 | vsrPSA4 | 45 | vsrPS10x11
10 | vsrPSA4Small | 46 | vsrPS15x11
11 | vsrPSA5 | 47 | vsrPSEnvInvite
12 | vsrPSB4 | 50 | vsrPSLetterExtra
13 | vsrPSB5 | 51 | vsrPSLegalExtra
14 | vsrPSFolio | 52 | vsrPSTabloidExtra
15 | vsrPSQuarto | 53 | vsrPSA4Extra
16 | vsrPS10x14 | 54 | vsrPSLetterTransverse
17 | vsrPS11x17 | 55 | vsrPSA4Transverse
18 | vsrPSNote | 56 | vsrPSLetterExtraTransverse
19 | vsrPSEnv9 | 57 | vsrPSAPlus
20 | vsrPSEnv10 | 58 | vsrPSBPlus
21 | vsrPSEnv11 | 59 | vsrPSLetterPlus
22 | vsrPSEnv12 | 60 | vsrPSA4Plus
23 | vsrPSEnv14 | 61 | vsrPSA5Transverse
24 | vsrPSCSheet | 62 | vsrPSB5Transverse
25 | vsrPSDSheet | 63 | vsrPSA3Extra
26 | vsrPSESheet | 64 | vsrPSA5Extra
27 | vsrPSEnvDL | 65 | vsrPSB5Extra
28 | vsrPSEnvC5 | 66 | vsrPSA2
29 | vsrPSEnvC3 | 67 | vsrPSA3Transverse
30 | vsrPSEnvC4 | 68 | vsrPSA3ExtraTransverse
31 | vsrPSEnvC6 | 256 | vsrPSUser
32 | vsrPSEnvC65 |  |
33 | vsrPSEnvB4 |  |
34 | vsrPSEnvB5 |  |
35 | vsrPSEnvB6 |  |

Data Type

ReportPaperSizeSettings (Enumeration)

See Also

Layout Object


Picture Property (Layout)

Returns or sets a background picture for the report body.

Syntax

layout.Picture[ = value As Variant ]

Remarks

You can use the Picture property to specify a bitmap or other type of graphic to be displayed as a background picture on a report (watermark-style).

Use the PictureShow and PictureAlign properties to specify which pages should display the picture and how it should be aligned.

Data Type

Variant

See Also

Layout Object


PictureAlign Property (Layout)

Returns or sets how the background picture is aligned.

Syntax

layout.PictureAlign[ = PictureAlignSettings ]

Remarks

The settings for the PictureAlign property are described below:

Constant | Value | Description
vsrPALeftTop | 0 | Align to the left and to the top, clipping if necessary.
vsrPACenterTop | 1 | Align to the center and to the top, clipping if necessary.
vsrPARightTop | 2 | Align to the right and to the top, clipping if necessary.
vsrPALeftBottom | 3 | Align to the left and to the bottom, clipping if necessary.
vsrPACenterBottom | 4 | Align to the center and to the bottom, clipping if necessary.
vsrPARightBottom | 5 | Align to the right and to the bottom, clipping if necessary.
vsrPALeftMiddle | 6 | Align to the left and to the middle, clipping if necessary.
vsrPACenterMiddle | 7 | Align to the center and to the middle, clipping if necessary.
vsrPARightMiddle | 8 | Align to the right and to the middle, clipping if necessary.
vsrPAClip | 9 | Align to the left and to the top, clipping if necessary.
vsrPAZoom | 10 | Scale the picture to use as much of the page as possible, while preserving the picture's aspect ratio.
vsrPAStretch | 11 | Stretch the picture to fill the page.
vsrPATile | 12 | Tile the picture to fill the page.

To select the background picture and which pages should display it, use the Picture and PictureShow properties.

Data Type

PictureAlignSettings (Enumeration)

See Also

Layout Object


PictureShow Property

Returns or sets where the background picture is displayed.

Syntax

layout.PictureShow[ = PicShowSettings ]

Remarks

The settings for the PictureShow property are described below:

Constant | Value | Description
vsrPSNoPages | 0 | Do not show the background picture.
vsrPSAllPages | 1 | Show the background picture on all pages.
vsrPSFirstPage | 2 | Show the background picture on the first page only.
vsrPSAllButFirstPage | 3 | Show the background picture on all pages but the first.

To select the background picture and how it should be aligned on the page, use the Picture and PictureAlign properties.

Data Type

PicShowSettings (Enumeration)

See Also

Layout Object


Width Property (Layout)

Sets or returns the width of the report's detail section, in twips.

Syntax

layout.Width[ = value As Double ]

Remarks

The Width property determines the width of the detail section of the report. Multi-column reports have header and footer sections that span all columns so their actual width is Width * Columns. For example, a two-column report with a one-inch wide detail section would have Width = 1440, and its total width would be 2880.

Data Type

Double

See Also

Layout Object