Remember Me
forgot your password?

Populating Visual FoxPro Reports with data on the Fly

Abstract:

Visual FoxPro’s report writer is a powerful full-featured report writer that provides all the tools you need to create and ship compelling reports with your application. On Most occasions, you can create Visual FoxPro reports based only on data that already exists (e.g. an existing table, query or view). However, imagine that the data you need to populate your report with does not exist as a table that can be readily added to your report’s data environment nor does it exist as a set of tables upon which you can execute a straight-forward SQL Query or view! This article describes how you can populate a Visual FoxPro report at run time by collecting report criteria from users, deriving the data from your tables based on that criteria, creating a cursor and then populating the cursor with the derived data all at run time.

 

Who should read this article?

This article assumes some familiarity with building and developing applications with Microsoft Visual FoxPro 9

Introduction:

One of the key benefits of using Visual FoxPro as your primary development tool is that it provides all of the tools you need to build powerful, compelling full-featured applications that are fast and feature rich!

One of the features of Visual FoxPro that makes this possible is the newly revamped report writer that ships with Visual FoxPro 9! Because of the need to provide or make data available for your report or label before you print it, the Report Writer provides a variety of ways to make data easily available for your report.

One method of making data available for your report and incidentally the most often used is to write a report that is always based on the same data sources. This method would actually require you to add tables or views to the data environment of a report or to use a DO <query> command in the Init event of the report’s data environment. Alternatively, you could execute a query by creating an executing an SQL Statement in the Init event of the report’s data environment.

A second method is when you need to create a report that utilizes separate sets of data sources for the report. In this case, you would dynamically open those data sources at run time by using a USE <table>, USE <view>, DO <query> or SQL SELECT statement to the click event of a button or other code that will run before you issue a REPORT or LABEL command.

However, what happens when the data for your report is not in a table that can be dynamically queried with a SELECT SQL statement nor is it in a form that you can simply open with a USE command! The Richness of the Visual FoxPro programming language allows you to easily solve this problem as this article will demonstrate. To demonstrate the concept being discussed, imagine that you need to print or generate the Income and Expense Report for your company as at a given day! This would mean that you need to keep a daily running balance of each account in your General Ledger chart of accounts in a table that we shall perhaps call ActGLDayTot. The sections that follow will describe how to create these tables and their structure as well as the code that generates the report.

Printing Reports in Visual FoxPro

As already noted, you need to make data available for a report before you proceed to print the report. To print a report in Visual FoxPro, you will need to issue the REPORT FORM <reportname> command. For the full syntax of the REPORT FORM command, see your Visual FoxPro 9 online help documentation.

If you issue the REPORT FORM command with no tables in the data environment and no data sources open in the data environment of the report, the report simply appears to flash and then close again! To avoid this situation, you will either need to add data to the data environment or use the Init event of the data environment to make data available within the data environment prior to printing. When the data does not already exist in a query or in a form that can be directly queried, what will you do?

Making Data Available on the Fly

Because data must be first made available prior to running a report, you will need to issue an SQL SELECT statement or open a table at least in the Init event of the Data Environment of the report. However, if your data does not exist in a form in which you can easily build a view over it or a query over it and if it does not exist in a form in which it can be added as a table then neither of the methods discussed so far will yield the desired results!

This means that you must find a new way of making the data available to your program. A closer examination of how you would use the SQL SELECT statement provides an insight into how you could do this. The general form of the syntax of the SQL SELECT Statement we want to consider is as follows:

 

 

 

SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] Select_List_Item [, ...]

 

   FROM [FORCE] Table_List_Item [, ...]

 

   [WHERE JoinCondition | FilterCondition [AND | OR JoinCondition | FilterCondition] ...]

 

   [INTO StorageDestination | TO DisplayDestination]

 

 

This form of the syntax indicates that the SQL SELECT statement creates a query and then fetches the required information from the table into a storage destination most usually, a cursor (temporary table), table or array. The cursor representing storage destination is then used as the source of data for the report. Based on this actuality, we can deduce that our report would run if we created a cursor object using the CREATE CURSOR or a temporary table using CREATE TABLE in the Init event of the data environment. This would make data available to the report and would thus prevent the report from again closing immediately upon being opened.

