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

By Jerry J. Jansen On June 28, 2009 Under Uncategorized

Abstract: 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). Data Aware classes provide a powerful means to control access to your data and also reduce the amount of data access code you will have to write. This promotes code reuse (meaning that the same code can be called from more than one application module to perform the same task). The next few articles will explore the use of Data Aware Classes to build powerful Visual FoxPro Applications. This article (Part 1) will discuss how to build data aware Visual FoxPro classes for use in your pure Visual FoxPro desktop code. Other articles will explore how to access remote Visual FoxPro or Client Server and develop thin client applications.

Introduction

Visual FoxPro classes allow you to encapsulate much of your code and make functionality instantly accessible to all parts of your application. Code contained in a class can be accessible once you create an instance of that class for use in your code. This means that powerful data access functionality can now be made available by means of setting object properties and calling class methods

At first glance, the tight coupling of data and language in Visual FoxPro makes it seem that this is not necessary, after all; you can just add a table to your form’s data environment and then use the SELECT Command to make it the active alias! If you are using Visual FoxPro to build applications that access a powerful SQL Servers such as ORACLE or Ms SQL or Advantage Database Server, the process looks even more opaque being that you are dealing with a very powerful database engine both on the front-end and the back-end.

However, good software design, even for pure fox applications can benefit from encapsulation of data access, storage and processing that data aware classes bring! The main benefits are that you have an extra place to put code (not just on the Form’s Front-End or Visual FoxPro Stored Procedures and Triggers attached to the Visual FoxPro Database .dbc  file) plus the fact that the functionality to operate on one table is encapsulated in one class based on that table so you can easily amend this code without affecting the functionality of your application in a major way. Additionally, by encapsulating your code in Classes, you protect your investment in code by placing sensitive code in a secure location without having the need to replicate such code in several event procedures in different forms.

In Microsoft Visual FoxPro, classes are contained in Visual Class Library (.vcx) files or you could even dynamically create one in code using the CREATE CLASS command. You can then add these vcx files to your tool box and then drop them on a form or simply use the CREATEOBJECT command at run time to create the object and invoke its methods and properties. If you drop the class from the toolbox onto your form, you will not need to use CREATEOBJECT but will only have to call the properties and methods of the class as for example: THISFORM.Employees1.AddRecord to perform a task.

An Example of How and when to Use Data Access Classes

We have found over the years that an easy way to organize the data classes in your application is to come-out with a solid, well normalized database. In this way, you ensure that the tables that comprise your application do not contain redundant information. You can then logically represent each table with a data class that will operate on it. The fields of each table can quickly become the properties of the class, while it could have methods that add and remove records. If you had an employees table represented by an Employee custom class in a vcx file, you could have methods such as AddPerson(), RemovePerson(),FindPersons(), GetPersons(), IncreaseSalary(), CheckStatus() and so on. You could pass parameters as need be to each method as needed to enable the method complete its work. Once you had the class defined, you could call it from any form or even another class where an employee service is required.

For example, imagine that you needed to check the status of an employee during payroll computation to see if the employee is still a valid employee or has been released from the employment of the company! You could open the employees table, scan until you find the employee record and then check its status field! If you needed to perform this same check from the Promotions module, you would have to write the same code again! How much easier it would be to call the CheckStatus() method of the Employees custom class and you know that the code to perform this valuable service is kept in one location that you can amend at any time. One amendment is immediately reflected in all places where you used that class because VFP immediately propagates changes in the parent class code to all sub classes. The class that represents your table and works on it could be created as a non-visual class (one that displays a visual element at design time only but not at run time by basing it on the Custom Base Class). Lets imagine that you had the following table called Employee in a Visual FoxPro Database:

 

Field Name

Type

Width

Dec

Index

Null

EmpID

I

4

 

Y(P)Auto

N

EmpName

C

50

 

 

Y

EmpDept

C

10

 

 

Y

EmpStatus

C

10

 

 

Y

 

You can use the following SQL Statement to create the table shown above:

CREATE TABLE Employees (EmpID I NOT NULL AUTOINC NEXTVALUE 1 STEPVALUE 1 PRIMARY KEY

EmpName c(50) NULL,EmpDept c(10) NULL,EmpStatus c(10))

Of course, you could have several other tables in your Visual FoxPro database as the need may be.

The Employees Class

The Employees class will provide the data services required by your application’s form including saving information, deleting data and searching for existing information and then returning these to the form as the need may be. If a real-world application, you may have many more methods and Visual FoxPro allows you to have as many methods as need be.

