Third Class
Building Data Aware Classes in Visual FoxPro Part 2: Using Data Transports and Temporary StorageAbstract: 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. However, most Visual FoxPro programs, need to provide a means of data capture, retrieval and navigation, which is why a lot of programmers provide selective information navigation buttons (next, previous, last and basi buttons). This is one of the reasons why Visual FoxPro programmers have often plainly added the required tables to the data surroundings of the form or report thus, making the selective information natively available to the form. If Data Access and Validate code is encapsulated in classes, how may data be returned to a form and how may data-bound forms be built? This article seeks to demonstrate that you may build effective, powerful, effective, flexible database apps even altho your data access code is encapsulated in ‘data conscious classes’. This article explores the use of arrays as info transports and Cursors as temporary storage emplacements for forms. Introduction In portion I of this article, it was demonstrated that encapsulating selective information access code and business rules in classes made the code without apparent effort accessible from dissimilar modules in your application and warded off the need to write the same selective information access code repeatedly in dissimilar application forms within your application. Also, communication and info interchange amid the form and the classes was by means of properties (members) of the class. If your application form (user interface) necessitated to save a record developed by the user, the properties (variables or members) of the class were modified with values typed into controls on the form and then the Save method of the class was called. Similarly, when a user necessitated to display an existent record, the EmpID property of the class was altered and the Find method of the class was called to search for the record. When the record was located, the properties of the class (i.e. the object invented from the class) would be modified with the values of the record found so that the form could then display the value of each property in the matching form controls (e.g. text boxes). While this method in general works and may be effective for work with single records in a little system, what happens when you need to return more than one record at a time such as in the scenario described earlier? Could there be an substitute way to pass selective information to a class or return selective information from it? What is faulty with just using properties? To commence with, let us just consider the drawbacks of just using properties only as described! While working in that way is simple and in general works, it has various drawbacks such as the following: 1) Your capacity to procedure more than one record at a time is seriously curtailed because the property variables may hold info for only one record at a time. This means that if you wanted for example to populate a list box on your form, an substitute mechanism would surely be suitable since you have not added any tables to your form’s selective information surroundings (but have delegated all selective information access and retrieval code to your info conscious class), 2) If your application were running in a networked environment, each property you set or retrieve would cause a round-trip on the network (especially if your classes were compiled as automation parts and hosted remotely on a remote machine). How much better it would be to be competent to pass all records to be saved at one time or return all records that you need to use at one time! Not only does this solve the few difficulties itemized above, it scaled down network load and increments data availability…but how? Combining the power of Temporary Storage with effective Data Transports Arrays are selective information storage containers but by using them as Data Transports, you could invent and have effective communications among your front-end (form, report, etc) and your middle-tier (data conscious classes). To get your info conscious class to return data to your form, the class could read the required records into an array that was passed to it as a parameter by reference. Once the array is returned, a cursor (temporary table) could be formulated to store the records returned so that the records could then be employed and manipulated locally. Your form could holds the following code in it is Init event:
LOCAL oE AS Object, lAnswer AS Logical, intRows AS Integer, cMsg AS Character DIMENSION arrE(1,4) && Create the Array oE = CREATEOBJECT(“Employees”) && Create an Object from your class -* Call the GetAllRecs method and pass the array as a parameter lAnswer = oE.GetAllRecs(arrE,intRows) IF NOT lAnswer && Method did not finish successfully cMsg = “Error occurred obtaining employee records!” MESSAGEBOX(cMsg,48,”Test Program”) CANCEL && Abort the form Opening Process…Prevent Form from Opening ENDIF -* Now build the cursor to host the info returned CREATE CURSOR TEmployees (EmpID c(15) UNIQUE, ; EmpName c(50), EmpDept c(10), EmpStatus c(10)) FROM ARRAY arrE The Dimension array gives rise to the array that will be passed to the class to return selective information from the backend table. The array is a two dimensional array where the firstborn dimension represents the number of records in the table and the second dimension represents the total number of fields in the table. The CREATEOBJECT() function develop the object as general and returns to the reference to the object variable oE. The line lAnswer = oE.GetAllRows is the line that calls the method to return info from the class, passing the array you have declared. The CREATE CURSOR line is where the temporary cursor is devised for the form and then hosted locally on the form. Creating the cursor early in the init event of the form allows your selective information to be available for use in the form early on Now that the table records you need are hosted locally, you could work with the cursor just as you could any table by adding new records (APPEND), searching for records in it (LOCATE), or even deleting records in the cursor (DELETE). While these operations were taking place in the Form (front-end), the back-end table would stay available for other users to obtain selective information in incisively the same way (increased data availability). Another way to use this approach would be to bind the fields of the cursor (temporary table) to the matching suitable controls on the Form for ease of navigation (say you wanted to use Next | Last | Previous | First buttons), you could on an individual basis bind each control using code such as:
THISFORM.txtEmpID.ControlSource = TEmployees.EmpID THISFORM.txtEmpName.ControlSource = TEmployees.EmpName THISFORM.txtEmpDept.ControlSource = TEmployees.EmpDept THISFORM.txtEmpStatus.ControlSource = TEmployees.EmpStatuis
To bind the Employee ID text box on your form, we assigned a field of the cursor to the ControlSource property of the sameness control to which we wanted to display the selective information for each field in our initial table. This allows you to directly edit the contents of the cursor by typing selective information into a control on your form. You could then add a Next button and then write the following code in it is Click event:
SELECT TEmployees && Ensure this is the active cursor particularly if you have assorted in your form IF NOT EOF() && We are not yet at end of file SKIP ENDIF THISFORM.Refresh
IF NOT EOF() checks to make sure that we are not at the end of file after which a SKIP moves us one record forward. You could likewise add a Previous button and then add the following code to it is Click even:
SELECT TEmployees IF NOT BOF() && It it not yet End of file SKIP -1 ENDIF THISFORM.Refresh
IFNOT BOF() checks to assure that it is not beginning-of-file after which a SKIP -1 moves backward one record. THISFORM.Refresh ensures that the controls on the form are refreshed with the current record in the cursor. For a Last button, the code to be added to it is Click event could be like the following:
SELECT TEmployees GO BOTT THISFORM.Refresh
The GO BOTT command moves us to the last record in the table. If you decisive to add a First button, you could add the following code to it is click event:
SELECT TEmployees GO TOP THISFORM.Refresh
The GO TOP record moves us to the original record in the table. After making changes to the cached records, you would have to resubmit the records in your cursor back to your class so the changes could then be saved. The click event of such a Save button could integrate the following code:
LOCAL lAnswer DIMENSION arrE(1,4) SELECT TEmployees COPY TO ARRAY arrE lAnswer = THISFORM.Employees1.SaveRecords(arrE) IF NOT lAnswer MESSAGEBOX(“Error occurred saving records!’,48,”Test Program’ ENDIF
The SaveRecords method of the Employees class could then integrate code such as the following:
PARAMETERS arrE,intRows LOCAL intCnt As Integrer, lFileInUse As Logical STORE 0 TO intCnt IF USED(“Employees”) lFileInUse = .T. ELSE lFileInUse = .F. USE Employees IN 0 ENDIF FOR intCnt = 1 TO intRows SELECT Employees GO TOP LOCATE FOR ALLTRIM(Employees.EmpID) = ALLTRIM(arrE(intCnt,1)) IF NOT FOUND() && Record does not exist…create it APPEND BLANK REPLACE Employees.EmpID WITH arrE(intCnt,1) ENDIF -* Save changes to the rest of the record REPLACE Employees.EmpName WITH arrE(intCnt,2) REPLACE Employees.EmpDept WITH arrE(intCnt,3) REPLACE Employees.EmpStatus WITH arrE(intCnt,4) ENDFOR IF NOT lFileInUSe USE IN Employees ENDIF RETURN .T. && Tell user you finished routine successfully
In the code above, the For…EndFor loop ensures that each row of the array is processed. It is a counter. For each row of the array, the program checks in the table to see of the record exists! If it does, changes to the record are saved. If it does not (IF NOT FOUND()), an APPEND BLANK gives rise to a new blank record in the table and the new record saved to the table through the REPLACE affirmations that follow. What if the user had deleted a series of records on the form that will have to also be deleted on the back end table? A similar technique of submitting the list of deleted records could do the occupation rather well! A Delete button on the form could integrate the following code in it is Click even to delete the presently displayed record:
DELETE
You could then add an Apply Deletes button to remove all deleted records at once by adding the following code to the Click even of the Apply Deletes button:
LOCAL intRows AS Integer DIMENSION arrE(1,4) && Create the array SELECT TEmployees && Make the Employees cursor the active work area COPY TO ARRAY arrE FOR DELETED() = .T. && Copy all recs marked for deletion COUNT ALL FOR DELETED() = .T. TO intRows && Count all records marked for deletion lAnswer = THISFORM.Employees1.ApplyDeletes(arrE,intRows) && Call Class method to delete
In the code above, the Copy To Array command populates the array arrE only with the records marked for deletion. The DELETED() function returns true for any records marked for deletion. In order to return the total number of records marked for deletion, the COUNT…TO command is likewise used, qualified also with the DELETED() function to make sure that only records marked for deletion are taken into account in the COUNT command. The ApplyDeletes method of the Employees class is then called, with arrE and intRows passed as parameters to it. The ApplyDeletes method of the Employees class could incorporate the following code:
PARAMETERS arrE,intRows LOCAL cMsg AS Character, lFileInUse AS Logical, intCnt AS Integer intCnt = 0 IF USED(“Employees”) && File is already open lFileInUse = .T. ELSE USE Employees IN 0 lFileInUse = .F. ENDIF SELECT Employees FOR intCnt = 1 TO intRows SELECT Employees GO TOP LOCATE FOR ALLTRIM(Employees.EmpID) = ALLTRIM(arrE(intCnt,1)) IF FOUND() && Record is located DELETE && Mark it for deletion in the back end table ENDIF ENDFOR IF NOT lFileInUse && If we opened the table, close it too USE IN Employees ENDIF RETURN .T. && Tell calling app that you concluded successfully I the code above, the Employees table us opened. The For…EndFor look ensures that each element of the array of deleted records is searched and matched versus the Employees table in the back-end database. If the record is found, a DELETE command marks the record for deletion in the actual table. The Return .T. ensures that the calling application knows that the procedure finished successfully. So much with regards to forms, what with regards to reports? Visual FoxPro Reports also form a part of a finish Visual FoxPro application so that users of your apps may draw out necessitated data for hard copy. Reports are normally built in the Reports Designer and like forms, reports too normally have a data surroundings in which you would have to put the tables and queries that integrate the selective information applied on the report. If we advocate a policy of pooling all info access through info conscious classes and not tightly binding reports and forms to the database, how may we obtain data for reports? Usually, we are required to prepare the data required for a report before running the report. This would mean adding tales or views to the form’s data-environment (what we are advocating against) or using a DO <query> or SQL statement in the Init event of the form or even using a USE command to open the applicable info origins to be employed in the report! In the model we are advocating in this article, we could utilize the power and richness of the Visual FoxPro programming language to assure that we announce an array, pass the array to a method of the data-aware class along with the criteria required and then use the contents of the array returned to build a cursor or table to be used locally! This all could be accomplished in the Init event of the selective information surroundings just as we would have done if we had employed a DO <query> or any of the other methods as described in the Visual FoxPro online documentation (but that would perchance be an article for another day when time permits)! But the point is nevertheless made that the way to obtain selective information for your report from a data conscious class would fundamentally be the same method as you have employed on your form! Conclusion This article demonstrates that you may build windows client apps with Visual FoxPro and increase data availability and application flexibleness by using every-day application features that you already recognise – arrays and cursors to build the most powerful applications. Of course, when you deal with apps in which the user interface is disconnected from the back-end database such as those we have been demonstrating in these series of articles, you will have to write code to handle any selective information conflicts that may arise (e.g. a great deal of other user has just changed a record you want to save or a record that you have likewise amended) and so on. However, the point is made in the article that using Data Aware classes as the bed-rock of your application’s development allows you to discerned the info access tier from your user services (forms and reports) and therefore increments selective information availability. So far, the articles in this series (both the share I and this specific article) have assumed that you are building Visual FoxPro Windows Clients (using Visual FoxPro Forms) to access selective information stored in a Visual FoxPro database. But what if the application database you are required to access is stored in a file format other than the native Visual FoxPro format such as perchance Oracle, Advantage Database Server or Ms SQL Server? Part III of this article series to come soon will explore how you may access powerful Server Databases from your Data-Aware classes!
1970 Press Photo Third class and bulk mail, WW2 Navy Jumper Uniform (Aviation Boatswains Mate-Third Class) USS Yorktown, North Korea 3rd Class Tank Hitter Medal, Rare Catholic 3rd Class Relic Piece of Cloth & Medal From Saint St Philomena, WORLD WAR II TWO-SIDED UNIFORM PATCH ELECTRONIC TECHNICIAN RADIO MAN 3rd CLASS, Mexican Order of Military Merit 3rd class, USSR (Russia): order of Kutuzov (3rd class), USSR (Russia): order of Bogdan Khmelnitsky (3rd class), Mercedes-Benz : R-Class R500 4MATIC 2006 MERCEDES R500 4-MATIC! NAV PANO AMG-SPORT-PKG PDC HEATED-STS 3RD-ROW 6-CD!!, ALBANIAN ORDER OF THE LABOR S/B 3RD CLASS, 1912 BF Goodrich Tire adv cover, Akron, Ohio. 3rd class., U.S. Coast Guard Petty Officer 3rd Class Rank Insignia - Three Sets, YUGOSLAV ORDER OF THE PARTISAN STAR WITH RIFLES, SOVIET MADE, 3RD CLASS NUMBERED, YUGOSLAVIA ORDER PARTISAN STAR 3rd class №8914 USSR Monet.Dvor, Mercedes-Benz : M-Class 3.5L 3.5L SUV AWD Aluminum Wheels Sun/Moonroof 3rd Row fold falt seating Navi, SOVIET UNION RUSSIAN MILITARY NAVIGATOR ENAMEL 3RD CLASS BADGE, 1909 Print White Star Line RMS Adriatic Ocean Liner Third Class Saloon Cruise, USSR SOVIET MILITARY PILOT 3RD CLASS ENAMEL BADGE , WWII German Snipers badge insignia 3rd class-20 kills Ball Cap hat , JAG-Complete 3-Three-Third Season-New Sealed- Free First Class Shipping, US Navy WW II Rank Patch Sonar Technician 3rd Class, USCG Coast Guard Third Class Storekeeper Patch 1950's Korean War Era plus Extra, Cunard Line Postcard Ocean Liner Lancastria, Third Class Multi View 1922 Rare, Mercedes-Benz : E-Class 320, S4, AWD very clean and mechanicaly sound, AWD, CD changer,3rd seat, $4,950 (856)379-7433, Mercedes-Benz : E-Class E320s Wagon W210 *** Wagon ***, Smoke Silver/Tan Leather Interior, 3rd Row seat, CD Changer, Mercedes-Benz : R-Class R350 4MATIC 2006 MERCEDES R350 4-MATIC! NAV PANO-ROOF PDC 3RD-ROW HEATED-STS HK-SOUND 6-CD!!, lot seaman 3rd class, T.S.S. Caledonia - Third Class Deck Plan - 1938 Anchor Line , Rare Catholic 3rd Class Relic Piece of Cloth & Medal From Divine Mercy Jesus, U.S. Navy Uniform Cracker Jack Jumper & 13 Button Trousers 3rd Class Petty , WW2 US NAVY STOREKEEPER 3rd CLASS P.O. RATE PATCH & Other Patch, Bavarian Military Merit Cross 3rd Class with Swords in original case Medal 1866, Rare Catholic 3rd Class Relic Piece of Cloth & Medal From Saint St Peregrine, USN NAVY PETTY OFFICER 3RD CLASS MILITARY WOOD COSTERS, Fleischmann HO 5153 Express coach 3rd class, 4-axled, type C 4ü Pr08 of the DRG , Third-Class Radiotelephone License Handbook: A Revision of Radio Operators..., 32 Third Graders and One Class Bunny by Phil Done, P..., Mercedes-Benz : GL-Class 2010 Mercedes Benz GL550 3rd Row Rear Entertainment Navigation 21 AMG Wheels, Rare Catholic 3rd Class Relic Piece of Cloth & Medal From Saint St Gerard, US Navy Petty Officer 3rd Third Class Pin By Krew Vintage Eagle 1 Bar No Reserve, Navy Rating Patch 3rd Class Boatswains Mate 1944, Third World America: How Our Politicians Are Abandoning the Middle Class and Bet, (27186) 1910 POSTCARD WHITE STAR LINE S.S. "CELTIC" THIRD CLASS TWO MEAL MENU, DDR Rocket Troops Qualification Badge 3rd Class, Yugoslavia/Order Partisan Star 3rd class *small numbering!*, SHOOTING MEDAL 1971 MARKSMAN CLASS 3RD TROY PISTOL LEAGUE, 1944 DATED NAVY AVIATION ORDNANCEMAN (3rd class ), Mercedes-Benz : GL-Class GL450 4MATIC BUY NOW $47,700..LOW MILES 2009 MERCEDES GL450 4MATIC AWD.3RD ROW.NAV.DVDs.4X4, ALBANIA - ORDER RED STAR - THIRD CLASS, SS NORMANDIE 3rd Class Salon B & W Photo Post Card, RMS MAURETANIA II 3rd Class Lounge B & W Photo Post Card, ► 1877 Athens PA 3rd Class License Patent Medicines check revenue tax stamp RNG1, 3rd class Relic medal,Blessed Frederic Janssoone, A U.S. NAVY WWII ERA 3RD CLASS AVIATION CARPENTER'S MATE WHITE TWILL RATE, Märklin COACH - HO - Express Train 2nd/3rd Class Royal Württemberg (4210) - 1548, Märklin COACH - HO - Express Train 3rd Class Royal Württemberg (4211) - 1549, Vestment 3rd class relic medal, EARTH FROM FATIMA, Märklin COACH - HO Gauge - DRG 1st/2nd/3rd Class Interior Lights (4143) - 1543, Märklin COACH - HO Gauge - DRG 3rd Class with Interior Lights (4141) - 1540, Mercedes-Benz : E-Class 320 Wagon MERCEDES E-320 WAGON WITH THIRD ROW SEAT & SUNROOF - low miles, great condition!,
Is a Third Class Bachelors Degree the end of my academic career? Hello all, Masters level courses in general look for students with a 1st or 2.1. PGCE courses that offer Masters modules receive students with 2:2s - but it does limit you to Education based Master's courses. If you live in the UK - most University funding comes from the government with you paying only a little fraction of what is necessitated (will change when fees go up). If a student doesn't finish the course or cannot cope with the course and consequently drops out, then the University will loose percentage of the funding they get from the Government. The Universities, therefore, only want students who are academically capable and bright. Your best choice would be pre-master's course, even though if you've been working in the area you want to do a MA in - then probabilities are that will stand you in good stead to get on the Pre-masters course. It all depends on the University, your personal statement, experience levels and how a lot of people have applied. |







