How would this actually work in practice?

1.       Create your Report: First off, you would have to create a report a report in the Report Designer. You can do this by choosing the Reports Node in the Project Manager and then choosing the New button. When the New Report dialog box displays, you would then choose New Report. Visual FoxPro would then create a new blank report named Report1 and open it in the Report Designer

2.       Layout your Report: Now that the report designer is open, you can start laying out your report. Usually, you would do this by dragging fields from the data environment unto the report canvas. But in this case, you have no data in the data environment so you must set the properties of the report manually. You must therefore display the Reports Controls Toolbar by choosing Reports Control Toolbar from the View main menu. Once the toolbar displays, you can layout your report surface by performing the following action:

a.      Select a control from the toolbox to be placed on your report. If you select a control such as a text box control and then click on the detail band of the report, Visual FoxPro automatically opens the Field Properties dialog box so you can set not only the source of data for the field but also other characteristics of the field.

b.      In the Expression box on the General tabbed page, enter the expression that will server as a source of data for the report. You will enter it in the format cursorname.fieldname where Cursorname will represent the name of the cursor that you will create (of course you have not created it yet otherwise you would simply have chosen the … button to allow you select it from the expression builder[i]). If you click a control such as a Label control, place it anywhere on the report and then type where the Insertion point appears to add a descriptive label. For example, click a label control on the report and then add a descriptive label for each text box in the Page header. You can add descriptions such as Field One and Field Two. You can add a report title (e.g. Test Report) by clicking on the Label control, and then clicking at the appropriate position on the Report Header. To set styles and font sizes for your captions, right-click the appropriate caption, choose Properties and then choose the Style tabbed page. In the Style tabbed page, you can make the appropriate settings under the Font box or make any other settings as necessary. Remember to save your work as you go along.

c.       Now that you have gotten fields onto your report, you can apply the usual formatting to the report such as calculated fields, lines, etc

3.       Set Properties for the Data Environment: You will still want to prevent your report from automatically shutting down when you try to run it so you must set properties for the data environment as follows:

a.      Right-click your report and then choose the Data Environment menu command from the shortcut menu that displays. The Data Environment – Report Designer opens. It is empty, showing that no data sources have been added to it.

b.      Right-Click inside the Data Environment and then choose the Properties menu command to display the properties sheet for the Data Environment.

c.       Set the AutoOpenTables property to false. When you set this property to false, the report does not attempt to open the tables or views in the data environment upon running of the report. If this were to happen, the report would simply find that the data environment did not contain any data and then the report would close abruptly. You are now ready to add code for the report as described in the next step (step 4 – Writing code to make data available).

4.       Write Code to make Data Available: Remember that the data is to be fetched or made available only at run time. So you must now write the code that will make this data available for your report. You will do this in the Init event of the data environment by writing code such as:

a.      Locate the Init event of the data environment in the properties sheet and then double-click it to open the code window.

b.      In the code window, type the code that creates your cursor by using the CREATE CURSOR command and also write code to add several records to the cursor by using the APPEND command. This code could look as follows:

 

CREATE CURSOR Testcursor (Field1 c(10) unique,Field2 i)

APPEND BLANK

REPLACE TestCursor.Field1 WITH "TEST"

REPLACE TestCursor.Field2 WITH 50

APPEND BLANK

REPLACE TestCursor.Field1 WITH "TEST2"

REPLACE TestCursor.Field2 WITH 100

APPEND BLANK

REPLACE TestCursor.Field1 WITH "TEST3"

REPLACE TestCursor.Field2 WITH 150

 

 

c.       Close the code window and close the data environment designer

d.      Quickly test your report by choosing the Print Preview button on the toolbar. The report should open in Print Preview mode.

5.       Save and Run your Report: Now that you have created your report and generated data at run time, you will need to save the report and then to run it. You can test whether your report will run by performing the following action:

a.      Choose the Save button on the toolbar to ensure that you have saved your report.

b.      Close the report by choosing the Close button. The report appears under the Reports node in the Project Manager.

c.       To run this report, select the report (Report1) in the project manager and then choose the Preview button. The report opens in print preview mode.