You can now organize your class based on the following class diagram:

Member

Description

Member Type

Visibility

EmpID

Unique ID of each employee

Property

Public

EmpName

Name of each employee

Property

Public

EmpDept

Department to which an employee belongs

Property

Public

EmpStatus

Current Status of Employee

Property

Public

MBInfo

Constant for information icon. Default Value is 64

Property

Hidden

MBExclamation

Constant for Exclamation Point. Default Value is 48

Property

Hidden

AddEmployee()

Insert a New employee into the table

Method

Public

RemEmployee()

Delete an employee from the table

Method

Public

FindEmployee()

Search for an Return an Employee Record

Method

Public

 

Create the Class

If you do not yet have a Visual Class Library in your project, you can create a new library now by choosing the New button on the Classes tab of your Visual FoxPro project manager. The library that you create will have a .vcx file extension and will list on the Classes tab. Now that you have added a new visual class library, you can add a custom class to it by performing the following action:

  • Select the Visual Class Library to which you want to add the new Employees class on the Classes tab and then choose the New button. The New Class dialog box displays.
  • Enter Employees on the Class Name box and then select Custom from the Based On drop down list box
  • Choose Ok.  The Class Designer displays.

 

Add the Properties and Methods

 

Now that the Class Designer displays, you can proceed to add your properties to your class. You can add properties to your visual class by performing the following action:

  • Choose the New Property menu command from the Class main menu. The New Property dialog box displays so that you can begin adding properties.
  • In the Name box, type the name of your property. For example, EmpID.
  • In the Visibility field, select Public (which means that code in other classes or procedures can set the value of this property). If you set visibility to Hidden, only members of your class will see it. If you set the visibility to Protected, access to the member is protected.
  • In the Default/Initial value field, initialize the value of the property. By default, .F. (False) appears in this field. If property will hold a character value, you can leave this box blank to initialize the property value to nothing.
  • In the Description box, describe this field. This description will display on the description area in the property window to enable a user of your class understand the purpose of the class.
  • Choose the Add button to add the class.
  • Repeat this action to add all the properties in your class.
  • Choose the Close button when you are done.

You can now proceed to also add methods to your class. A method is anything that your object can do. So in our case, since the class represents the employees table, it should be able to add a new record (AddEmployee()), remove an unwanted record from the table (RemEmployee()), and so on. You can add a method to your class module by performing the following action:

  • Choose the New Method menu command from the Class main menu. The New Method dialog box displays.
  • In the Name field, add the name of your method e.g. AddEmployee.
  • In the Description box, type the description of the class. This description displays at the bottom part of the Properties window, when you select the method in the properties window.
  • Choose the Add button to add the method.
  • In the Visibility box, choose Public. Like properties, methods could either be Public, Hidden or Protected.
  • Repeat this procedure for all the methods you want to add.
  • Choose the Close button when you are done adding methods.

 

Add Code to your methods

We can now add code to make the methods work for us.

Insert a New Record

If you have a form, you would add the control to the form. Visual FoxPro would give the control the name Employees1. Alternatively, you could create an instance of the control in code using the CreateObject function. Either way, once you have a reference to the object, you could call the AddEmployee method of the class after setting properties.  So the form could have text boxes for the relevant information to be collected and could then set properties for the controls in the Click event of a Save command button like this:

THISFORM.Employees1.EmpID = THISFORM.txtEmpID.Value

THISFORM.Employees1.EmpName = THISFORM.txtEmpName.Value

THISFORM.Employees1.EmpDept = THISFORM.txtEmpDept.Value

THISFORM.Employees1.EmpStatus = THISFORM.txtEmpStatus.Value

lAnswer = THISFORM.Employees1.Save(“Data Aware Class”)

IF NOT lAnswer

                cMsg = “Record not saved successfully!”

                MESSAGEBOX(cMsg,64,”Data Aware Class”)

                RETURN

ENDIF

THISFORM.cmdNew.Click    && Clear form for new/next record

The code behind the AddEmployee method could then look like this:

PARAMETERS cProgTitle

LOCAL lFileInUse AS Logical,cMsg AS Character

cMsg = “”

                Check to ensure that the correct data has been supplied

                IF ISBLANK(THIS.EmpName)                && Each user must have a name

                                cMsg = “Enter an employee name!”

                                MESSAGEBOX(cMsg,THIS.MBINFO,cProgTitle)

                                RETURN .F.             && Tell user you did not complete successfully

                ENDIF

                IF USED(“Employees”)

                                lFileInUse = .T.

                ELSE

                                USE Employees IN 0

                                lFileInUse = .F.

