home *** CD-ROM | disk | FTP | other *** search
- ***************************************************************************
- ** CHARITY.ZIP
- ** (C) Copyright 1990, Sub Rosa Publishing Inc.
- ** A demonstration application provided to VP-Info users.
- ** This program may be copied freely. If it is used in commercial code,
- ** please credit the source, Sub Rosa Publishing Inc.
- **
- ** This suite of programs provides an actual example of a complete
- ** application, written in VP-Info, the data base language published
- ** by Sub Rosa Pulishing Inc.
- **
- ** This is a demonstration application. Some techniques are
- ** used primarily to enrich the variety of examples used, even if they
- ** would usually not all be used in a single application.
- **
- ** The entire application is compatible with all Sub Rosa Publishing
- ** editions of VP-Info.
- **
- ** Sid Bursten and Bernie Melman
- ** June, 1990
- ***************************************************************************
-
-
-
- Programmers may find it helpful to study an actual application,
- complete with most of the features available to Info users.
-
- Although many additional features could easily be added, this
- example is designed to showcase techniques as simply as possible while
- providing a useful skeleton for real organizations to use.
-
- CHARITY.ZIP should be un-zipped in a hard-disk directory of its own.
-
- It assumes that a charitable organization has a cadre of
- solicitors who canvass the public for pledges of support for the
- cause. Once pledges are received, the charity has to log funds as
- they are received from the donors, keeping information on how many
- dollars are collected on pledges in both the donor and solicitor data
- files.
-
- The application has three data files with the following
- structures:
-
- Data file: DONATE.DBF
- Field Name Type Width Dec
- 1 DONOR C 6
- 2 SOLICITOR C 6
- 3 DATE C 6
- 4 AMOUNT N 8 2
- 5 HOWPAID C 1
- ** Record Length ** 28
-
-
- CHARITY.DOC Page 2
- Data file: DONOR.DBF
- Field Name Type Width Dec
- 1 DONOR C 6
- 2 FNAME C 15
- 3 NAME C 15
- 4 ADDRESS C 30
- 5 CITY C 18
- 6 STATE C 2
- 7 ZIP C 9
- 8 PLEDGE N 8 2
- 9 PAID N 8 2
- 10 SOLICITOR C 6
- ** Record Length ** 118
-
- Data file: SOLICIT.DBF
- Field Name Type Width Dec
- 1 SOLICITOR C 6
- 2 FNAME C 15
- 3 NAME C 15
- 4 ADDRESS C 30
- 5 CITY C 18
- 6 STATE C 2
- 7 ZIP C 9
- 8 PLEDGE N 8 2
- 9 PAID N 8 2
- ** Record Length ** 112
-
- Execution begins with DONMENU, which is built around the MENU(
- function. By selection an option numbered 0 through 9, the user
- selects a free-standing program, a subroutine, a procedure, a report
- form or exit from the program or from Info altogether.
-
- The menu screen and selection is set up with the following
- commands:
-
- WINDOW 1,2,23,77 double ;draw border and force all display inside
- SET date to 'yymmdd' ;default to years first; allows date sort
- SET talk off ;suppress messages like NO FIND
- SET text on ;include display fields in GET TABLE for
- READ
- SET trim off ;do not trim & macros in TEXT display
- SET execution off ;don't re-execute ON FIELD on exit
- SELECT 1
- ERASE
- @ 1,3 SAY date(full)
- @ 3,3 SAY cen(:company,74) ;display company name on menu
- @ 5,3 say cen('Main Menu',74)
- WINDOW 8,25,22,77 blank ;create invisible window to position text
-
-
- CHARITY.DOC Page 3
- TEXT
- 0. Enter Conversational Mode
-
- 1. Enter/Edit Donations
- 2. Enter/Edit Donors
- 3. Enter/Edit Solicitors
- 4. Post Donations
- 5. Report Donations
- 6. Report Solicitors
- 7. Print Labels
- 8. Reindex All Files
- 9. Exit to the Operating System
- ENDTEXT
- WINDOW ;window no longer needed
- SET width to 80 ;restore line width for later text displays
- CURSOR 10,23 ;position cursor for MENU( function
- CLEAR keyboard ;empty type-ahead buffer
- ANS=menu(9,38) ;9 options, with bar 38 characters wide
-
- Note that a bordered window is created to display the menu, along
- with the current date, the company or organization name and the menu
- title. Then an invisible window is created into which the TEXT block
- is positioned. Using WINDOW with the BLANK option is much easier than
- attempting to center text in the program itself.
-
- Once the window is no longer needed, it is canceled, the cursor
- is correctly placed and the keyboard buffer is emptied to eliminate
- characters that may have been inadvertently left over from an earlier
- program. Finally, the user enters his choice from the options given.
-
- Choice zero cancels execution and puts the user into
- Conversational Info, while option 9 exits Info and returns to DOS.
-
-
- Data Entry with TEXT
-
- Option 1 chains to the program ENTRY, which in turn chains back
- to DONMENU when complete. ENTRY edits and adds records in the DONATE
- data file, which contains one record for each payment made. The user
- enters the code number of the donor, which the program uses to
- retrieve the donor's name and address, and the code number of the
- solicitor; the name of the solicitor is then retrieved from the
- SOLICIT data file.
-
- Both donors and solicitors are assigned unique code numbers by
- the computer in options 2 and 3, which enters and edits records of
- these individuals. The code number consists of the first three
- characters of the last name, the first initial, and a two-digit serial
- number that starts at 01 and goes up to 99 as people are added with
- similar names. This method makes it easy to find code numbers, yet
- assures a large number of unique code numbers.
-
-
-
- CHARITY.DOC Page 3
-
- The subroutine DONEDIT is used to add donor records to DONOR.DBF.
- An input screen is retrieved from a library (DONATE.LIB) and is
- activated with READ. All of the functions normally available in EDIT
- are obtained by checking the value of KEY, a system variable
- containing the number of the key used to exit READ.
-
- The TEXT stored as library volume .1:
-
- The prompt box at the top is similar to that provided by EDIT
- with SET MENU ON. Note that double carats (^^) are needed to print a
- single carat on the screen, since carat has a special meaning to TEXT.
-
- .. donor,!!!-!-99
- .. solicitor,!!!-!-99
- .. state,!!
- .. zip,!!!!!!!!!
- ┌─────────────────────────────────────────────────────────────────────────────┐
- │REC: prev <PgUp> next <PgDn> Delete current record ^^U │
- │FILE: top ^^<Home> bottom ^^<End> DELETE: char <Del> to end of field ^^Y │
- │APPEND MODE: begin ^^<PgDn> exit <PgUp> EXIT: with save <End> no save ^^Q │
- └─────────────────────────────────────────────────────────────────────────────┘
-
- Enter or edit donors and pledges
-
-
- Name (first/last)... %fname %name
- Code Number......... #donor
-
- Address............. @address
- City and State...... %city %state
- Zip Code............ @zip
-
- Pledge Amount....... @pledge Paid to date....... #paid
- Solicited by........ @solicitor
- &fname#2 &name#2
-
- This sample uses all four macro symbols. Inputs are indicated by
- @ and %, while display-only fields are indicated by # and &. The @
- and # symbols are used for fixed-position fields, while % and & are
- used for floating-position fields. This TEXT requires SET TEXT ON and
- SET TRIM OFF, both of which are in DONMENU.
-
- FNAME and NAME, and CITY and STATE, use the floating symbols
- since we only want to ensure the fields have a space between them no
- matter how long they are.
-
- Four of the fields require specific format pictures, which are
- given at the top on lines starting with two periods.
-
- Here are the commands that create the code number inside the DO
- WHILE structure whenever a new record is created:
-
-
- CHARITY.DOC Page 4
-
- recnum=# ;store current record number
- finder=!(left(mname,3)+left(mfname,1)) ;build alpha part of code
- finder=replace(finder,' ','*') ;fill in blanks in code with asterisks
-
- FIND &finder ;these 6 lines are equivalent to the LAST command,
- IF #>0 ; although LAST is substantially faster. Essentially,
- LIMIT 4 ; all we have to do is find if a record exists with
- GOTO bottom ; the same 1st 4 letters of the code, and find out
- LIMIT ; what the last serial number is so we can increment
- ENDIF ; it.
-
- The previous 6 lines in Level 1 code can be replaced by the single line
- LAST &finder ;find last matching code in file
- in VP-Info versions which support the LAST command.
-
- IF #=0
- finder=finder+'01'
- ELSE
- num=val(right(donor,2)) ;get number of last matching record
- IF num<99 ;only allow numbers up to 99
- finder=finder+right(str(101+num,3),2) ;increment with leading zero
- ELSE
- finder='******' ;overflow if already 99 records with same letters
- ENDIF
- ENDIF
- GOTO recnum ;go back to original record and fill in name and code
- REPLACE fname with mfname,name with mname,donor with finder
-
- This TEXT has an associated ON FIELD structure, which among other
- things does lookups into the DONOR and SOLICIT data files. Here's the
- section that does it:
-
- IF solicitor<>solicitor#2
- FIND#2 &solicitor#1 ;align file when solicitor code filled in
- IF recno(2)=0
- :field=field(solicitor)
- @ 23,0 say cen('No solicitor found with this code number.',80)
- ELSE
- :field=field(fname)
- @ 23,0
- ENDIF
- ENDIF
-
- The reason the FIND is inside an IF is that it would waste time
- and effort to align the files when they are already aligned.
-
-
-
- CHARITY.DOC Page 5
-
- Posting Totals to a Data File
-
- One of the most useful functions of a relational database system
- is the ability to accumulate totals from fields in one data file into
- another data file.
-
- In this application we want to add up all the pledges and
- receipts for each donor and each solicitor.
-
- The first step is to zero out the totalling fields in the
- respective files. Then an index is set to establish the relation and
- the POST command invoked.
-
- In this application, we've added a complication: limiting the
- records to be posted to donations made within a specified period.
-
- The following commands do the posting, depending on whether
- beginning and/or ending dates are specified:
-
- DO CASE
- CASE finish<'999999' .and. start>' '
- POST on solicitor from donate fields paid with amount for
- date>=start .and. date<=finish
- POST#2 on donor from donate fields paid with amount for date>=start
- .and. date<=finish
- CASE finish<'999999'
- POST on solicitor from donate fields paid with amount for
- date<=finish
- POST#2 on donor from donate fields paid with amount for
- date<=finish
- CASE start>' '
- POST on solicitor from donate fields paid with amount for
- date>=start
- POST#2 on donor from donate fields paid with amount for date>=start
- OTHERWISE
- POST on solicitor from donate fields paid with amount
- POST#2 on donor from donate fields paid with amount
- ENDCASE
-
- An unusual feature of the POST command is the ability (with SET
- ADD ON) to add records to the target data file automatically if no
- record is found to accumulate totals to for unknown or incorrect
- records in the source file. This assures complete posting, since no
- amounts are "lost."
-
-
- CHARITY.DOC Page 6
-
- Reporting
-
- The menu offers two report options. The simpler one merely lists
- all the solicitors in code-number order, with the amounts posted from
- the DONOR and DONATE data files.
-
- The list of donations, however, has two additional features:
-
- A. The report uses two additional related files, so the names
- of both the donor and solicitor can be shown
-
- B. The same date feature mentioned for posting is used, again
- in an ON CASE structure, to optimize the report depending on
- whether beginning and/or ending dates are specified
-
- Printing Labels
-
- There are a number of complexities to printing labels,
- particularly 2 or more across.
-
- Among these is how to handle records with one or more missing
- pieces of data. For example, many small-town residents have only the
- town name as an address; merely printing name, address and city on
- three separate lines would leave a blank line in this case.
-
- The subroutine DONLABEL uses a 3x3 matrix to organize the data
- for up to three labels at once, and a second 3x3 matrix is used to
- print the labels.
-
- The matrixes are created in DONMENU as follows:
-
- DIM char 32 label[3,3] ;matrix for 3-across labels
- DIM char 34 labelout[3,3] ;actual output matrix for 3-across labels
-
- Since Info adds one space between horizontal elements of a
- matrix, LABELOUT has 35 characters between the start of one label and
- the start of the next . . . 3.5 inches as normal printer pitch.
-
- LABEL is about a quarter of an inch narrower; this increases the
- margin between labels to about a third of an inch without changing the
- position of the labels themselves.
-
- DONLABEL is fully commented, and is used to print labels for both
- SOLICIT and DONOR data files.
-
-
-
- CHARITY.DOC Page 7
- Maintaining Indexes
-
- Every application requires not only a set of index files, but an
- easy way of creating and correcting those index files. The indexes
- used in this application are maintained with the following module:
-
- SET talk on ;show progress of indexing...? lines show steps to do
- ? "USE donate"
- USE donate
- ? "INDEX on donor+date to donatdon"
- INDEX on donor+date to donatdon
- ? "INDEX on solicitor+date to donatsol"
- INDEX on solicitor+date to donatsol
- ? "INDEX on date+donor to donatdat"
- INDEX on date+donor to donatdat
- ? "USE donor"
- USE donor
- ? "INDEX on !(name)+left(fname,1) to don_name"
- INDEX on !(name)+left(fname,1) to don_name
- ? "INDEX on donor to don_code"
- INDEX on donor to don_code
- ? "USE solicit"
- USE solicit
- ? "INDEX on !(name)+left(fname,1) to sol_name"
- INDEX on !(name)+left(fname,1) to sol_name
- ? "INDEX on solicitor to sol_code"
- INDEX on solicitor to sol_code
- SET talk off
-
-
- Compiling the Application
-
- This application has only two separate programs, although one
- consists of several files.
-
- The following program is used to compile the programs in this
- application, and immediately execute the menu program
-
- COMP entry
- COMP donmenu
- CHAIN donmenu
-
-
- Summary
-
- If this were created for a real customer, instead of as a
- demonstration, a number of additional features would probably be
- added.
-
-
-
- CHARITY.DOC Page 8
- For example, the three data entry programs -- ENTRY, DONEDIT, and
- SOLEDIT -- should probably allow users to change the current index,
- find records based on the current index, and switch between BROWSE and
- EDIT as shown in the demonstration program EDBROW included on the Info
- distribution disk.
-
- Since ENTRY and DONEDIT require the user to enter records by
- donor and solicitor code numbers, it would also be useful to give
- users a way to BROWSE those data files to check the code numbers.
-
- There are several additional reports that would be useful,
- including the ability to limit the report to specific solicitors
- and/or donors, or groups of them. Rather than extend the list of
- reports on the main menu, creation of a separate program with its own
- menu of reports would be preferred.
-
- Charities have to produce receipts to donors, donor cards for
- collectors, solicitation cards for solicitors, and solicitation
- letters for the next campaign. All of these functions can easily be
- done in one program using TEXT for output processing to the printer.
-
- You are invited to run this application, and make these and other
- improvements as a way to improve your programming ability in Info. By
- the time you have one complete application under your belt, you're a
- genuine Info expert!
-
- Good luck.
-