6.       Running Your Report Through the User Interface: You would typically make your report available to the users of your application through the application user interface. For example, you may provide a form through which users can select your report and then press either a preview or a print button. To do this, you will have to use the REPORT FORM command to run the report programmatically. If you want your report to be available through the application user interface, you will have to perform the following action:

a.      Select the Forms node on the Documents tabbed page of the Visual FoxPro project manager and then choose the New button. The New Form dialog box displays.

b.      Choose the New Form button. Visual FoxPro creates a new form named Form1 and opens it in the Form Designer.

c.       Display the Forms Control Toolbox if it is not already displayed by choosing the Form Controls Toolbar menu on the view menu.

d.      Select the Command Button control on the Forms Control Toolbox and then click on the form. Visual FoxPro will create a new command button called Command1.

e.       Double-Click Command1 button to display the Code window for its Click event.

f.        You can now enter the following code:

 

REPORT FORM Report4.frx NOCONSOLE PREVIEW

 

g.      Click the Save button on the button bar to save the form you have created.

h.      Run the form by either pressing Ctrl + E or by choosing the Run toolbar button on the toolbar. The form runs.

i.         Now click the command button to run the report. The report appears in print preview window.

Applying the concept to a Real Life Situation

The example already illustrated has been kept deliberately simple. Now, this must be applied in a real-life situation. In the example shown, the cursor is populated by issuing APPEND BLANK commands. In a real-life application however, it may be possible that your data may already exist, needing only to be read back and re-arranged into a format that your report can print. Lets illustrate this by building a Trial Balance Report as at a given day (Trial balances are usually printed as at a given period end date).

To be able to print such a trail balance, we would have to know the balance of an account as at a given day. Lets now accept that such data is stored day-by-day as transactions are passed in a table called ActGLDayTot and this table could be created with the following SQL Statement:

CREATE TABLE ActGLDayTot(BatchNo c(20) PRIMARY KEY,AccountCode c(15),;

ValueDate D,CurrYear i,NextYear i,PeriodNumb i,MonthNumb i,Debitamt Y,;

CreditAmt Y,Balance Y)

 

For each account in the General Ledger Master file, we want to obtain the account’s balances as at the specified day so that we will be able to build the trial balance. Now imagine that your General Ledger Master table could be created with the following SQL Statement:

CREATE TABLE ActGLMast(AccountCode c(15) PRIMARY KEY,AccountName c(50),;

AccountType c(40),CurrBal Y)

The following code is placed in the Init Event of the data environment of our report:

* This Code Constructs the cursor used in the Report

LOCAL dValueDate AS Date,cBranchCode aS Character,intNoOfRows as Integer,oDT as Object ,lAnswer as Logical

DIMENSION arrTR(1,9)

STORE "" TO cBranchCode

STORE ({  /  /    }) TO dValueDate

STORE 0 TO intNoOfRows

 

* 1) Open the form and obtain the parameters

DO FORM frmMgtTBalByDate.Scx LINKED

dValueDate = frmMgtTBalByDate.txtValueDate.Value

cBranchCode = frmMgtTBalByDate.txtBranchCode.Value

frmMgtTBalbyDate.RELEASE

*OPENTABLES()

 

oDT = CREATEOBJECT('ActGLDayTot')

lAnswer  = oDT.GetTransByDate(dValueDate,cBranchCode,arrTR,intNoOfRows,chrProgTitle)

CREATE CURSOR MgtTBalByDate (AccountCode c(20),AccountName c(50),AccountType c(50),TBalDate D,MTDDebit Y,MTDCredit Y,YTDDebit Y,YTDCredit Y,UserName C(10))

SELECT MgtTBalByDate

APPEND FROM ARRAY arrTR

This.OpenTables()

 

In the code above memory variables are declared that will be used either to hold the user’s report criteria or to store and transport data. The DIMENSION command creates an array that will be used to return data from a Data Aware Class that encapsulates the functionality of the ActGLDayTot table. Another thing to note is how we have allowed users to specify the data to be included in the report by entering the specified date for which they want a trial balance. To collect this information from the users, the line DO FORM frmMgtTBalByDate.Scx runs the report parameter form so users can enter criteria. When  the user clicks the Ok button in that form, a THISFORM.Hide command temporarily hides the form from the user while the lines immediately following the DO FORM command collect the information on the form. The line frmMgtTBalByDate.RELEASE then removes the form from memory.

 