ENDIF

SELECT Employees

GO TOP

IF THIS.EmpID <= 0

                APPEND BLANK  && Table automatically assigned next ID

ENDIF

REPLACE Employees.EmpName WITH THIS.EmpName

REPLACE Employees.EmpDept WITH THIS.EmpDept

REPLACE Employees.EmpStatus WITH THIS.EmpStatus

IF NOT lFileInUse   && We are the ones that opened it…close it now

                USE IN Employees

ENDIF

RETURN .T.             && Tell user you completed successfully

The code accepts one parameter – cProgTitle that can be used in the MESSAGEBOX function to display the name of the application that calls the method. This also illustrates the ability to pass parameters to your procedure just as you would have passed them to any other procedure or function. This also opens up the possibility that you could declare and use arrays to pass the information especially in network environments to reduce the amount of network traffic that you would generate each time you set or retrieved a property (but that is a subject for another day)!

After this local variables used in this method are declared and a series of IF statements will check to ensure that basic information is supplied. Of course this is a demonstration program. In a real life program, your class could contain many more methods and thus many more checks!

If our table is already opened in another work area, we can simply use it (lFileInUse) otherwise, we open it with the USE command and set the lFileInUse flag to remember to close it again later when we are existing the procedure (IF NOT lFileInUSe…). We will insert a new record is EmpID is zero (because EmpID is always automatically assigned by the system since it is an Auto Increment field). A series of REPLACE commands then save the record to your table. RETURN .T./RETURN .F. is our means of telling the user whether the procedure completed successfully or not.

Find and Return a Record

Another critical service that your class would perform would be to search the table for an existing record and then return that record to you. Once the record is returned, it could be displayed, edited and then the changes saved back to the table. Your Data Form could contain a Find button whose click event could contain the following code:

LOCAL cMsg

cMsg = “”

IF THISFORM.txtEmpID.Value = 0

                cMsg = “Enter an employee ID to find!”

                MESSAGEBOX(cMsg,64,”Data Aware Classes’)

                THISFORM.txtEmpID.SetFocus

                RETURN

ENDIF

lAnswer = THISFORM.Employees1.FindEmployee(THISFORM.txtEmpID.value,”Data Aware Classes”)