Next, the line oDT = CREATEOBJECT (‘ActGLDayTot’) creates an instance of the class ActGLDayTot and stores a reference to it in the object variable oDT. The line lAnswer = GetTransByDate… calls the method in the class to return the specific data we want, passing the necessary parameters collected form the user along with the array that will be used to store and transport the data back to our report.

 

As we did earlier, we then use a CREATE CURSOR MgtTBalByDate command to create a cursor with the necessary fields. The line APPEND FROM ARRAY arrTR populates the table. The report is then made to recognize this cursor in its data environment with the line THIS.OpenTables().

 

By separating the code that does the collection and processing of information from the Report’s own Init event, we are able to make this code available always form multiple locations because it is contained in a data aware class. The code contained within the GetTransByDate method of the ActGLDayTot class is as follows:

 

* Obtain Transaction By Date

PARAMETERS dTranDate,cBranchCode,arrTR,intNoOfRows,chrProgTitle

LOCAL cMsg AS Character,intRows AS Integer,lGLMastInUse AS Logical

LOCAL lGLDayTotInUse as Logical

 

* Initialize your variables to the correct types to avoid any errors

STORE "" TO cMsg

STORE 0 TO intRows

 

IF TYPE('dTranDate') <> 'D'

      cMsg = "You must enter transaction date!"

      MESSAGEBOX(cMsg,48,chrProgTitle)

      RETURN .F.

ENDIF

 

IF TYPE('intNoOfRows') <> "N"

      RETURN .F.

ENDIF

 

IF TYPE('arrTR',1) <> "A"

      cMsg = "Array of Transactions not found!"

      MESSAGEBOX(cMsg,48,chrProgTitle)

      RETURN .F.

ENDIF

 

IF TYPE('cBranchCode') <> "C"

      cMsg = "ALL"

ELSE

      cMsg = " FOR BranchCode = '" + cBranchCode + "'"

ENDIF

 

IF USED('ActGLMast')

      lGLMastInUse = .T.

ELSE

      USE ActGLMast IN 0

      lGLMastInUse = .F.

ENDIF

SELECT ActGLMast

GO TOP

 

IF USED('ActGLDayTot')

      lGLDayTotInUse  = .T.

ELSE

      USE ActGLDayTot IN 0

      lGLDayTotInUse = .F.

ENDIF

SELECT ActGLMast

GO TOP

SCAN &cMsg

      intRows = intRows + 1

      DIMENSION arrTR(intRows,9)   

      arrTR(intRows,1) = ActGLMast.AccountCode

      arrTR(intRows,2) = ActGLMast.AccountName

      arrTR(intRows,3) = ActGLMast.AccountType

      DO CASE

            CASE ActGLMast.CurrBal > 0

                  arrTR(intRows,7) = ActGLMast.CurrBal

                  arrTR(intRows,8) = 0

            CASE ActGLMast.CurrBal < 0

                  arrTR(intRows,7) = 0

                  arrTR(intRows,8) = ActGLMast.CurrBal

            OTHERWISE

                  arrTR(intRows,7) = 0  && YTD Debit

                  arrTR(intRows,8) = 0  && YTD Credit

      ENDCASE

      SELECT ActGLDayTot

      GO TOP

      *LOCATE FOR ALLTRIM(ActGLDayTot.AccountCode) = ALLTRIM(cAccountCode) AND ActGLDayTot.ValueDate = dTranDate

      LOCATE FOR ActGLDayTot.ValueDate = dTranDate

      IF FOUND()

                  DO CASE

                        CASE ActGLDayTot.Balance > 0

                              arrTR(intRows,5) = ActGLDayTot.Balance

                              arrTR(intRows,6) = 0

                        CASE ActGLDayTot.Balance < 0

                              arrTR(intRows,5) = 0

                              arrTR(intRows,6) = ActGLDayTot.Balance

                        OTHERWISE

                              arrTR(intRows,5) = 0

                              arrTR(intRows,6) = 0

                  ENDCASE

      ELSE

            arrTR(intRows,5) = 0    && MTD Debit

            arrTR(intRows,6) = 0    && MTD Credit

      ENDIF

ENDSCAN

intNoOfRows = intRows

* Now close all tables you dont need

IF NOT lGLMastInUse

      USE IN ActGLMast

ENDIF

IF NOT lGLDayTotInUse

      USE IN ActGLDayTot

ENDIF

RETURN .T.

 

The PARAMETERS command that begins the method identifies the parameters passed to the class. The program uses a SCAN…ENDSCAN loop to go through the ActGLMast table to isolate all accounts that meet the criteria and then to populate the array with matching data from the ActGlDayTot table. At the end, the program returns .T. if the method completes successfully. You could now run this report with a REPORT FORM command just as we did either from a form or visual FoxPro menu.

 

Conclusion

 

Visual FoxPro’s data manipulation language is one of the things that makes Visual FoxPro standout amongst numerous products in its class. This article has demonstrated how the richness of the Visual FoxPro language and development environment allows a developer to compile the data needed for a report at run time and still be able to pretty much control the report generation process. Even though this article has assumed that the programmer is building a ‘pure fox’ application (after all, Visual FoxPro gives you pretty much everything you need to build complete robust data management applications), with a little tuning and changes, you can use this method to derive data from powerful SQL Servers such as ORACLE, Microsoft’s own SQL Server or Advantage Database Server for use within a Visual FoxPro report. If you can imagine it, Visual FoxPro lets you build it.

 

 

[i] If you want to be able to use the expression building to select from a list of fields using a field picker, then you may have to type a command in the command window that creates your cursor in advance before proceeding to layout the report designer. If you do this, the fields of the cursor will be available to you from the expression building. For example, you could type the following in the command window:

CREATE CURSOR Testcursor (Field1 c(10) unique,Field2 i)

Once you have done this, you will find the fields of your cursor listed in the fields list on the expression builder, so you can just click the desired field to be added to the report.

Sylvester Alelele

Sylvester Alelele is a Senior Systems Analyst/Programmer and Group Head of Operations for Forest-Elephant Technology & Procurement Group Plc. He lives and works in Addis Ababa Ethiopia. He develops applications with Microsoft Visual FoxPro, Visual Basic and the .Net Framework, Oracle, Advantage Database Server and Ms SQL Server. He has over sixteen (16) years of experience building enterprise database solutions of all sizes

Rate this Article: 0 / 5 stars - 0 vote(s)
Print Email Re-Publish

Add new Comment



Captcha

  • Latest Programming Articles
  • More from Sylvester Alelele

Syntax Not Understood Error For Robots.txt File in Google Webmaster Tools

By: Murat Yasar | 01/01/2010
I saw a strange error in my webmaster tools account when I reviewed robots.txt file. It was saying that syntax not understood.

Websites Development: Make Your Presence Felt in the Online World

By: Arun Kumar | 01/01/2010
For corporate enterprises, these companies offer a site development which can give a strong corporate identity for your business which has the potential to impress potential clients, partners, and customers. For small businesses, the designs offered are usually affordable and customizable with easy site navigation.

How to Locate and Make the Most of an iPhone Web Development Company?

By: Arun Kumar | 01/01/2010
By installing the iPhone apps, be it the web based or the business or entertainment based, you can easily broaden your wings of achievement all easily. All sorts of iPhone apps are now becoming extremely popular because of their ease of use. They can be easily downloaded from the web just by paying a very reasonable amount to the developers.

Integrating facebook in cakephp

By: Digisha Modi | 30/12/2009
FaceBook Application is the powerful tool of marketing or to connect people for all type of business. Now it's easier to find social applications on Facebook, on your phone, and on external websites. The new "Featured by Facebook" section highlights Facebook's favorites. Since 2007 the kind of concept FaceBook has come up with become a unique challenger to established payers. The benefit of FaceBook application is any one can post their own application with out any cost.

Outsourcing of iPhone Application Development Offers Profits for Developers as Well as Users