IF NOT lAnswer

                cMsg = “Employee not found or does not exist!”

                MESSAGEBOX(cMsg,64,”Data Aware Classes”

                THISFORM.txtEmpID.Value = 0

                RETURN

ENDIF

                ‘ * Display the record for editing

                THISFORM.txtEmpName.Value = THISFORM.Employees1.EmpName

                THISFORM.txtEmpDept.Value = THISFORM.Employees1.EmpDept

                THISFORM.txtEmpStatus.Value = THISFORM.Employees1.EmpStatus

               

Once the record is displayed as described above, you could move the cursor into any field and then make amendments to the record after which you could click the Save button to save the changes you have made. The code in the FindEmployee method of the class could then look like this:

PARAMETERS nEmpID,cProgTitle

LOCAL cMsg AS Character,lFileInUse IN Logical

IF nEmpID = 0        && No employee ID supplied…exit

                RETURN .F.             &&  Tell user you did not perform the search

ENDIF

IF USED(“Employees”)          && If file is already in use…use it

                lFileInUse  = .T.      && So we shall leave it open

ELSE

                lFileInUse = .F.       && So we shall remember to close it

ENDIF

SELECT Employees

GO TOP

LOCATE FOR Employees.EmpID = THIS.EmpID

IF NOT FOUND()    && Record not found or does not exist

                IF NOT lFileInUse   && Close the table

                                USE IN Employees

                ENDIF

                RETURN .F.

ENDIF

THIS.EmpName = Employees.EmpName

THIS.EmpDept = Employees.EmpName

THIS.EmpStatus = Employees.EmpStatus

IF NOT lFileInUse   && Cloise Table if we opened it

                USE IN Employees

ENDIF

RETURN .T.             && Tell user you did it successfully

The parameter EmpID is the value that the employee wants to search for. By making the employee supply the value to be searched for, you accept use input and then search for it. The table Employees is open if it is not already open and a LOCATE command is used to search for the record. If the record IS NOT FOUND(), the table is closed and .F. (false) is returned to the calling procedure to indicate that the employee requested could not be found otherwise, the properties of the class module are updated so these can be accessed by the calling application.

Delete a Record

Just as you can add and emend records, you could also build your class module to remove records you don’t want to keep. Your form could call the class method to perform the deletion by having code such as this:

LOCAL cMsg,lAnswer

cMsg = “”

IF THISFORM.txtEmpID.Value = 0

                cMsg = “Display an existing record and then try again!”
                MESSAGEBOX(cMsg,64,”Data Aware Classes”

                RETURN

ENDIF

lAnswer = THISFORM.Employees1.RemEmployee(THISFORM.txtEmpID.Value,”Data Aware Classes”)

IF NOT lAnswer

                cMsg = “Record was not successfully deleted!”

MESSAGEBOX(cMsg,48,”Data Aware Classes”)

THISFORM.txtEmpID.SetFocus

RETURN

ENDIF

THISFORM.cmdNew.Click

cMsg = “Record was successfully deleted!”

MESSAGEBOX(cMsg,64,”Data Aware Classes”)

The above code calls the Class module with the line lAnswer = THISFORM.Employees1.RemEmployee. This is because the Rememployee method returns a logical (True or False) to indicate whether the process completed successfully. Now the RemEmployee class can have the following code:

PARAMETERS nEmpID,cProgTitle

LOCAL cMsg, lAnswer, lFileInUse

cMsg = “”

IF nEmpID = 0        && No employee record was supplied

                RETURN .F.

ENDIF

IF USED(“Employees”)

                lFileInUse = .T.

ELSE

                USE Employees IN 0

                lFileInUse = .F.

ENDIF

SELECT Employees

GO TOP

LOCATE FOR Employees.EmpID = THIS.EmpID

IF NOT FOUND()

                IF NOT lFileInUse   && Close the file

                                USE IN Employees

                ENDIF

                RETURN .F.

ENDIF

DELETE                   && Delete the record…you will pack later

IF NOT lFileInUse

                USE IN Employees && Close file

ENDIF

RETURN .T.

In the Code above, the calling procedure passes the employee ID of the record to be removed to the RemEmployee method of the class. The method checks for and opens the table if need be and then uses a LOCATE command to check to see if the record already exists. If it does, it will delete the record and return .T. (True) else it will return .F. (False).

Clearing the Screen

You could add a New button to your form to clear off the current record from the window. This Click even of this button is also called from the Save and Delete command buttons. The click even of this button could simply contain the following code:

THISFORM.txtEmpID.Value = 0

THISFORM.txtEmpName.Value = “”

THISFORM.txtEmpDept.Value = “”

THISFORM.txtEmpStatus.Value = “”

Closing your form

When you have finished working with the forms in your application, you must close the window. The Click even of the Close button could contain the following code:

THISFORM.RELEASE

Using your class

Once you have built up your class, you can use it to render the services for which it has been built. The availability of the class will allow you to encapsulate business rules and data processing operations. To use the class you have just built, create a form and add four text boxes to the forms names txtEmpID, txtEmpName, txtEmpDept and txtEmpStatus. You can then add four command buttons and name them cmdClose, cmdSave,  cmdRemove and cmdFind. The code to be contained in the click events of all these buttons has been described in the paragraphs above. Simply copy and paste the code for the appropriate events and then run the form.

Conclusion

This article has demonstrated that Visual Class Libraries provide an additional place for you to put code even for pure Fox (that is applications accessing a Visual FoxPro database) applications. The form you have created and your application functionality could have been constructed in so many different ways. For examples, if you are used to data-bound forms that allow users to issue APPENDS or that provide Next/Previous buttons as navigation aids and so on, this could also be done. Part 2 of this aricle will demonstrate techniques that you can use to implement Set based data access in your visual FoxPro desktop applications and how these will aid database availability in high-performance pure fox applications.

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

Article Source:http://www.articlesbase.com/programming-articles/building-and-using-data-aware-classes-in-visual-foxpro-applications-part-1-utilizing-visual-class-libraries-for-data-access-and-business-rules-989318.html

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • NewsVine
  • Reddit
  • StumbleUpon
  • Google Bookmarks
  • Yahoo! Buzz
  • Twitter
  • Technorati
  • Live
  • LinkedIn
  • MySpace
  • StumbleUpon
  • Technorati
  • Twitter
  • Twitthis
  • Yahoo! Bookmarks
  • Yahoo! Buzz
Related Products:

Over one million products online and on sale! Click ad above to browse our site!

You must be logged in to post a comment.

Load time improved by PHP Speedy Load time improved by PHP Speedy