By: Arun Kumar | 30/12/2009
Being a 3G phone, it offers users the advantage of thrilling web access which helps them being on top of all online activities even on the move. Also, there are several additional applications available for download for the device. Thanks to the efforts of the outsource iPhone application development firms which have helped iPhone users get more with their devices using the apps developed by their expert developers.

Magento Template Integration

By: Digisha Modi | 30/12/2009
If you have purchased Magento template or simply need to integrate an existing graphic design template into your e-commerce shop we will integrate it into Magento for you. A web template is a ready- made web design need to be integrated. Usually web templates make possible a standardized layout (page arranging, colors, positions, etc.) for different web contents while using the same basic layout.

Magneto Template Designing

By: Digisha Modi | 30/12/2009
If you want your magento store to be very attractive and user friendly then we at Biztech Consultancy do it for you. We help in customizing the appearance of your Magento e-commerce store with Magneto’s powerful theming engine. Basically Magento theme is combination of layout, template and/or skin file(s) that create the visual experience of your store.

Pass4side 000-135 practice test

By: Adela1987 | 30/12/2009
Pass4side 000-135 Details: Pass4side is your source for the IT Exam 000-135 exam. With our 000-135 Exam Resources, you can be rest assured that you will Pass your 000-135 Exam on Your First Try. Our Exams are written and formatted by Top senior IT Professionals working in today is prospering companies and data centers. All of our practice exams including the IBM 000-135 exam guarantee you success on your First Try. 000-135 is a challenging exam,with our 000-135 study guide,you can feel safe wit

Populating Visual FoxPro Reports with data on the Fly

By: Sylvester Alelele | 27/08/2009 | Programming
If you are using Visual FoxPro's Report Writer as your reporting environment, how can you generate report data and populate your report at run time? This article explains how to generate or compile data at report run time to be used by your report. This data may not exist or may exist in a form that cannot be readily used in the report!

When it is crunch time: Migrating from Visual Basic 6 to Visual Basic .Net/2005

By: Sylvester Alelele | 27/08/2009 | Programming
As a Visual Basic 6.0 programmer, what is the roadmap forward for your applications? As Visual Basic 6.0 becomes ‘deprecated technology’ what will you do with your enterprise class applications written in Visual Basic 6.0. This article is the musings of a developer that has been looking at migrating existing enterprise-class Visual Basic 6.0 applications to Visual Basic 2005.

Building Data Aware Classes in Visual FoxPro Part 2: Using Data Transports and Temporary Storage

By: Sylvester Alelele | 16/07/2009 | Programming
In the last article (Part 1), we discussed how to encapsulate data access code and business rules in Visual FoxPro by using classes contained in Visual Class Libraries (.vcx) files. If Data Access and Validate code is encapsulated in classes, how can data be returned to a form and how can data-bound forms be built? This artcliel seeks to demonstrate that you can build effective database applications even though your data access code is encapsulated in Data-Aware Classes

Building and Using Data Aware Classes in Visual FoxPro Applications Part 1: Utilizing Visual Class Libraries for Data Access and Business Rules

By: Sylvester Alelele | 23/06/2009 | Programming
Visual Class Libraries allow you to build powerful Visual FoxPro applications and to implement powerful Object Oriented features. Because you can create your own class libraries, you will have an additional place to put code that accesses your application database by building data aware classes (classes that can ‘talk’ to your database and either return queried information, save new information or perform updates and deletes as necessary). This article explores use of Data Aware Classes.

Visual FoxPro is still here, still very relevant

By: Sylvester Alelele | 22/04/2009 | Databases
An artime on SD Times Paraises FoxPro's Contributions to technology and then Asks 'Where have you gone Visual FoxPro?' In this article,we want to share some of the great things Visual FoxPro is doing in our part of the world and how VFP provides a robust database environment for architecting affordable enterprise class applications for fast growing companies. This article discusses why Visual FoxPro continues to be a compelling tool in applications development and why FoxPro will remain relevant

Submit Your Articles Free: Signup
Article Categories




Use of this web site constitutes acceptance of the Terms Of Use and Privacy Policy | User published content is licensed under a Creative Commons License.
Copyright © 2005-2008 Free Articles by ArticlesBase.com, All rights reserved. (0.08, 1, w3)