home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1996 February
/
PCWK0296.iso
/
sharewar
/
dos
/
bazy
/
easybase
/
pack1.prg
/
EBOUT
/
EB2.REP
< prev
next >
Wrap
Text File
|
1995-08-04
|
176KB
|
4,856 lines
EASY BASE USERS MANUAL
══════════════════════
Contents
────────
System Overview.............................. 1
Data Management Principles................... 2
Form Design.................................. 6
Relationships and Lookups.................... 11
Data Entry................................... 15
Procedures (Reporting)....................... 20
Procedures (Transactional)................... 36
User Menus................................... 39
External File Access......................... 43
Data File Format............................. 45
System Requirements and Limitations.......... 46
DOS Filename Convention...................... 47
Selected Programming Topics.................. 49
Easy Base is copyright (c) John Turnbull 1994 published by:-
Easy Software Tel/FAX (044) (0) 1625 614669
3 Brookside Court CIS 100410,717
Prestbury Road
Macclesfield
SK10 3BR
UK
................................................................................
TERMINOLOGY
═══════════
Field The storage space for an individual data item.
─────
Record A set of related data items.
──────
Form The storage space for a set of records.
────
Procedure A set of instructions which manipulate the data
───────── stored in forms.
Relationship A record in the relationships form recording
──────────── a link between forms.
................................................................................
EASY BASE SYSTEM OVERVIEW
Easy Base is a complete rapid programming system for data
management. Virtually every data management problem can be
broken down into three areas. Creating disk files (referred to
as "Forms" in Easy Base) in which to store data, creating
procedures which manipulate that data and presenting those
forms and procedures in a logical menu system for use.
In Easy Base you create the forms in which to store data in a
simple screen-painting environment which not only designs the
data file but at the same time provides a default data entry
screen for your data. As you place the "Fields" in which data
is to be stored you can use relational links ("Lookups") to
import data from other forms. Each field you create for data
storage is also treated as a deriveable "Cell" similar to a
spread sheet. You can make almost any calculation or derivation
within a field as, apart from all arithmetic, relational and
logical operators, Easy Base also provides a set of over fifty
functions covering everything from Modulo arithmetic to
spelling out dates. Once you have created your forms you can
use the default screen to enter and view your data using the
"Data Entry" system.
Once you have data stored you will need to be able to
manipulate it and report on it. Easy Base provides a combined
transaction and reporting system ("Procedure Generator"). With
the procedure generator you can use the default screens you
have designed or create custom screens in which to gather input
either from the keyboard or from relational Lookups. You then
instruct Easy Base what to do with this information using a
simple "Basic" like programming language. If your procedure is
transactional you have commands to enter, modify or delete
records in any number of forms within a single procedure. If
your procedure is reporting then there are commands to group,
order and list data in almost every conceivable way.
You now have all the "Parts" required to create a useful data
management program. All that remains is to tie your procedures
to a menu system so that other people can use your application
without having to know anything about Easy Base. Creating an
end user menu system in Easy base is as simple as filling in a
form with the text you wish to display and the procedure or
form you wish to run. You give at least one of your menus a
start up password. If you then restart Easy Base but sign on
with that password instead of your developers password then you
will be running your own custom designed program.
- 1 -
................................................................................
DATA MANAGEMENT PRINCIPLES
In Easy Base, creating forms and entering data is very easy.
You will be tempted to rush on and create programs for yourself
without reading the "Bumf". However, unless you are an
experienced data programmer, you should at least read this
section and the one on Relationships before embarking on any
serious project.
The crux of data management is "Data Integrity" or "Data
Verification". You might know that "A Smith", "Smith's Garage"
and "Smith and Son" are all the same customer of yours but your
computer definitely does not! If you have a small business you
might wish to use Easy Base to create invoices - you might be
tempted to start by creating an invoice form in which you enter
your customers name, work done and price. - DON'T - Start
instead by creating a form to hold each of your customers'
names, addresses, credit limit etc. If you sell things then
create a form to hold each of your stock items with their name,
partno, price etc. These are your "Core" data forms from
which you "Lookup" data for other purposes. Each of your "Core"
data forms has a "Unique" field which defines the record as an
entity. "Smith's Garage" will always be "Smith's Garage" and
the lookup function described later will not allow any other
representation to be entered.
Although of less significance than "Data Integrity", the names
which you give to forms and fields are very important and worth
mentioning now. When you come to write "Lookup" derivations and
later, Procedural code you have to refer to your data by a
combination of its form and field names. Please give
considerable thought to the names you use. Each name should be
short but fully describe the form or field. The names of forms
should be plural and the names of fields singular. For example
- a form which is to hold details of your customers should be
called "Customers", the name field should be called "Name" and
the credit limit field should be called "Creditlimit" . When
you need to lookup data from this form the lookup function will
be written - Lookup(customers,name) and when you write
procedures the data will be referred to as customers.name ,
customers.creditlimit etc. If you did not follow this naming
convention and called the form "F1" , the name field "customer"
and the credit limit field "Max cred" then writing procedure
code would be extremely frustrating.
It is equally important to give the same name to fields which
hold the same data in different forms. If you already had a
form called "Employees" which had fields "Worksno", "Name",
"Address" and "Taxcode" and you then created a "Payslips" form
the fields which hold the employee's name and taxcode should
also be called "Name" and "Taxcode". This not only makes it
easier to remember field names but when you come to write
- 2 -
................................................................................
procedure code, data can be transferred between one form and
another with the command "Copy all from". This command only
transfers data between fields with the same name. If you have
given different names to the fields in the two forms you will
have to transfer each individual field separately.
The fields which you create are of four general types - The
definition (unique) field, grouping fields, ordering fields and
descriptive fields.
When you create your "Core" data forms it will be fairly
obvious which is the definition field. In the "Employees" form
"Worksno" defines the record. In a "Manufacturers" form "Name"
defines the record. As a general rule, each form should have a
definition field. There is an exception to this where a form is
used to store temopary lists (described later) but for the
moment you should expect to have a definition or "Unique" field
on each form to prevent duplicate entries. When you create
secondary forms which lookup data from your "Core" forms the
data which defines the record as an entity will not necessarily
be contained solely in one of the fields you wish to display.
As an example - A magazine wholesaler has two "Core" forms, one
containing details of the magazines he supplies and one
containing customers details. He creates a form on which to
record orders from his customers. This "orders" form has three
fields, "Name"(for the customer), "Magazine" and "Quantity".
When a customer phones in an order for a particular magazine
the wholesaler will need to be warned if this particular
customer has already ordered this particular magazine but no
one field defines the record. In fact the record is defined as
unique by a combination of the two fields "Name" and "Magazine"
In this case, a fourth field should be added to the form in
which the two fields "Name" and "Magazine" are combined using
the "jointext" function. This field is then the "Unique" field
and no duplicate entries will be allowed.
In many secondary forms the records definition will be even
less obvious but if you are to create data storage for flexible
reporting you should always attempt to create a suitable
"unique" field.
For example :- An "Aircraft" form has a field "Manufacturer"
which is looked up from a "Manufacturers" form. It also has
fields for "Name" and "Mark". The definition of an aircraft is
what it is known as. If it has a name then it is known as a
combination of the manufacturer and the name (Supermarine
Spitfire) but if it does not have a name it is known as a
combination of the manufacturer and mark (English Electric P1b)
Even in these more complicated situations you can still create
a unique field to prevent duplicates. In the above example you
would create the unique field "Knownas" and derive it with the
- 3 -
................................................................................
formula - Jiontext(manufacturer,if(name = blank,mark,name))
When you define a field as unique Easy Base automatically
indexes this field.
The second type of field is a "Grouping" field. This is a field
which will be used in procedures to select subsets of records.
In the "Aircraft" form you might add a field "Type" which would
qualify each record as belonging to a group - "Fighter",
"Bomber", "Transport" etc. Grouping fields should also be
defined as indexed and should always be subject to data
integrity checking. Where the number of groups is small (17 or
less) Easy Base provides a quick method of data verification in
the "Choice" field type. If the number of groups is larger than
17 then you should create a "Core" form to hold the group names
and look them up into the secondary form.
The third type of field is used for ordering data. In many
instances the order in which you wish to print or view data
will be that of the definition field or one of the grouping
fields but not always. In the "Aircraft" form you might wish to
list them by the dates they were first introduced or by the
total production runs. In order to do this you would have to
add fields for "Date" and "Production". You would later write
procedures to list the aircraft with "Date in order" or
"production in order". Ordering fields should also be indexed
but they need not necessarily be checked for data integrity.
Fields which are not used for ordering or grouping are
descriptive and need not be indexed or integrity checked.
One of the most common mistakes made by beginners to data
management is to create different forms for the same data.
With the "Aircraft" form above you might be tempted to save all
the military aircraft of World War 1. Later you might create a
second form for the aircraft of World War 2. This would be a
mistake. The data you are recording is "Aircraft". The era to
which they belong should simply be another "Grouping" field.
If having saved your data you were asked for a list of all
"Boeing" military aircraft showing which wars they were used in
then this could be achieved with one simple procedure if they
were in one form but would be rather more difficult if they
were in two.
That example was fairly obvious but on many occasions it will
be easy to assume that two or more sets of data are separate
when in fact they are simply groups of the same.
Should you decide to write your own accounting program (Which
is not as daunting a task as it might seem on the surface) You
might be tempted to create forms for a Sales Ledger, Nominal
Ledger and Customers Accounts. In fact the entries in the
- 4 -
................................................................................
Nominal Ledger and Customers Accounts are simply sub groups of
the entries in the Sales Ledger. Provided that you include
grouping fields for the customers account number and nominal
account name you can construct customers and nominal accounts
when required by extracting and totalling the sub sets. There
is no need to save them as separate data.
The final problem you will encounter when deciding how to store
data is that of "Related Lists". Consider the "Aircraft" form.
If you had a grouping for "Airliner" you might wish to record
all the airlines which operate each aircraft. You cannot just
add fields to the "Aircraft" form - One airliner might only be
operated by one airline and another might be operated by fifty.
To store this data you need another form let's call it Userlist
with fields "Aircraft" , "Airline" and "Uni" which is the
unique field derived by joining the other two. The "Aircraft"
field is looked up from the "Aircraft" forms unique field
"Knownas" and the "Airline" field is looked up from the
"Airlines" form "Name" field which is also unique.
In this form you enter one record for each combination of
aircraft and airline. When you come to report on your data you
can list single records from the main "Aircraft" form together
with all related records from the "Userlist" form.
...................PROCEDURE CODE.............
declare output fields
aircraft.knownas : Aircraft.production :aircraft.seats
userlist.airline
end
for aircraft with knownas = input.knownas
print formfields
for userlist with aircraft = aircraft.knownas
print userfields
next
next
...................FORMAT.....................
.formfields
{ Aircraft.knownas field }
Production { Prodn. field} Seats {Seats field }
Operated by :-
.userfields
{ Userlist.Airline field }
.end
- 5 -
................................................................................
FORM DESIGN
To start designing your forms select "Form Design" then "Design
new Form" from the menu system. You are presented with a blank
form. Each form has four pages. To move from one page to the
next use the PgDn and PgUp keys. To move the cursor around on a
page use the arrow keys. Designing your form is a bit like
designing a form on paper. If you were to type on a paper form-
Name .................
Address .................
.................
.................
.................
Then in Easy Base you type Name and Address as above but
instead of typing the dots you define fields for the data to be
entered to.
Easy Base provides several facilities for "Polishing" the
presentation of your forms and these are covered first before
moving on to field definition.
If you wish to enclose your text within boxes or in some
tabular format Press F3 and select "Line Drawing". To draw
lines on the screen hold down the Alt key, The Ctrl key or both
and drive the cursor around with the arrow keys. The Alt key
draws double thin lines, the Ctrl key draws single thin lines
and a combination of both draws a thick single line. Press Esc
when you are finished line drawing to return to normal editing.
If you wish to shade areas of the screen then again press F3
and select "Shading". Shading works much the same as Line
Drawing.
If you require Greek, Mathematical or International characters
which cannot be typed directly from the keyboard then press F3
and select either "Greek and Mathematical" or "International" A
menu of all such characters provided by your PC will appear.
The one you select is printed to your form at the cursor
position.
If you wish to use other than the default text colour then
press F4 after you have typed your text. In each Easy Base
screen colour set you can select one of two alternate text
colours or "Blink" - choose 1, 2 or 3 . To change the colour
of your text or lines just hold down the shift key and drive
the cursor over the text you want to change with the arrow
keys. Press Esc when you have finished colouring your form.
Text input in the form designer has "overtype" as the default.
If you wish to move text (or fields) to the right press the
- 6 -
................................................................................
Ins key. Insert mode is indicated by a block cursor and
Overtype by an underscore cursor. (This is the opposite to all
other editors in Easy Base as it keeps the underscore cursor as
the default)
To insert a blank line above text or fields press F1. You
cannot scroll text or fields between pages in form design.
If you need to move areas of your form then press F9, shade the
rectangle you wish to move and move it around with the arrow
keys. You can also transport the rectangle between pages with
the PgUp and PgDn keys. F9 can also be used to erase areas of
the screen.
When you are ready to define the data fields, position the
cursor where you want the field to start and press F10.
A window opens into which you enter all the attributes for the
field.
The first attribute is "Field Name". If you have typed text to
the left of the field then Easy Base will have inserted this as
a default in the Field Name attribute. If it's not the name you
want just edit it. When you are happy with the field name press
return or the down arrow to the "Data Type" attribute. A menu
appears with the nine different field types. (The field types
are described fully in the Programmers Reference)
When you have chosen a field type the cursor automatically
moves down to the "Field Length" attribute if you have chosen
"Text", "Integer", "Fixed Point" or "Floating Point" and to the
"Mandatory Entry" attribute if you have chosen one of the
others. Enter the field length you require in characters. If
you have chosen "Fixed Point" as the field type there are two
entries, one for the digits left of the decimal point and one
for the digits right of it. If your field is to hold a currency
value then the second entry will of course be 2.
You must supply values for the first three field attributes.
The others all have preset defaults so you can save your field
at this point if none of the others have to be changed.
The next Field Attribute is "Mandatory Entry" which has a
default of "No". You can set this to "Yes", "No" or "If". If
you set it to "Yes" then Easy Base will not allow a record to
be filed with this field left blank. If you set it to "If"
then the "Code Snippet" editor opens up and you can enter the
condition under which an entry becomes mandatory. If you were
designing a "Payments" form and one of the fields "Paymethod"
could be filled with either "Cash" or "Cheque". Then the field
"ChequeNo" would have to be filled only if the "Paymethod"
field had "Cheque" entered in it. To make an entry mandatory
- 7 -
................................................................................
in the "Chequeno" field only if "Paymethod" is "Cheque" enter -
paymethod = "cheque" in the Code Snippet editor.
When you use the Code Snippet editor for Mandatory Entry and
for User Entry, only the condition is entered :-
total < 100
name = blank
length = blank or breadth = blank
the "if" is assumed.
If you set the "Mandatory Entry" attribute to either "Yes" or
"If", a window will open into which you can type the message
which you wish to be displayed should an attempt be made to
file a blank entry. If you leave the message blank Easy Base
will supply the default message "This field must be filled !".
The next attribute is "Unique". This can be set to "Yes" or
"no". You can only have one unique field on a form. If you
have already defined a field as the unique field and you change
your mind and define another then Easy Base will automatically
cancel the unique attribute on the first field. Indexing is
automatically set to "Yes" for the unique field.
The next attribute is "Indexed". Select "Yes" or "No"
When you set "Index" to "yes", Easy Base Creates a separate
"Index" file in which the contents of the field are kept in up
to date order. Index files are used by Easy Base in exactly the
same way that you would use an index in a book to find things
quickly.
The next attribute is "User entry". This has a default of
"Yes" but can be set to "No" or "If". If you set this
attribute to "No" then the cursor will not visit the field
during record entry so the user cannot alter its contents. You
would normally set this to "No" if the contents are derived or
calculated from the values of other fields. You can set this
attribute to "If" if the value entered in another field makes
this one superfluous. For example, in the "Aircraft" form, if
you had a field "Passengers" and the type had been entered as
"Fighter" there would be no point in the cursor moving to the
"Passengers" field. When the Code Snippet editor opens you
could type:-
type = "Transport" or type = "Airliner"
The next field attribute is "Display". When the cursor
reaches this attribute a menu appears with the seven different
ways in which the field can be displayed.
- 8 -
................................................................................
The field display attribute settings have the following
meaning.
1. FIELD
The field's size is displayed as a block which shows
up against the screen background.
2. TEXT
The field size does not show up against the screen
background and the contents are in the default text colour.
3. 1ST ALT COL.
As Text but with the contents in the first alternate colour
4. 2ND ALT COL
As Text but with contents in the second alternate colour.
5. BLINKING
As Text but the contents blink.
6. INVISIBLE
Neither the size nor the contents can be seen.
Invisible fields are used to hold compound index fields and
the results of intermediate calculations which the user
need not see.
7. CODEWORD FIELD
The size of a codeword field shows against the screen
background but its contents are masked by stars.
Codeword fields are used to collect passwords for
restricted menus or procedures. An onlooker cannot see the
password which is being entered.
The final field attribute is "Derived". If you set this to
"yes" then the Code Snippet editor opens and you can enter the
formula by which the fields contents are to be derived.
In the Code Snippet editor you can enter almost any derivation
formula. Formulae consist of field names operators and
functions.
price * markup
VATon(net,vatrate)
datetext(system date)
if(sex = male,"Mr","Ms")
- 9 -
................................................................................
All the operators and functions are fully described with
examples of how they are used in the Programmers Reference.
If in the Code Snippet editor you cannot remember a field or
function name then Press F1 for the reminder lists.
There is a cut and paste facility in the Code Snippet editor.
To mark text hold down the shift key and move the cursor with
the arrow keys. When you release the keys the "Cut" or "Copy"
choice will appear. To paste text, position the cursor at the
insertion point and press Shift + Ins. Text which is cut or
copied from the derivation of one field can be pasted into the
derivation of any other field in any other form.
When you have finished entering the field attributes press F2
to save the field. When you have defined all the fields press
F2 to save the form.
There is one other facility in the Form Design editor. If you
press F5 at any time you enter "Derivation Test Mode". In
derivation test mode you can enter data to your fields and
check if your derivations work correctly. Any fields which you
have defined as invisible are not hidden in test mode. The
main advantage of test mode as opposed to testing in Record
Entry comes not when you are designing new forms but when you
wish to modify one after you have saved many records in it. If
you add, delete or alter the length of a field then the entire
data file has to be reformatted and this takes time. With
"Derivation Test Mode" you can ensure that the modifications
you have made are correct before reformatting.
The only exception to test mode is if you have added a new
lookup function and you have not yet entered the relationship.
If you select test mode with a relationship missing you will
get an error message and be returned to Form Design.
When you save your form Easy Base tests it in derivation test
mode before saving. If it cannot find a relationship you will
be given an error message and offered the choice to remain in
Form Design (which you would do should you know that the
relationship exists and you must therefore have mistyped a
lookup formula) or to save and go to the relationships form
Which you would do if the relationship had not yet been
entered)
If you opt to go to Relationships Easy Base will transfer you
to the relationships form and back again via a macro.
- 10 -
................................................................................
RELATIONSHIPS AND THE LOOKUP FUNCTION
In Easy Base the Lookup Function together with pre-recorded
relationship links provide two of the most important facilities
of a data management system.
1. Reuse of previously entered data.
2. Verification of text data.
Consider the situation where you have designed a form to hold
information about your business's customers. The form has an
"accountno" field which has been derived as "Sequence" and this
is therefore the "Unique" field on the form. It also has
fields "Name" and "Address". All your customers have now been
recorded in this form. You now want to create an invoice form.
Each invoice issued will have to have a customer's name and
address entered on it. All the names and addresses are already
filed in Easy Base so they do not have to by typed again.
Provided that Easy Base knows which customer's name and
address is required it can copy it automatically from the
"Customers" form to the "Invoice" form.
The way in which Easy Base accomplishes this is exactly the
same as you would accomplish the task manually in a hand
written system. If you knew where to find the book in which
your customers names had been written and you knew the
customers account number then you could find the customers name
and address.
The only slight difference for the computer is that while you
would consider it "Obvious" that the account number on the
invoice would be the same as the account number in the
addresses book your computer does not - You have to tell it.
To tell Easy Base where to look and that the "accountno" is the
link, you enter a record in the "Relationships" form.
When you select "Relationships" from the main menu you will see
five fields to be filled. The first field is the name of the
form which data is to be copied to. In this case you will enter
"Invoices". You will notice that easy base has displayed a
list of all your form names and that you must choose one. You
cannot enter the name freehand. This "internal" data
verification is the same as you will be doing for your own data
later.
The second field is for the name of the form in which the data
can be found. In this case select "Customers".
The next two fields record which fields in the primary and
secondary form hold the "Linking" data. In this case select
"acountno" in both.
- 11 -
................................................................................
The final field is the name of the relationship record. You
will notice that Easy Base has already entered a default name
of "Customers". The relationship name can be anything you like
but as the "Lookup" function which you are about to use quotes
the relationship name as its first parameter and the field to
be copied as its second then Lookup(customers,name) has to be
more meaningful and easy to remember than any other name you
could give.
When you have entered all the fields press F2 to save the
relationship, return to Form Design and load your "Invoice"
form.
All that remains to do now is edit the field attributes of the
"Name" and "address" fields. To edit a field you can either
press F10 with the cursor on the form background and select the
field to edit by name, or you can position the cursor within
the field you wish to edit and then press F10, in which case
the field attribute window will open automatically. Position
the cursor in the "Name" field and press F10. Move the cursor
to the "Derivation" attribute and set it to yes. (you can move
the cursor from the "Name" attribute directly to the "Derived
attribute by pressing the up arrow)
When the Code Snippet window opens type -
Lookup(customers,name)
and press F2. If you had not already done so then set the
"User Entry" attribute to "No".
Press F2 to save the new field attributes and then do the same
for the "Address" field, this time entering the derivation -
Lookup(customers,address)
To test that you have typed the lookups correctly press F5 for
Derivation Test Mode. Enter a customers account number in the
"Acountno" field and press the return key. If your formulae are
correct the customers name and address will appear in the
"Name" and "Address" fields.
In this example you have performed two "Secondary" lookups.
Both the "Name" and "Address" fields were found using the
"accountno" link which you had to enter correctly in order
to find the other two fields.
The real power of the Lookup function is only realized when you
perform "Primary" and "Secondary" lookups. In a "Primary"
lookup the field whose value is to be looked up is also the
"Link". It is "Primary" lookups which are used for data
integrity checking.
- 12 -
................................................................................
Consider the "Aircraft" and "Manufacturers" forms which were
discussed earlier. Suppose that you want to lookup the
manufactures name and the name of his base airfield into the
"Aircraft" form. The definition field in the "Manufacturers"
form is "Name" - There is no handy "accountno". You are going
to have to enter a relationship between "Aircraft" and
"Manufacturers" linking the two fields "Manufacturer" in the
"Aircraft" form with "Name" in the "Manufacturers" form.
Having done this you could derive the "Base" field in the
"Aircraft" form with - Lookup(manufacturers,base) - and it
would be looked up when you entered the manufacturers Name just
as in the invoice example. But what of the "Manufacturers"
field itself. Was the name you entered in the manufacturers
form "A.V.Roe", "A.V.Roe & Co." or "AVRO A/C Co.".
Easy Base provides a simple solution to this problem.
Having entered the relationship, return to Form design and
enter the lookup derivations. Derive the "Base" field with -
Lookup(manufacturers,base)
and the "Manufacturers" field with
Lookup(manufacturers,name)
This time, leave the "User Entry" attribute set to "Yes" in the
"Manufacturers" field.
Press F5 for "Test mode". When the cursor enters the
"Manufacturers" field type - AV* - and press return.
Provided there is only one manufacturer whose name begins with
"AV" the Avro name will be looked up into the "Manufacturers"
field and its representation will always be exactly the same as
the original entry in the "Manufacturers" form. If there are
several manufacturers whose names begin with "AV" then a menu
will appear listing all of them and you can choose the one you
want. As soon as you select the name the secondary lookup
"Base" will fill automatically.
If you cannot remember the first letters of the name you want
to look up - say for example that you could only remember that
"Roe" was in the name - then type Roe* and press return. If
any manufacturers names begin with "Roe" they will be displayed
first. If not Easy Base will fill the "Manufacturer" field with
the first name it finds with the letters roe in it. If this is
not the one you want press F3. Each time you press F3 Easy
Base will find the next name containing the letters until you
find the one you want. As a final resort - if you really
can't remember what you are looking for - just enter an "*" on
- 13 -
................................................................................
its own and press return. Easy Base will then list all the
manufacturers names for you to choose from.
There is no limit to the number of secondary lookups which can
be made from each primary and there is no limit to the number
of different forms you can look data up from.
If you have many different forms which all look up data from
the "Customers" form then they can all use the same
relationship name "Customers" but if you have more than one
relationship between the same two forms then they must have
different names.
If you had a "Stock" form with the unique field "Item" and
another field "Price" then you could add four fields to your
"Invoice" form - "Item", "Quantity" "Price" and "Total".
You would enter a relationship "Stock" between "Invoice" and
"Stock" with the related fields being "Item" in both forms.
In your invoice form you would derive :-
Item as Lookup(stock,item)
Price as Lookup(stock,price)
Total as quantity * price
When you entered the "Item" field (primary lookup) the price
field would fill automatically and when you entered the
"Quantity" the "Total" field would be calculated.
However, if you now add four more fields "Item2", "Price2",
"Quantity2" and "Total2" you will need another relationship
between "Invoice" and "Stock" this time linking "Item2" in the
"Invoice file" with "Item" in the stock file and you cannot now
use the default name "Stock" for the relationship.
Although you can give your additional relationship any name you
like, the best name will be "Stock2".
Please note that this example is used purely to show the use of
multiple relationships between the same two forms. If you are
intending to write an invoicing system then unless you know
that there will only be a limited number of items on each
invoice this is not a practical way to tackle the problem.
In a flexible invoicing system each item and quantity is
entered via a procedure to a temporary list form whose contents
are then printed to the invoice.
From V9 the lookup function also accepts a third parameter with
which you can specify the display of a field other than that
which is being looked up. See "Lookup" in Programmers Reference
- 14 -
................................................................................
DATA ENTRY
As soon as you have designed forms you can enter and view data
directly using the default screen you created. To enter data
to a form select "Data Entry" from the main menu and choose the
form you wish to use.
Your default entry screen will appear with the cursor in the
top left field. The top line of the screen shows the name and
page number of the form you are using together with the system
date and time. Line 2 shows the number of the record you are
creating or editing on the left hand side. It is also the line
on which any error messages are passed. The bottom line lists
the most used function keys and is also the line on which help
prompts are displayed.
To move the cursor around between fields you can use all of the
cursor control keys which work as follows:-
The Return key moves from field to field in the order top left
to bottom right unless you have overridden this in form design
by deriving fields with "Goto (fieldname) Next".
The Tab key moves the cursor from field to field in the order
bottom right to top left (reverse of Return).
The arrow keys move the cursor in the direction indicated.
The Home Key moves the cursor to the beginning of the current
field if it is not already there and to the first field on the
page if it is.
The End Key moves the cursor to the end of text if it is in a
text field and to the last field on the page if it is not.
The PgUp and PgDn Keys move between pages if your form has more
than one.
When you have entered the data for your first record press F2
to save it to disk. The screen will clear, the message "Record
1 has been added" will appear briefly on line two and you will
be ready to enter the next record.
If some of your fields are primary lookups then you use them
exactly the same as was described for "Derivation Test Mode" by
entering part of the text followed by a star and pressing the
Return Key.
Once you have saved a few records to disk you may wish to view
or edit them. You can bring previously entered records back to
the screen for editing in several ways. From record creation
the F5 Key brings up the first record and subsequent presses
- 15 -
................................................................................
bring up the next record. Similarly, from record creation the
F4 Key brings up the last record and subsequent presses bring
up the previous record.
Once you have entered several records this process becomes
impracticable and you "search" for the record you wish to view
or edit. Position the cursor in any field and type part of the
field contents you wish to search for followed by a star and
press F3.
Searching for records within a form is a similar process to
looking up data except that you press the F3 rather than the
Return Key to initiate the process. If the field in which you
are searching is indexed and more than one record matches the
data you have entered then Easy Base will make a list of all
the field contents which match for you to choose from. If the
field is not indexed then Easy Base will bring up the first
record it finds a match in. If this is not the record you want
then press F3 again. Easy Base will find another match on each
successive press of the F3 key until you find the record you
want. As with lookups, Easy Base will search for "Part Matches"
after it has exhausted all the records where the entered data
matches the beginning of the field and if you enter a star on
its own and press F3, Easy Base will list all the field
contents for you to choose from.
When you have brought a previously entered record back to the
screen you will notice that line 2 now displays "Editing Record
x of y " rather than "Creating New Record x ". Easy Base
automatically changes from "Create" to "Edit" mode when you
view a record. The changes which you make on screen are not
entered to the record on disk until you press F2.
To clear the contents of the field in which the cursor lies
rather than delete each character press F6. To return to
"Create" mode press F6 twice.
Not all of the active function keys are listed on the prompt
line. To see a full menu of the function key uses press F1 for
the Function Key Menu. The following is a summary of the
function key usage in Data Entry:-
F1
The F1 Key brings up the function key Menu.
F2
The F2 Key writes a new record from "Create" and updates the
record on screen from "Edit" mode.
- 16 -
................................................................................
F3
The F3 key initiates searches for previously entered records
based on the data entered in the current field.
F4
The F4 key moves to the previous record when in "Edit" mode and
to the last record from "Create" mode.
F5
The F5 Key Moves to the next record when in "Edit" mode and to
the first record from "Create" mode.
F6
The F6 key clears the current field on the first press and
returns you to "Create" mode on the second press.
F7
The F7 key deletes the record currently on screen in "Edit"
mode. When you delete a record with the F7 key it is not
actually erased from the disk. It is simply "Flagged" for
deletion at the next "Pack" operation. If you delete a record
accidentally you can reinstate it any time before the form is
next packed.
F8
The F8 key creates a new record by copying the record currently
on screen. If a new record you wish to create contains similar
data to one already entered then you can find the previous
entry, change the unique field and copy it with F8 rather than
type it all again.
F9
If you know the number of the record you wish to view or edit
you can press F9 and enter the record number. Easy Base will
then bring the record whose number you have entered to the
screen.
F10
When you press the F10 key Easy Base searches for records which
are "Flagged" for deletion. When it finds one it will bring it
to the screen. You can reinstate a deleted record by pressing
F2 while it is on screen. The F5 key searches for the next
deleted record and the Escape key returns you to "Live
Records".
- 17 -
................................................................................
F11
If you have been viewing records and you wish to return to one
which you had on screen earlier then press F11 and Easy Base
will back step through the records you have viewed.
F12
The F12 key brings up the form's "Options". There are four
options in Data Entry.
1. Clear screen on Adding Record. (Default Yes)
2. Confirmation Required to delete Records. (Default Yes)
3. Confirmation Required to abandon Edits (Default No)
4. Clear Field on Editing (Default No)
If you change "Clear Screen on adding Record" to "No" then,
when you press F2 to file a new record, the data which is
written to disk remains on screen ready for the next new
record. This is useful if you are entering several records and
many of the fields in each record contain the same data. You
only have to overwrite the fields which are different each
time.
If you have many records to delete then set option 2 to "No"
and you will be able to delete them without having to confirm
each one.
If you set option 3 to "Yes" then Easy Base will ask you to
confirm that you wish to leave a record which you have edited
but not updated to disk.
If you set option 4 to "Yes" then Easy Base will clear the
old contents of any field you start to edit. This is most
useful when used in conjunction with option 1. You can file a
record, retain the contents for the next record and when you
edit the fields which are different you do not have to first
delete the data in them.
The options you set for any given form remain with it until
changed. They do not revert to the defaults when your computer
is turned off and each form can have different option settings.
Ctrl + E
If you press the "E" key while holding down the Ctrl key you
will get the extended "Greek" and "International" characters
menu which was discussed in form design.
- 18 -
................................................................................
Ctrl + S
If you press The "S" key while holding down the Ctrl key you
start the Spell-checker. The Spell-checker will check the
current field. If it finds a word not included in the Easy base
dictionary it will offer you the choices to leave the word and
continue, add the word to the dictionary, or choose one of the
suggestions for replacement.
The Spell checker does not automatically move from field to
field but once you have started it, it remains active and will
immediately check the next text field you move the cursor to.
The Spell-checker is cancelled if you press the Escape key or
if you press the F2 key to update the record.
- 19 -
................................................................................
PROCEDURES (REPORTING)
The Easy Base procedure generator is the means by which you
manipulate and report on your data.
Each procedure has at least one part, the procedure code. The
procedure code contains the instructions you write to tell Easy
Base what you want done.
If your procedure has an "output", in other words your
instructions tell Easy Base to send data to the screen or to
the printer, then the procedure must also have an Output
Format. The Output Format is where you show Easy Base how you
want the data you are about to "output" arranged on the screen
or page.
If what your procedure is to do depends on variables, ie it
requires information from the operator or from Looked up data
from one or more of your forms then it also requires an "Input
Screen". The Input Screen is where you gather the variable
information that your procedure needs in order to carry out its
task.
Select "procedures" from the main menu and have a look at the
items on the procedures menu.
You will notice that the menu has pre-selected item 2 "Load
Existing Procedure". Other than your first procedure this is
the most useful starting point. Item 1, "Create New Procedure"
is only required if you wish to start a new procedure after you
have another one loaded. The three parts to a procedure
mentioned above are created and edited at items 3,4 and 5.
Procedures, like forms, are saved to disk and can be re-used
repeatedly. Item 6 runs the current procedure and item 7 saves
it to disk.
Item 8 deletes procedures which are no longer required and Item
9 copies an existing procedure. Often you will require a
procedure which is similar to one you have already created. It
is much quicker to copy the first procedure and then edit it
than to start a new procedure from scratch.
Item 10 recalls the last output from a procedure to the screen.
If you need to see the output from a procedure but it is not
imperative that you have the most up to date information,
(close of business / month end figures Etc) then it is much
quicker to view the last output than to re-run the procedure.
Finally, a small window just below the menu shows the name of
the currently loaded procedure. In this case it is "Untitled".
- 20 -
................................................................................
If you have not already done so, read the descriptions of the
Declare, For..Next, If..Then, Print and Printer Control
commands in the Programmers Reference now. These are the basis
of all "reporting" procedures and should be thoroughly
understood. If you are a programming beginner then some of the
examples in the For..Next section may seem a bit advanced -
Just ignore them - for the moment it is only important that you
understand the principle of the loop and the qualifications
that can be applied to it.
Now select item 4 to write your first Procedure Code.
The next few pages will describe simple reporting procedures
based on the "Aircraft" form. To write like procedures for the
forms you have designed all you have to do is substitute your
form and field names.
Before you start, have a look at the function key list on the
bottom line. F2 saves your code and checks it. If you press the
Escape key your code is still saved but the checking routine is
bypassed. If you have written code and find that it is not
passed on F2 because, for example, one of your form fields
needs to be indexed, then you can still save the code you have
written while you modify the form.
F3 and F4 provide search and replace facilities similar to a
word processor.
There is a cut and paste system. To mark code for cutting or
copying hold down the Shift key and shade the code with the
arrow keys. As soon as you release the keys a menu will pop up
with three options - Cut, Copy or Indent. The cut and copy
options work exactly the same as in the Code Snippet editor
with Shift + Ins used to paste the text. If you select "Indent"
then you can indent all the selected lines at once with the
left and right arrow keys.
If you want to print out your code then press F10.
The F1 key, labelled "Help" is the key you use when you can't
remember something. It has all the names of your forms, the
names of the fields in each form and the names of all Commands,
functions, and System values. If Easy Base recognizes the
context of your procedure when you press F1 then it will list
the names you need (Formnames, fieldnames or Commands). If not
a menu will appear from which you can pick which you need.
With the cursor at the start of the top line on your blank
procedure screen press F1.
The "Commands" reminder list appears on the right hand side of
the screen. The command you want is the first one , "Declare
Output Fields" but before selecting it have a look at how to
- 21 -
................................................................................
select from the reminder lists. There are over fifty commands
on this list but only the first seventeen are shown. You can
scroll though them with the arrow keys but you can also use the
inbuilt alphabetic search facility. If you type "o" then the
highlight bar will move directly to the "Odd Page Print"
command.
Take the highlight bar back to the "Declare Output Fields"
command either by scrolling or by pressing the Home key and
press return. The command will be inserted on the first line,
the cursor will move to the second line and the "Forms"
reminder list will appear. Select the form which you wish to
report on. In my example case this will be "Aircraft".
"Aircraft." is inserted on the second line and the "fields"
reminder list appears. I select "Knownas". I also wish to list
the aircraft's mark and type so I write.
Declare output fields
Aircraft.knownas : Aircraft.mark : Aircraft.type
end
Declare the fields you wish to list either by typing them
freehand or by pressing F1 for reminders.
Now complete your procedure code:-
Declare Output fields
Aircraft.knownas : Aircraft.mark : Aircraft.type
end
for Aircraft
Print list items
next
and press F2 to check and save the code.
If you have typed everything correctly you will be returned to
the Procedures menu. If you have misspelled something then the
line with the error will be highlighted and you will get an
error message. Correct the error and press F2 again.
Easy Base now knows that it is to list the three fields
Knownas, Mark and Type from all the records in the "Aircraft"
form. It does not know how they are to be arranged or whether
they are to be printed or just shown on screen. This
information must now be recorded on the procedures "Output
Format".
Select item 5, "Output Format", from the procedures menu and
have a look at the screen. As usual the bottom line shows the
function key usage. To insert a blank line you use F1 as in
form design. F2 saves the format and the Escape Key abandons
it. F3 gives you a line drawing facility similar to that in
- 22 -
................................................................................
form design and Ctrl + "E" brings up the Greek and
International characters menu. The F10 Key is used to place
your output fields.
The upper status line shows the paper size you have selected at
the left hand edge. If you scroll to the right it also shows
where the right hand edge of your paper will be at the three
different print sizes 10, 12, and 17 characters per inch.
On the right hand side of the screen a small menu will have
appeared offering you a choice of Format Section names. You do
not have to use one of these they are just to save you time.
For the moment select "List Items" from this menu.
.List items will appear on the first line and the cursor will
move to the second. For a first procedure we will simply list
the fields required in columns. To do this move the cursor in
along the second line to leave a reasonable margin and press
F10 to place the first field. A menu appears listing the three
fields which were declared in the procedure's code. I select
"Aircraft.knownas". As soon as The field has been selected a
window opens showing the default type and length of the field.
You can change these defaults if you wish the printed length or
type(for numeric fields) to be different in the report to what
it is in the form. This window also presents an extra attribute
marked "Trim Trailing Spaces" which defaults to "No". If you
set this to "Yes" then any blanks at the beginning or end of
the fields contents will not be printed at run time. This
facility is used mainly for inserting numbers or names into
form letter text.
Press F2 to accept the defaults. The area which the field will
occupy is shown on screen. Now move the cursor to the right and
place the other two fields. Finally, press the return key to
take the cursor to a new line and type a full stop ".". The
section names menu appears again. This time select "End".
The format screen now looks like this.
.List Items
██████████████ ████████████ ████████████
.End
Press F2 to save the format. When you do, a new menu will pop
up with four choices for the output destination. The exact
meanings of these selections will be discussed shortly. For
the moment select "Output to Screen". When the Procedures menu
appears select item 7 and save your procedure to disk.
Now select item 6 and run the procedure.
The fields from each record of the "Aircraft" form are listed
- 23 -
................................................................................
down the screen. When the list reaches the bottom line the
screen starts to scroll. When all records have been listed the
screen returns to the start of the list from where you can
browse the report. If the list is long you can pause the output
by pressing the return key while it is still running. Once the
report is complete you can browse through it using the PgUp,
PgDn and arrow keys. You can also use the text search facility
at F3.
When you have finished reading the report press Escape to
return to the procedures menu. You can browse the report again
at any time by selecting item 10 (Recall Last Output). Try it
now. While browsing a report you can also print it out by
pressing F10. If you press F10 to print a report from browse
mode you invoke a low level print driver which prints the
report at 10 CPI, 6 LPI in draft mode. Other font sizes and
effects such as Bold and Underline are only available when you
direct the report output to the printer at run time.
To try printer effects select "Edit Procedure Code" and change
The code to:-
Declare output fields
Aircraft.knownas : Aircraft.mark : Aircraft.type
end
Bold on
12 CPI
for aircraft
print list items
next
Save the new code and select "Edit Output Format". There is
nothing to change in the format itself but when you press F2 to
save it, this time choose "Choose at Run time" for the output
destination.
When you now select "Run Procedure", the computer will beep and
you will be asked whether the output is to be to the screen or
printer. Choose printer and easy base will print your report in
bold at 12 characters to the inch. (Assuming you have installed
the correct printer driver from the utilities menu)
You will notice that while Easy Base was printing your report
it also output it to the screen but on completion it returned
you to the procedures menu without invoking Browse mode.
The output destinations which you choose when saving the output
format are not "Either or" choices. Irrelevant of your choice
the output is always sent to both the screen and the disk file.
It is the disk file that you browse when you select "Recall
Last Output". The differences between the choices are that
only an output to the screen invokes Browse mode on completion
- 24 -
................................................................................
and only an output to printer prints the report. Output to disk
is only selected if you want to update reports from a Batch
Execute menu.
Now let's try something a bit more interesting. So far the
report simply lists the aircraft in the order in which the
records were filed. To list them in alphabetic order, edit the
procedure code and change the "For" line to:-
for aircraft with knownas in order
Save the code. Easy Base can only list in order if the field
you wish the order to be done by is indexed. If the field you
have chosen is not indexed you will get an error message. If
this happens, save the code by pressing the Escape Key - Save
the procedure at item 7 then return to form design. Load your
form - edit the attributes for the field changing Indexed to
"Yes".
You can now reload your procedure and run it. This time the
aircraft names will be in alphabetic order.
Because a procedure has up to three parts it may not at this
stage be obvious how Easy Base is handling the "Saving" or
"Abandoning" of separate parts. Here is a quick explanation.
If you escape from either the output format or later the input
screen and choose to "abandon" it you are abandoning it in the
version of the report you are editing only. If you escape from
the procedures menu and choose to "abandon" the procedure then,
if it is a new "Untitled" procedure it is lost but if it is a
procedure which you have loaded for editing then it is only the
edits which are abandoned - The original procedure remains
unchanged on disk. A procedure which you have loaded for
editing is only changed on disk when you save it with item
seven from the procedures menu. At any time during the editing
of a procedure you can throw away all your edits and return to
the original version by reloading it from disk and replying
"No" when you are asked if you wish to save the currently
loaded version.
Suppose now that we wished to list the aircraft in groups by
type - all the bombers together - all the fighters together
Etc.
To do this, edit the procedure code again and change the "For"
line to: -
for aircraft with type in order
This time, when the report is run, all the airliners come first
followed by the bombers etc. but the group field "Airliner" ,
"Bomber" etc. is listed on each line and it would be much
- 25 -
................................................................................
neater if it could be separated or printed in Bold or
underline.
Edit the code again, this time to:-
Declare output fields
Aircraft.knownas : Aircraft.mark : Aircraft.type
end
declare variables
lasttype as text
end
for Aircraft with type in order
if aircraft.type <> lasttype then print group header
lasttype = aircraft.type
print list items
next
In this code we have introduced a text variable "lasttype".
During the "For" loop the list items will be printed on each
iteration but the group header will only be printed when the
type changes
Now edit the output format to:-
.group header
████████████████
.list items
███████████████ ██████████████
.end
The group header starts with a blank line which will separate
the groups. It contains only the "Type" field. The list items
section contains the "Knownas" and mark fields.
When you run this report the output will be:-
Airliners
Boeing 707
Dehaviland Comet Mk4
Boeing Jumbo Jet 747
Bombers
Boeing B52
Avro Vulcan
Avro lancaster 2
If you want the group header to be in bold or underline then
all you have to do is insert the on and off commands before and
after the "Print group header" command using the block If then
construction.
- 26 -
................................................................................
Declare output fields
Aircraft.knownas : Aircraft.type : Aircraft.mark
end
declare variables
lasttype as text
end
for Aircraft with type in order
if aircraft.type <> lasttype then
bold on : underline on
print group header
bold off : underline off
end if
print list items
next
As a beginner, you are probably wondering about the reason for
the indentations after the "for" and "if" lines. The code will
work perfectly well without them. When you come to write more
advanced procedures you will have many For loops, Do Loops and
If conditions interwoven with each other. If each has its own
indentation then you will be able to see at a glance which
commands occur within which loops and conditions and your code
will be very easy to read and edit.
Going back to the "Aircraft" listing procedure, we now have
each group separated but the aircraft names themselves are no
longer in alphabetic order. This is because we changed index
files when we selected "With Type in order". It is now the
"Type" groupings which are in alphabetic order. Suppose that
we want to keep this grouping but still list the aircraft in
each group with their names in order. Neither of the index
files on the "Knownas" or "Type" fields can produce this order.
We need a combined or "Compound" index on both fields
To construct this index, save the present procedure and return
to form design. Load the "Aircraft" form and add a new field
anywhere on it. Assuming the length of the "Knownas" field as
45 and the length of the "Type" field as 14 the new fields
attributes are:-
Name Typename
Type Text
Length 59
Mandatory No
Unique No
Indexed Yes
User Entry No
Display Invisible
Derived Yes
The derivation formula is:-
Jointext(spacepad(type,15),knownas)
- 27 -
................................................................................
Test that the derivation formula is correct by pressing F5 for
test mode. When you type a name into the "Knownas" field and a
type in the "Type" field the new field should derive as a
combination of the two.
Escape from test mode and press F2 to save the form. Easy Base
will first re-format the data file to incorporate the new field
and then write the new index file.
When this is complete, return to the procedure and edit the
"For line of the code from:-
For aircraft with type in order
to
For Aircraft with typename in order
No change is necessary to the output format. The output will
be laid out as before but the names in each group will be in
alphabetic order.
To "Polish" the "Aircraft" report it would be nice if it had a
heading. We would also like to prevent the list from running
off the end of the page when printed and add a page number at
the foot of each page.
To do these things edit the code to:-
Declare output fields
Aircraft.knownas : Aircraft.type : Aircraft.mark
page number 'New Field
end
Declare variables
lasttype as text
end
bold on
print report header
for aircraft with typename in order
if bottom margin < 1 then
bold on : print page footer
page feed : print page header : bold off
end if
if aircraft.type <> lasttype then
bold on : underline on
print group header
bold off : underline off
end if
print list items
next
print report footer
- 28 -
................................................................................
Now edit the output format to:-
.Report header
════════════════════════════════════════════════════
AIRCRAFT LIST BY TYPE
────────────────────────────────────────────────────
.Group Header
████████████████
.List Items
████████████████ ██████████████████
.Page header
════════════════════════════════════════════════════
Aircraft List By Type (Cont)
────────────────────────────────────────────────────
.Page Footer
- ██ -
.Report Footer
════════════════════════════════════════════════════
.End
The new print sections Report Header, Report Footer, and Page
Header contain only fixed text. The new section Page Footer
contains the new field "page number" and the "Trim trailing
spaces" attribute should be set to "Yes" in this. This will
keep the correct spacing of - 9 - and - 10 - when the
page numbers are printed.
So far all the fields we have printed are from the same form
"Aircraft". Suppose that we also wanted to list the country of
origin for each aircraft. The "Aircraft" form does not hold
this information but the "Manufacturers" form has a field
"Nationality". To incorporate this field into the report all we
have to do is declare it as an output field and then arrange to
have that field in memory when we print the list items. We can
load the correct record from the "Manufacturers" form by using
the linking data "Name" in the manufacturers form and
"Manufacturer" in the "Aircraft" form. This is a similar
process to looking up data except that a pre defined
relationship is not necessary. We can tell Easy Base exactly
what we want within the code.
Declare output fields
Aircraft.knownas : Aircraft.type : Aircraft.mark
Manufacturers.nationality : Page number
end
Declare variables
Lasttype as text
end
- 29 -
................................................................................
'.....................PRINT REPORT HEADING...
print report header
'.................
for aircraft with typename in order
'..................PRINT HEADERS AND FOOTERS...
if bottom Margin < 1 then
bold on : print page footer
page feed : print page header : bold off
end if
'..................PRINT GROUP HEADERS.........
if aircraft.type <> lasttype then
bold on : underline on
print group header
bold off : underline off
end if
'...............LOAD MANUFACTURERS NATIONALITY..
for manufacturers with name = aircraft.manufacturer
Print list items
next
'..............
next
print report footer
Because the procedure code is becoming longer, remarks are
added to make it easier to see which parts of the code do what.
You can add remarks to your code anywhere by prefixing them
with an apostrophe.
At the point where we are about to print the list items we
start another "For" loop. This time "For Manufacturers". When
one "For" loop is "Nested" within another, the record currently
loaded by the first loop remains in memory while the records
selected by the "Nested" loop are processed and all the fields
of both records are available at the same time.
As we have qualified the "Manufacturers" loop:-
for manufacturers with name = aircraft.manufacturer
only the single record in which the "Name" field matches the
"Aircraft.manufacturer" field which is currently loaded by the
outer loop will be selected from the "Manufacturers" form.
While we have both the required records in memory we print the
list items.
All that remains to do now is to edit the output format and add
the "Manufacturers.nationality" field to the .List Items
section.
- 30 -
................................................................................
By nesting loops in this way, you can list data from any number
of different forms which have "Linking" data in one of their
fields. Where only one record matches as in the example above
then the required fields go in the .List items section with the
other fields. Where there are many matches (Related list) the
fields from the secondary loop have their own print section.
(See example on page 5)
Now we can print any of the fields from any "Related" forms in
any order. We are still, however, listing all the records from
the "Aircraft" form and we may for example only wish to print
those records which are in the "Bomber" group.
Start a new procedure and enter the code:-
Declare output fields
Aircraft.knownas : Aircraft.type : Aircraft.base
end
for aircraft with type = "Bomber"
print list items
next
Create the output format placing the three output fields within
the .List Items section.
When you run this report, only the bombers will be listed but,
once more, the aircraft names will be in the order in which
they were entered to the form.
To get them in alphabetic order we must again use the compound
index on the "Typename" field. This time we have to ensure that
the loop starts with the first "Bomber" and ends with the last
"Bomber".
Declare output fields
Aircraft.knownas : Aircraft.type : Aircraft.base
end
declare variables
group as text
end
group = "Bomber"
for aircraft with typename > "Bomber"
if aircraft.type <> group then exit for
print list items
next
Before starting the "For" loop we set a variable "Group" to the
value "Bomber". The "For" loop is then qualified such that the
records will be processed with "Typename" in order but starting
with the first occurrence of "Bomber" in the field. To stop
the loop when all the bombers have been processed we test the
contents of the "Aircraft.type" field on each iteration of the
- 31 -
................................................................................
loop and when the first record is loaded which is not a bomber
we stop processing the loop with the command "Exit For".
As in the first procedure, we could now add Page headers, Page
footers and number the pages Etc.
Suppose however that having created this procedure we now
wanted a list of all the "Airliners".
We could achieve this by changing "Bomber" to "Airliner" within
the code but this would be time consuming. It would be much
better if we could tell Easy Base which type group we wanted at
the start of the procedure and have Easy Base make the
necessary changes.
To supply "Variables" to a procedure before running we use an
"Input Screen", the third part of a procedure. Save the code
and select item 3 (Create Input Screen) from the procedures
menu.
As soon as you select item 3 Easy Base will ask if you wish to
copy an existing form. Type "N" for no. The next screen will
be familiar to you. It is exactly the same as the form design
screen.
When you first designed your forms, the form design routine
performed two tasks. It created your form and also a default
input screen from which to enter data. Now that you are about
to create input screens for procedures, the same routine is
used to design the screen. It does not, of course, create a
parallel form.
All the facilities for "Polishing" your forms - all the
facilities for deriving, calculating looking up and testing
derivations which you had in Form Design are also available for
Input Screen design.
The only difference you will notice is that when you define a
field, the "Unique" and "Indexed" attributes are marked "Not
Applicable" and when you run the procedure, only the "Options"
"Clear Screen after Running Procedure" and "Clear Field on
Editing" are available.
Move the cursor to somewhere near the middle of the screen and
type:- "Which Aircraft type would you like listed". Then press
F10 to define a field.
If, in the aircraft form the "Type" field had been defined as a
choice field, then we would define this field as a choice field
and use the same list.
If, on the other hand the "Type" field in the "Aircraft" form
- 32 -
................................................................................
looked up its contents from a core data form containing the
type names then we would set the attributes:-
Name type
Data type text
Field Length 15 (Same as the "Type" field in "Aircraft")
Mandatory Yes
User Entry Yes
Display Field (or text or Alt colours as you wish)
Derived No
The field will of course be derived:- Lookup(Aircraft,type)
but as we have not yet entered the relationship, we will leave
the derived attribute set to "No" to prevent an error message
when we save the screen.
Save the screen. When you do, you will be asked to select
between "Repeat Screen after F2" and "Run Once and Exit".
If you choose the first option then the procedure will repeat
until you press the Escape Key. If you choose the second
option, control will return to the procedures menu after the
report has been run.
Now save the procedure. Let's call it "Aircraft By Type".
You may have noticed that all Form, Field and Procedure names
so far have been single words. There is no restriction on
using multiple words in names but single ones make code much
easier to read. The only good reason to use more than one word
is in a reporting procedure name. After the procedure has been
run the status line in Browse mode will be "Procedure:-
Aircraft By Type" which makes more sense to an end user than
"Procedure:- ACbytyp".
Now go to Relationships and enter the relationship "Aircraft"
between "Aircraft by Type" and "Aircraft" linking the two
fields "Type".
Reload the "Aircraft by Type" procedure and edit the Input
screen setting the derived attribute to "yes" and entering the
derivation formula:- Lookup(aircraft,type)
Save the screen again and select "Edit Procedure Code".
To use the Input screen quickly you could change the two
occurrences of "Bomber" to input.type. However, now that we
have an input.type field the variable "group" is superfluous.
The finished procedure code and Output format are shown on the
next page.
- 33 -
................................................................................
Declare output fields
Aircraft.knownas : Aircraft.base
Page number : input.type
end
Print report header
for aircraft with typename > input.type
if bottom margin < 1 then
print report footer
page feed : print page header
end if
if aircraft.type <> input.type then exit for
print list items
next
print report footer
page feed
......................Output Format.........
.Report Header
══════════════════════════════════════════════
████████████ LIST
════════════
Name Built at
──────────────────────────────────────────────
.Page header
──────────────────────────────────────────────
Name Built at
──────────────────────────────────────────────
.List items
████████████████████ █████████████████
.Page Footer
- ██ -
.Report Footer
══════════════════════════════════════════════
.End
The field in the Report header is input.type. The fields in
the list items are Aircraft.knownas and Aircraft.base.
The field in the page footer is Page number.
Suppose now that we print out the report and find that we had
entered all the "Aircraft" "Knownas" fields in Upper case and
all the "Base" fields in Lower case. This would make the
report quite untidy. There is no need however to change the
original data. To print both fields in Upper case all we need
to do is alter each of the "Base" field contents using the
"Upper" Function before printing it.
To do this insert the line:-
- 34 -
................................................................................
aircraft.base = upper(aircraft.base)
immediately before the print list items command.
As well as simply "Listing" data you can manipulate it in many
different ways. You can do any form of arithmetic on numeric
fields and you can alter text, date and time fields with over
fifty different functions.
A function is a small internal routine which returns a value
derived from one or more other values (Parameters) which you
supply. For Example, in the code line:-
date = datetext(invoice.date)
"Datetext" is a function to which you are passing the parameter
"Invoice.date". If invoice.date is 02/02/94 then the function
"Datetext" will derive the text "2nd February 1994" and
"Return" this as if it were a variable. The output field "Date"
will therefore become "2nd February 1994".
A functions parameters are always passed to it enclosed in
brackets. If there are more than one then they are separated
by commas.
The next section of the Manual introduces you to Procedures
which perform transactions. You should now read the
descriptions of the following commands in the Programmers
Reference.
Copy All From
Delete Record
Clear Records From
Update Record
Pause On/Off
Escape On/Off
Together with the field control "Beep".
Note:
From Version 7 Procedures with input screens can be innitiated
with any of the function keys 2,4,5,,7,8,9 or 10
See Programmers Ref. Procedure command "Run"
- 35 -
................................................................................
PROCEDURES (TRANSACTIONAL)
In Data Entry you make a "Transaction" when you add, update or
delete a record. You can make the same transactions in
procedures. There are, however, two major advantages to
making your transactions via procedures.
1. You control which transactions can and cannot be made.
2. You can make any number of different transactions in any
number of different forms.
Consider the "Customers" form. You would want any of your
staff to be able to add a new customer in your absence. If you
allow them to do this in Record Entry then they could also
(deliberately or inadvertently) alter or delete other customers
records.
To prevent this, create a new procedure. Create an input
screen. When you are asked if you wish to copy an existing
form - reply "Yes" and select the customers form. Save the
input screen and select Create Procedure Code. Now enter the
procedure code:-
for customers new record
copy all from input
next
Save the procedure - Let's call it "Enter customers". You can
now call this procedure from your "User Menus" described in the
next section and your staff will be able to enter new customers
without the opportunity to make any other transactions.
You can also control parts of a transaction. If your
"Customers" form had a field for "Creditlimit" then, in the
form, you would wish to be able to enter any credit limit you
wanted, but you might wish to restrict the amount your staff
could enter for a new customer.
To do this you simply edit the field attributes for the
"Creditlimit" field in the input screen.
To set a fixed credit limit of say £500.00 set the user entry
attribute to "No", the derived attribute to "Yes" and enter the
derivation formula:- 500.
To restrict the entry to a maximum of say £1000.00 you would
leave the user entry attribute set to "yes" but derive the
field:- If(creditlimit > 1000,blank[beepMaximum credit £1000
for new customers],creditlimit)
There might also be fields on the "Customers" form which are
- 36 -
................................................................................
irrelevant to the transaction of adding a new customer. You
might also have fields for personal comments which you do not
wish your staff to see. You can simply delete these from the
input screen or change them to invisible.
In other words you can limit a transaction in any way you wish
and the final input screen can be totally different to the
original form.
Transaction procedures which delete or update records are
created in a similar manner but are slightly more complicated.
To create a procedure which allows your staff to delete
customers, you would again copy the customers form as the input
screen. This time, the only field to which you allow User
Entry is the "acountno" field. You enter a relationship
between this report and the "Customers" form linking "acountno"
and derive all the other fields you wish to show as:-
lookup(customers,name)
lookup(customers,address)
Etc.
Your staff now enter the account number to be deleted. The
other "looked up" fields are only there so that the name and
address will appear confirming that the correct account number
has been entered.
The procedures code to delete the record is:-
for customers with acountno = input.acountno
delete record
next
As with the procedure to add a record you are still in complete
control of what can or cannot be done. Suppose that you had a
field on the "customers" form which you kept updated with his
account balance. You would not want anyone to delete a
customer who still had an outstanding balance on his account.
To prevent this, just change the derivation for the "balance"
field to :-
if(lookup(customers,balance) <> 0,blank[beepCustomers cannot be
deleted until their A/C is clear],0)
You would also set the Mandatory attribute to "Yes" to prevent
anyone from ignoring the warning.
If you wanted a procedure which allowed staff to change a
customers address but no other fields, then you would create
the same input screen as for the delete record and the same
- 37 -
................................................................................
relationship but this time you would allow user entry to the
address field and derive it:-
Default(lookup(customers,address))
When the operator enters the account number for the customer
whose address he wishes to change, the old address will appear
to confirm that he has the right customer, but he will be able
to edit it.
The procedure code would be:-
for customers with acountno = input.accountno
customers.address = input.address
update record
next
The second advantage of making transactions via procedures is
that you can perform several tasks at once. Consider a Video
Library hiring films to its members. There will be a form for
the films, one for the members and one for daily takings.
The procedure used for hiring out the films will have an input
screen with a field for the members number, possibly three
fields for the film numbers being hired, three more fields in
which the films rental prices are looked up and one in which
these three fields are totalled. When the operator runs the
procedure all the necessary transactions are performed by the
procedure code:-
for members with number = input.member
if input.film1 <> blank then members.film1 = input.film1
if input.film2 <> blank then members.film2 = input.film2
if input.film3 <> blank then members.film3 = input.film3
update record
next
if input.film1 <> blank then
for films with number = input.film1
films.hiredto = input.member
films.datehired = system date
update record
next
end if
for daily takings
total = total + input.total
update record
next
The mid section of the code updating film1's record would of
course be repeated for film2 and film3 but has been omitted for
clarity.
- 38 -
................................................................................
USER MENUS
Once you have created forms and procedures you can create an
end user menu system to run them. You could wait till all your
procedures are finished but you will get a much better feel for
how your program is developing if you start and use a menu
system as you go. Easy Base includes a User Menu call to its
system menus so you can work from your own developing menu
system while you are still developing your program.
Select "Menus" from the main menu and have a look at the
screen. The Menus screen is an internal form just like the
ones you have created. You have all the same facilities to
enter, update and delete menus that you have in Data Entry to
one of your own forms.
Let's create a menu based on some of the forms and procedures
previously discussed.
The first field on the menus form is "Menu Name". This is the
unique field and a name must be supplied. We'll call it
"Customers". The next field is "Menu Type". This is a choice
field with two options, "Normal" and "Batch Execute". The
"Batch Execute" option will be discussed later. For now,
select "Normal".
The third field is "Menu Title". Whatever you enter here will
be displayed as a title (or heading) above your menu.
The fourth field which is untitled on the screen is a choice
field with the options, "Run on Number Key" and "Run on Return
Key". If you choose the first option then the items on your
menu will be run as soon as the item number is pressed and if
you choose the second option then typing the item number will
move the highlight bar to the selection but the item will not
be called until the return key is pressed. In either case you
will still be able to select items with the cursor control keys
The next field asks for a "Sign on password" if a startup menu.
You can start your application (program) on any menu that has
a sign on password by restarting Easy Base and using that
password instead of your developers password. In this case we
are going to menu the reports which add, delete and alter a
customers address. This will be a sub menu so we leave this
field blank.
The main section of the "Menus" form has three columns of nine
fields. The first column is for the text to be displayed on
the menu. The second is for the type of action (function)
which is to be called. The third is for the individual item.
- 39 -
................................................................................
With the cursor in the first text field we type:-
Enter a New Customer and press return.
As soon as the cursor moves to the first "Function" field a
menu appears listing all the different functions that can be
called. The first four choices allow you to:-
1. Run one of your procedures.
2. Recall the last output from one of your procedures.
3. Call the data entry screen for one of your forms.
4. Call another of your menus.
The other functions are selected utilities from the system
utilities menu which you may wish to provide to the
end user without allowing him access to the entire system.
Select "Run Procedure" and press return.
When the cursor moves to the "Item" column Easy Base will list
all your procedures. Choose "Enter customers".
on the next two lines enter:-
Delete Existing Customer Run Procedure Delete Customers
Change Customers Address Run Procedure Address Change
and press F2 to save the menu.
Now let's make a start to the main "Startup" menu. We may not
have any procedures to put on it yet but we can get started
with an item to call data entry to "Customers" and one to call
the "Customers" sub menu.
Fill in a new menus record using the name "Main Menu", Type
"Normal" and Title "- M A I N M E N U -". This time enter a
startup password, say "Fred". Complete the Items section
with:-
Customers Records Data Entry Customers
Customer Updates User Menu Customers
Program Development System menus
Press F2 to save this menu then press escape all the way out to
the DOS prompt (or your hard disk menu system). Restart Easy
Base. This time, when the sign on screen appears, enter "Fred"
and press return.
Instead of the system menus, you will see your "Main Menu".
If you select item 1 the "Customers" form will come up. If you
select item 2 your sub menu will be overlaid and you can run
any of the three procedures on it. If you select item 3 you
- 40 -
................................................................................
will be transferred to the Easy Base System menus where you can
continue with the development of your program.
Whenever you create new procedures or forms you can add them to
your menu system.
Suppose you would like the utilities, Backup Data, Restore Data
and Install Printer to be available from your menu system.
Create a new menu, let's call it "Utilities" with the items:-
Backup data to disk Backup Data
Restore data from disk Restore Data
Install Printer Install Printer
Save this new menu then edit your main menu to include the new
item:-
Utilities User menu Utilities
When you have called the Easy Base system menus from one of
your own menus then pressing escape does not exit the program,
it returns you to your own menu. You close down by pressing
escape from your main menu. When you get back to your "Main
Menu" you will notice that the new "Utilities" item is not
there. New Menu items cannot be added while the program is
running. To incorporate the "Utilities" item you must again
exit the program and restart with the password "Fred".
As your program develops you can create as many menus as you
need. Your "Main Menu" can call up to nine sub menus. Each of
those can call another nine sub sub menus Etc Etc. You can also
have additional startup menus with different passwords. These
can either run completely different menus or can restrict
different parts of the menu system to different users.
When you start up on one of your menus systems Easy Base
creates a default "Tree" structure for it. From whichever menu
is on screen the escape key backsteps down the tree until you
reach your "Main Menu" and then exits the program.
If one of the "forward" menu calls crosses branches, ie it
calls a menu which is also called from a lower level then
subsequent presses of the escape key backstep down the current
branch and not back "cross tree".
You can also make menu calls from low to high levels. (a sub-
sub- sub menu can have an item which calls the main menu).
In some circumstances you may prefer a hierarchical rather than
a tree structure where the main menu is recalled after each
individual procedure. To accomplish this, each final item is
placed on its own menu followed by a call to the main menu and
- 41 -
................................................................................
the menu type is changed to "Batch Execute".
When you create a "Batch Execute" menu then instead of
displaying a menu for you to choose from, Easy Base
executes each item on the menu in sequence and then returns to
the menu which called it.
With batch execute menus you can automate many of the processes
in your application. If you have several printouts to be done
each day you can have them all done from batch execute menus.
Similarly, if you need to update many reporting procedures for
later "Recall" to the screen, these can all be done at once.
There is no limit to the number of procedures which can be
batched - One batch menu can call another.
If you create a "Startup" batch menu then, provided it does not
call a "Normal" menu, Easy Base will perform all the tasks on
the menu and then exit to DOS.
If you create a "Startup" batch menu which eventually calls a
"Normal" menu then the batch process stops at that point and
the "Normal" menu becomes the main (root) menu. Pressing
escape from this menu exits to DOS. it never returns to the
startup batch menu which called it
Start up batch menus are useful for running regular daily
procedures and for forcing the user to check the system date
and time.
There are many other uses for batch execute menus. You can
automate menu changes. If, for example, running one particular
procedure is invariably followed by running one from a choice
of three others then the menu containing the others can be
batched after the first procedure.
In Easy Base you can create quite long and complex procedures
but they are eventually limited by memory constraints. If you
ever run out of memory creating a long procedure then just
split it and batch the parts.
Don't forget to set the output of non print reports to "Disk"
otherwise Browse Mode will be invoked.
- 42 -
................................................................................
EXTERNAL FILE ACCESS
In order to provide flexible import and export to data files
external to your applications, Easy Base includes a complete
set of low level file access commands. :- Open, Close, Seek
Read, Write, Find, Shell and Erase.
Full details of the commands and how to use them are given in
the programmers reference but please read the following notes.
You can only open one external file at a time but you can
transfer data either way between it and any number of Easy Base
files.
You can open any number of external files within one procedure
but you must close each before you open the next.
In Easy Base all data is converted to a common type for
processing. Within the system this has the advantage that you
never need to worry about what type of data you are handling.
You can assign a text field's value to a numeric field and you
can assign the result of a calculation to a text field.
However, in order to do this Easy Base pre processes text
variables. If you are accustomed to file access, string
manipulation and trimming functions then you may get unexpected
results.
Here are the rules:
If you read a string to an Easy Base text field all leading and
trailing spaces are removed. If the remaining string is longer
than the declared field length then it is truncated to the
field length.
If you read a string to an Easy Base text variable then all
trailing spaces are removed. Text Variables are variable
length.
If you wish to create a string with leading spaces for a write
command then you must do it in a text variable. Text fields do
not accept leading spaces. You can pad strings with spaces
using the Spacepad and Jointext(stringof()) functions.
If you read an ASCII line then it is read without the Cr/Lf
sequence.
You can read ASCII directly into numeric fields.
The data in an Easy Base Text Block field is formatted with a
single Chr$(13) wherever a new line is to be forced.
To read ASCII to a Text Block field, read lines to a variable
- 43 -
................................................................................
then join the variable to the field with an intervening
CHr$(13).
Ex.
read line to LineVar
Pupils.notes = Jointext(pupils.notes,Chr$(13),Linevar)
To Write a Text Block field as ASCII lines use the keyword
Line_Len in the write command.
Ex.
write Pupils.Notes Line_len 60
You cannot write quotation marks within quoted text. Whenever
Easy Base processes a text field, variable or read in string it
substitutes Chr$(127) for internal quotation marks and replaces
them after the process. This substitution is not done for
direct assignments. TextVar = "Fred said "Hello"" is not
allowed. If you need to make such an assignment then you must
replace the internal quotation marks with Chr$(127) yourself.
To create CHR$(127) in the procedure editor, hold down the ALT
key and type 127 on the numeric keypad.
- 44 -
................................................................................
EASY BASE DATA FILE FORMAT
Easy Base data files are fixed length record files with no
field separator. There is no file header.
There is a three byte record header. Byte one is "L" for a live
record and "D" for a record marked for deletion. Bytes 2 and 3
are null.
The field order is top left to bottom right from the default
input screen.
All text fields are ASCII.
All numeric, date and time fields are Microsoft 8 Byte double
precision numbers.
In the case of dates, this represents the number of days from
the first of January 1981 and in the case of time, the number
of seconds from midnight.
- 45 -
................................................................................
SYSTEM REQUIREMENTS
Required.
IBM or compatible 286 or higher
1Meg Ram
540k free conventional memory
Preferred.
4 Meg expanded memory with 2 Meg allocated to PC-Cache
NOTE:-
If you have 2 Meg of expanded memory then certain EMS
managers can cause Easy Base not to load with the error message
"Insufficient EMS to load overlays". If this happens to you
then you can load Easy Base in conventional memory by remming
out the EMS driver in your Config.Sys file.
SYSTEM LIMITATIONS
Fields per Form 500
Indexes per Form 500
Record Length Limited by display of 4 screen pages
Records per Form Limited by Maximum data or index file
length of 2,100 Megabytes
Forms per application } Total of 500 in
Procedures per application } any combination.
Menus per application 500
- 46 -
................................................................................
DOS FILENAME CONVENTIONS
The Easy Base system files are:-
EB.EXE The program file
EB.CUR Initial screen setup
EB.SET Configuration file
EB.MEN User Menus form
EB.REL Relationships form
EB.MSG Text and error messages
EB.PRS Printer drivers
EB.D01 Main dictionary
EB.DO2 Personal dictionary
The files which are created in the data directories have the
following filename convention:-
Forms:-
BASE(No).DEF The entry screen definition.
BASE(No).DAT The data file.
BASE(No).(No) Index files.
Choice field lists
LIST(No).DAT
Procedures
PROC(No).PRO The procedure code.
PROC(No).DEF The input screen.
PROC(No).REP The output from the procedure.
There are also six individual files:-
MENUS.DAT The menus you create.
RELATION.DAT The relationships you create.
CHOICES.DIR The choice list directory.
BASE.DIR The forms directory.
PROC.DIR The procedures directory.
RECOVER.INF Recovery information to reinstate a form
should you suffer a power failure during
a pack or reformat operation.
- 47 -
................................................................................
Easy Base is a registered trade mark of John Turnbull.
Easy Base documentation is copyright John Turnbull 1994. It may
be freely distributed as part of the Shareware program and
users of Easy Base may print a single copy of the documentation
for their own use. All other rights are reserved.
Trade marks of any other company included in the documentation
are acknowledged.
John Turnbull disclaims all warranties as to this software,
whether express or implied, including without limitation any
implied warranties of merchantability, fitness for a particular
purpose, functionality, data integrity or protection.
- 48 -
................................................................................
════════════════════════════════════════════════════════════════
SELECTED PROGRAMMING TOPICS
────────────────────────────────────────────────────────────────
Address Labels 50
Automatic Lookups 52
Bypass Signon Screen 53
Check Off Fields 54
Compound Index 55
Compound Lookups 58
Conditional Lookups 59
Correcting Stats. 60
Creating Runtime 61
Customize Help Line 62
Cyclic Procedures 63
Data Type Conversion 64
Duplicate Prevention 65
Form Letters 66
Global Defaults 68
Input Screen Format 69
Invoicing/Ordering 70
Keyword/Text Search 73
Linking Applications 75
Maximizing Speed 76
Multiple Columns 78
Q And A Input Screen 79
Runtime Auto Start 80
Set System Values 81
Tabulation 82
Totals & Sub Totals 83
- 49 -
................................................................................
ADDRESS LABELS ADDRESS LABELS
The following procedure prints two columns of address labels
from a "Addr" form.
.......................Procedure code................
Declare output fields
Addr.name : Addr.street : Addr.town : Addr.pcode
Lname : Lstreet : Ltown : Lpcode
end
for Addr
if Lname = blank then
Lname = Addr.name : Lstreet = Addrstreet
Ltown = Addr.town : Lpcode = Addrpcode
else
print list items
Lname = blank : Lstreet = blank
Ltown = Blank : Lpcode = blank
end if
next
if Lname <> blank then print list items
....................Output Format........................
.List Items
{Lname field } {Addr.name field }
{Lstreet field } {Addr.street field }
{Ltown field } {Addr.town field }
{Lpcode field } {Addr.pcode field }
.end
The field positioning and the distance between the .List Items
and .end can be adjusted to fit the label paper.
If your label paper has three columns then you could use the
following procedure.
declare output fields
Addr.name : Addr.street : Addr.town : Addr.pcode
Mname : Mstreet : Mtown : Mpcode
Lname : Lstreet : Ltown : Lpcode
end
declare variables
x as number
end
Continued.
- 50 -
................................................................................
ADDRESS LABELS ADDRESS LABELS
for addr
x = x + 1
if Mod(x,3) = 1 then
Lname = Addr.name : Lstreet = Addr.street
Ltown = Addr.town : Lpcode = Addr.pcode
end if
if Mod(x,3) = 2 then
Mname = Addr.name : Mstreet = Addr.street
Mtown = Addr.town : Mpcode = Addr.pcode
end if
if Mod(x,3) = 0 then
Print list items
Lname = Blank : Lstreet = blank
Ltown = blank : Lpcode = Blank
Mname = Blank : Mstreet = blank
Mtown = blank : Mpcode = Blank
end if
next
If Lname <> blank then print list items
.........................output format...................
.list items
{ Lname } { Mname } { Addr.name }
{ Lstreet } { Mstreet } { Addr.street }
{ Ltown } { Mtown } { Addr.town }
{ Lpcode } { Mpcode } { Addr.pcode }
.end
See Also:- Form Letters
- 51 -
................................................................................
Automatic Lookups Automatic Lookups
Normally, when a user initiates a primary lookup in a text
field he will enter a few characters followed by the * in order
to narrow down his choice list. If, however, the possible list
is fairly small you may wish to have it displayed automatically
as if it was the list for a choice field.
For example, you have a departments form with a field "name"
and there are only twelve records.
When entering records to your "Employees" form which has a
field for his department, you wish to lookup the department
name. If you derive the Department field on this form as
"Lookup (Departments,name) and allow user access to it then the
user must type at least an * and press return to bring up the
list of department names.
You can make this list pop up automatically by setting user
entry to the department field to "no" and deriving it with the
formula:
If(Department = Blank,"*",Lookup(Departments,Name))
In other words the derivation formula automates the typing of
the *.
Please note that all forms and input screens must have at least
one field to which the user has access. If you wish to make an
automatic lookup on a procedure input screen that only has one
field then you must add a second field purely to hold the
cursor. This can of course be invisible.
- 52 -
................................................................................
BYPASS SIGNON SCREEN BYPASS SIGNON SCREEN
You can bypass the sign-on screen for both the developers
password and any User-menu password by adding the sub directory
and password to the start up command line. This is particularly
useful in finished applications as the application can be
called directly from a hard disk menu system - the sign on
screen will not appear and the application will start as if it
were a stand alone program.
To start an application in the accounts sub directory whos
start up menu password is "start" use the command line:
EB accounts/start
If you have several applications in different sub directories
all with the same password you can skip entering the password
but still choose the sub directory by using the command line:
EB password
If you supply both the directory and the password then you
cannot change directories from within the program.
See also Runtime Autostart
- 53 -
................................................................................
Check off fields Check off fields
Occasionally you may wish to have a field which is simply used
to mark or "Check off" items to be done or printed. There is no
graphical output from Easy Base but you can create a reasonable
check off field by making it a choice field and using the two
choices ASCII 255 and ASCII 251.
You must use ASCII 255 as the blank as a "Blank" choice is
deleted at run time and ASCII 251 (√) which is actually the
square root sign makes a reasonable "Tick".
To enter the characters, hold down the Alt key and type the
number on the numeric key pad.
To have a form or input screen display with the items ready
ticked, just define the tick fields with this choice list,
derive them as Default(√) and make the color Text, Alt1 or
Alt2. Easy Base will automatically display the help line "Press
the space bar to change".
- 54 -
................................................................................
COMPOUND INDEX COMPOUND INDEX
If you need to list records from a form in such a way that they
are grouped by one field but with each record in the group
ordered by another then you can either use a compound index
field or "Subindex" the group during the procedure.
A compound index field is simply an additional field in which
the contents of two or more fields are compounded using the
"Jointext" function. The field is indexed and the index on that
field can then be used to select records with the desired group
ordering.
For example:- A "Videos" form has fields for "Title",
"RentalPrice" and "Category".
To list the records grouped by "Category" but with the "Titles"
in each category in alphabetic order you add another field to
the form which is Text, Indexed and long enough to hold the
contents of both the "category" and "Title" fields. The field
is derived by joining the text of the "Category" and "Title"
fields.
There are a couple of minor complications in creating compound
index fields. Firstly the "Jointext" function by default strips
any trailing space characters from the text it is joining. If a
straight "Jointext" function was used and the first two videos
entered were "A Bridge Too Far" and "Snow White" then the
compound fields would derive as:-
"WarA Bridge Too Far" and
"CartoonSnow White"
When what you need is:-
"War A Bridge Too Far" and
"Cartoon Snow White "
To produce the desired spacing in the compound field use the
"Spacepad" function.
If the length of the "Category" field is 15 then derive the
compound field with - Jointext(spacepad(category,15),title)
If you are compounding more than two fields then "spacepad" all
the fields being joined to their own field's length except the
last one.
The maximum length of a text field in Easy Base is 80
characters. If the fields you need to compound total more than
80 then you must reduce the length of the field names. Compound
indices in Text Block fields should not be used.
- 55 -
................................................................................
COMPOUND INDEX COMPOUND INDEX
Once you have created a compound field and checked that it
derives correctly it is normal to define it as invisible and no
entry anyway as it is not its contents that are of interest but
the order which its index produces.
Ex. Assuming the compound field was called "catgroup"
..........................code..................
for videos with catgroup in order
print list items
next
........................format.................
.List Items
{Videos.Category Field} {Videos.Title Field}
.End
Ex.
...........................code....................
declare variables
catcheck as text
end
for videos with catgroup in order
if catcheck <> videos,category then print group header
catcheck = videos.category
print list items
next
..........................format...............
.Group Header
-------------------------------------
Films categorized as {category field}
-------------------------------------
.List Items
{Title field}
.End
There is yet a further complication if one or more of the
fields to be compounded is numeric. Easy Base index files are
sorted alphabetically if the field is text and numerically if
the field is numeric. A compound field is always text so if you
need to compound a numeric field you have to ensure that it
will sort alphabetically to the same order that it sorts
numerically. The text of numeric values sort alphabetically to
the same order as their values only if they all have the same
number of digits either side of the decimal point.
6 12 and 34 sort alphabetically as 12 34 6
but
06 12 and 34 sort alphabetically as 06 12 34
- 56 -
................................................................................
COMPOUND INDEX COMPOUND INDEX
Easy Base provides the function "Zeropad" to pad numbers to the
same length for compounding. The "Zeropad" function has three
parameters - The number to be padded, the number of digits left
of the decimal to pad to and the number of digits right of the
decimal to pad to. All three parameters must be supplied. If
the number is an integer then the third parameter is 0.
Ex. To list the "Videos" records grouped by rental price with
the titles in each price group in order you would create a
compound field derived with:-
Jointext(zeropad(rentalprice,2,2),title)
Ex.
A "Ships" form has fields for "Type" and "Displacement"
To list the ships grouped by type with the Displacement in each
group in order you would create a compound field derived with:-
jointext(spacepad(type,15),zeropad(displacement,8,0))
In many cases where you wish to compound a mixture of text and
numeric fields you will require the numeric values to be listed
in descending order while the text value is to be in alphabetic
order.
In the above example for ships, had you wished each group to
be listed with "Displacement" in descending order you would
derive the compound field as:-
jointext(spacepad(type,15),reverse(zeropad(displacement,8,0)))
The "Reverse" function simply inverts the ACSII number of each
character in its parameter so that it will sort in reverse
order in the index file.
The "Reverse" function works equally well on text values
although reverse alphabetic lists are seldom required.
The "Zeropad" function will only pad out a number to the size
required. It will not trim the number if it is already longer
than one of the pad lengths. You should not therefore create
compound fields with Floating Point numbers.
If you compound a date or time field you should zeropad it to
5,0 as the text which will be used is actually the date or time
fields numeric value.
- 57 -
................................................................................
COMPOUND LOOKUPS COMPOUND LOOKUPS
Occasionally, in an input screen, you will wish to lookup
details from a form whose unique field is a compound of two
others. As an example, if you wished to lookup details from
the "Userlist" form, mentioned in the manual, then you would
have to base the lookups on a relationship between a field on
the input screen and the "UNI" field in "Userlist". The "UNI"
field in userlist is a combination of the "Aircraft" forms
"Knownas" field and the "Airlines" form "Name" field.
Although you could simply use a field "UNI" on the input screen
and derive it :- Lookup(userlist,uni) - this would mean that
the end user would have to enter the whole of the aircraft
Knownas part plus part of the airlines name part plus the "*"
in order to get the lookup.
This would not only be awkward to use but would also entail
explaining compound fields to the end user.
You can avoid this situation by providing two fields, one in
which the user looks up the aircraft knownas field and one in
which he looks up the airline name. These are based on separate
relationships between the input screen and the "Aircraft" and
"Airlines" forms.
The input screen's "UNI" field can now be made invisible with
no user entry and derived:- Jointext(knownas,name).
A relationship is entered between the input screen and the
"Userlist" form linking the "UNI" fields and all the required
details can then be derived :- lookup(userlist,whatever).
- 58 -
................................................................................
Conditional Lookups Conditional Lookups
Occasionally you may wish to use a single field either to
initiate a lookup or to accept direct input from the keyboard.
For example on an input screen to a procedure that enters
invoice lineitems there is a field Partname which is related to
the Name field in the "Parts" form. The entry to this field
initiates a primary lookup for its own value and a secondary
for the Price field. The user enters the first few characters
of the part name followed by an *, then chooses the part name
from the lookup list. If you also wish the user to be able to
enter a partname that is not in the parts form then derive the
partname field:-
If(Intext(Partname,"*") > 0,Lookup(Parts,Name),Partname)
If the user enters an * anywhere in the field then a lookup
will be done from the parts form, but if he does not enter an *
then the field will retain whatever name he entered.
If you wish to be able to tell whether or not a lookup has been
made for use in the procedure code - perhaps to add the new
part to the parts form - then use a special character other
than the * as the condition.
For example, if you derive Partname as:-
If(Lefttext(Partname,1) = "+",Partname,Lookup(Parts,Name))
then any entry to the field which starts with the "+" character
will not initiate the lookup. You can then use the fact that
the partname starts with a + to enter a new record in the parts
form.
Declare variables
NN as text
end
NN = Input.partname
If Lefttext(NN,1) = "+" then
NN = righttext(NN,Lengthtext(NN)-1)
For parts new record
Parts.name = NN
Next
End if
for Invoicelines
copy all from input
Partname = NN
next
- 59 -
................................................................................
CORRECTING STATS. CORRECTING STATS.
If you write an application in which records are entered via
procedures and "running" statistics are kept, you will have to
provide procedures which allow the user to correct any mistakes
he has made.
For Example: - In a "Time Sheets" application the user enters a
time and customer on the input screen of a procedure. The
procedure then calculates the charge, writes the charge and
customers name to the "Timesheet" form, adds the charge to the
"Balance" field in the "Customers" form and also adds it to the
"Total" field in the "Workinhand" form.
If the operator makes an error then correcting the entry in the
"Timesheet" form is simply a case of updating it but to correct
the "Balance" and "Total" fields you must add the corrected
value and subtract the old incorrect value.
To get the two values together for your procedure, create an
input screen where the operator enters the "line" ("line" is
the unique sequenced field in "Timesheet"). Then create two
fields for the values. The first, "oldval" is derived
lookup(timesheet,charge) and the second, "newval" is derived
default(lookup(timesheet,charge).
The "Oldval" field can be invisible and has no user entry.
You would also add two similarly derived fields "Oldcustomer"
and "Newcustomer".
When the user edits the "Newval" and/or "Newcustomer" field and
presses F2 , all the required values are available to the
procedure code:-
pause off : escape off
for timesheet with line = input.line
timesheet.charge = input.newval
timesheet.customer = input.newcustomer
update record
next
for customers with name = input.oldcustomer
customers.balance = customers.balance - input.oldval
update record
next
for customers with name = input.newcustomer
customers.balance = customers.balance + input.newval
update record
next
for workinhand
workinhand.total = workinhand.total+input.newval-input.oldval
update record
next
- 60 -
................................................................................
CREATING RUNTIME CREATING RUNTIME
To create a distributable application with the Easy Base
Royalty free Runtime Module, first, ensure that your
application has a user menu with a start up password. If you
wish your runtime application to start without a sign on screen
then this password should be "Autostart".
Make a new directory for your module and copy all the files
from the Easy Base sub directory in which you developed the
application to it.
Copy the Configuration file "EB.SET" from your Easy Base
directory to this directory.
Insert the Runtime Module disk in a floppy drive. Change to
that drive and type "MODULE".
The "Module" program will first ask you for the path to the
application files. Once you enter this it will unpack the
runtime files into your new directory.
It will then ask for the name of your application. The name you
supply here will be displayed on any sign on screens and also
on the shutdown "Thank you for using - " line.
It will then ask you for your copyright line. The text you
enter here will replace the line "Application of Easy Base -
Not for Resale" which appears above your menus.
Finally, you will be asked for the Executable file name you
wish to use for your program.
When you have entered the details - Press F2 and your
application will be complete and ready to sell.
--------------------------
EASY INSTALL UTILITY
For professional distribution disks just like the ones Easy
Software is distributed on, you can purchase Easy Install.
This utility will compress your application and create a
distribution disk with an install program customized for your
application.
- 61 -
................................................................................
CUSTOMIZE HELP LINE CUSTOMIZE HELP LINE
You can replace the default help line (bottom line) in both
data entry and procedure input screens.
Press F6 in form or input screen design to access the help
line.
If you wish to revert to the default help line just erase your
customized one.
The line which you enter here becomes the default but is
overridden when the cursor is in any field with a Help prefix.
- 62 -
................................................................................
CYCLIC PROCEDURES CYCLIC PROCEDURES
In many applications you will come across the situation where
you need a procedure which will perform the same actions on a
given set of records. For example, in a payroll system the
procedure which calculates the employees wage and deductions
has to be repeated for each employee so that their hours can be
entered. If you simply enter each employees Worksno and lookup
his or her details then it will be easy to miss an employee or
to do one twice.
To avoid this you can create a procedure which will cycle each
employee through the input screen and terminate when all
employees have been processed.
On the employees form, add a field "Cycled" which is a single
character indexed field derived :- Default("N").
On the procedure input screen add an invisible field "Cycled"
which is derived "N"
You now enter two relationships between the procedure and the
employees form. The main relationship "Employees" links the
fields "Worksno" and the second, lets call it "Cycled" links
the "Cycled" fields.
On the input screen you derive the "Worksno" field as
Lookup(cycled,worksno) and all the other details as
lookup(employees,Whatever).
When you run the procedure, the first employees details will be
loaded automatically and all you have to enter are his hours.
To have the next employee loaded after you run the procedure,
the procedure code simply includes the lines:-
for employees with worksno = input.worksno
employees.cycled = "Y"
update record
next
When all employees have been processed the "Worksno" field will
derive blank as there are no employees with "N" in the "Cycled"
field. You can therefore pass a "finished" message by altering
the derivation of "Worksno" to :-
if(lookup(cycled,worksno)=blank,blank[beepAll Employees have
now been processed],lookup(cycled,worksno))
To reset cycling for the next payroll you write an additional
procedure with the code:-
for employees
employees.cycled = "N" : update record
next
- 63 -
................................................................................
Data Type Conversion Data Type Conversion
In Easy Base, modifying the structure of a data file after it
contains data is very easy and flexible. If you select Modify
Existing Form from the Forms menu you can add fields, delete
fields, change field order, change field lengths and Easy Base
will reformat your existing data automatically.
You can NOT however change data types simply by changing the
field type. If you change a field type and save the form you
will almost certainly lose the data that was in that field.
(Other than changing from one numeric type to another)
If you work entirely within Easy Base there is no reason why
you should ever need to change a field type. However, if you
have imported data from Dbase or Fixed Length ASCII you may
find yourself with numeric or date values held in text fields.
The procedure for converting data from one type to another is
as follows:-
1. Select Modify Existing Form
2. Add a new field of the desired type with a derivation
formula such that it will derive its value from the field
of the old type.
3. Save the form.
4. Select Modify the form again.
5. Cancel the derivation formula in the new field and delete
the old field.
6. Re save the form.
To derive a numeric field from a text field the derivation
formula is simply the text field name.
To derive a date field from a Dbase imported date in a text
field called DT the formula is:-
Makedate(midtext(DT,5,2),midtext(DT,7,2),midtext(DT,3,2))
Version 3.10
From V3.1 you can change field types between text and numeric
and retain any numeric values that were in the field
automatically . You still cannot change a field type from date
or time to text or vice versa without following the above
procedure.
- 64 -
................................................................................
DUPLICATE PREVENTION DUPLICATE PREVENTION
1. Where "Blank" values are acceptable.
Quite often you will come across a situation where a field must
not have duplicate entries but can still be left blank. You
cannot define this field as unique because that would prevent
more than one blank entry. A good example of such a situation
is in the "Menus Form" of Easy Base. The definition and unique
field is the "Menu Title" but no two records may have the same
entry in the sign on "Password" field.
To prevent duplicate entries other than blanks you must enter a
relationship between the form and itself with the field to be
tested as the related field in both primary and secondary
forms.
The field is then derived as :-
If(lookup(menus,password) <> blank,blank[beepDuplicate Password
!],password)
2. When entering records via procedures.
When you use a procedure to enter a new record to a form it is
not automatically checked as "Unique". To ensure that
duplicate entries are not entered via procedures you must check
that the data entered on the procedures input screen is unique
to the form you are about to enter it to before running the
procedure. For example: If you were about to enter a record to
the "Manufacturers" form in which the "Name" field was unique
then the "Name" field on the input screen would be derived:-
if(lookup(manufacturers,name) <> blank,blank[beepDuplicate
Name !cursor name],name)
- 65 -
................................................................................
FORM LETTERS FORM LETTERS
To print form letters (circulars) with a different address and
salutation for each entry in an address form simply type the
entire letter between the .List Items and .End of the output
format.
.........................procedure code........
Declare output fields
Addr.name : Addr.street : Addr.town
Addr.salutation
date
end
date = datetext(system date)
for addr
print list items
page feed
next
.........................output format........
.List Items
My street
My county
{date field }
{Addr.name field }
{Addr.street field }
{Addr.town field }
Dear {Addr.salutation},
You are invited................................
...................................................
...................................................
..........................................
Yours faithfully,
Fred A Blogs
.End
Although this is the fastest way to produce a short form
letter, the Format Editor is not the nicest place to write
text. If you want the benefits of word wrap and spell checking
then you can create a form in which to write the letter. Create
text block fields to hold a page of text and a name field so
that you can store many different letters and print them with
the same procedure. If your letters are to be more than one
page long then put the same name on each page.
- 66 -
................................................................................
FORM LETTERS FORM LETTERS
To print the form letters from the "Letters" form your
procedure must now have an input screen which looks up the name
of the letter to be printed.
'............................CODE.....................
declare output fields
addr.name : addr.street : addr.town :addr.salutation
date :letters.block1 :letters.block2 :letters.block3
end
declare variables
page as number
end
date = datetext(system date)
for addr
page = 0
for letters with name = input.name
page = page + 1
if page = 1 then print list items
if page > 1 then print extra
page feed
next
next
The output format is similar to that shown on the previous page
but the text in the .list items section is replaced by the text
block fields Letters.block1 ,letters.block2 and letters.block3
and an additional section .extra is added which has the same
text block fields but no address or salutation.
- 67 -
................................................................................
GLOBAL DEFAULTS GLOBAL DEFAULTS
In many instances, an application will use the same default
values in many procedures and field derivations. If you
"hardwire" these as constants into your procedures and code
then they will all have to be changed when the default value
changes.
Easy Base is supplied with a single global defaults form for
VAT rates but you can create your own for any particular
application.
For instance, should you write a payroll system you would wish
to be able to update the tax rates and bands globally
throughout your application when they change.
To do this, create a form to hold all the global defaults. In
addition to the default fields add a single character text
field derived "X" and index it. You then enter a single record
with all the default values. The "X" field is there to create
an artificial relationship between any input screen and the
defaults form in order to lookup defaults.
Wherever you need one or more global defaults in an input
screen you simply add an invisible "x" field and enter a
relationship between the procedure and the defaults form
linking the "x" fields.
The field "Tax" can now be derived:-
taxablepay * lookup(defaults,taxrate)
Similarly, you can pre load variables in procedure code for the
default values:-
Declare variables
Taxrate1 as number:Taxrate2 as number
Taxband1 as number:Taxband2 as number
end
for defaults
Taxrate1 = defaults.taxrate1 :Taxrate2 = defaults.taxrate2
Taxband1 = defaults.taxband1 :Taxband2 = defaults.taxband2
next
When the taxrates change you only have to alter them once in
the Defaults form.
- 68 -
................................................................................
Input Screen Format Input Screen Format
All form and input screens can be presented either mounted in a
window against a mottled background or exactly as drawn in form
design. The windowing effect is done automatically if you leave
a clear border around all text and fields. If you place fields
or text anywhere against the edge of the screen (even invisible
fields) then the window effect will not be invoked.
If you do not want the window effect but you still wish to
leave a clear border then you should place the invisible text
character (ASCII 255) in the top left hand corner of the
screen to disable it. To produce the invisible character hold
down the Alt Key and type 255 on the numeric keypad.
- 69 -
................................................................................
Invoicing/Ordering Invoicing/Ordering
To create a simple order processing or invoicing system you
need forms for :
Stock (ID#,descrip,price,qtyonhand etc)
Customers (ID#,name,address etc)
Lineitems (Customer ID,Item ID,Qty,price)
Last (Single record with Last invoice/order number)
Current (Single record for current Cust ID/Invoice No)
Both of the forms "Last" and "Current" also have a field called
"X" which is a single character indexed text field containing
the character "x"
You also need three procedures:
SelectCustomer
EnterItems
PrintInvoice
The first procedure has an input screen on which you verify the
Customers ID# for the invoice. Whether you do this by entering
the ID# and looking up the name and address to verify it or by
using a primary lookup on the customers name is up to you.
The input screen also has an invisible single character text
field which is derived "X" and an InvoiceNo field. As well as
the relationship to lookup the customers name, the input screen
is also related to the Last form linking the "X" fields.
The InvoiceNo field is derived Lookup(Last,InvoiceNo) + 1
When you have looked up the Customer you run this procedure
which has the code:
...................................................
For Last
Last.Invoiceno = Input.Invoiceno : Update Record
Next
For Current
Current.Invoiceno = Input.Invoiceno
Current.CustomerID = Input.CustomerID
Update Record
Next
Run EnterItems
..............................................
The second procedure "Enteritems" now takes over and it has an
input screen where you lookup items from your stock form
together with their price, and enter the quantity. This
procedure has a repeating input screen. It is used to enter one
line at a time into the LineItems form. You must also nominate
a function key which will be used to run the PrintInvoice
procedure when all invoice items have been entered. A suitable
default help line might be:-
- 70 -
................................................................................
Invoicing/Ordering Invoicing/Ordering
"F2=Enter Invoice Item F4=Print Invoice F10=Cancel"
It is important that the user should not terminate this
procedure with the escape key so you should disable it and the
other function keys in one of your field derivations:
Disable "Esc5789"
Like the SelectCustomer procedure this screen also has an
invisible "x" field - no entry and derived "X". This time it is
related to the X field in the Current form. There are fields
for InvoiceNo and CustomerID. Both are no entry and are
derived: Lookup(Current,InvoiceNo) Lookup(Current,CustomerID)
The main relationship of course is to the Stock form to lookup
the stock item and price. Again, like the first procedure, it
is up to you whether you enter stock ID#s and lookup the
description and price or do a primary lookup on the Stock
Descrip field. This procedure writes a new record to the
LineItems form if F2 is pressed, runs Printinvoice if F4 is
pressed and "Tidies Up" if F10 is pressed.
................................................
If Fun_Key = 4 then run Printinvoice
If Fun_Key = 10 then
for LineItems with InvoiceNo = Input.InvoiceNo
Delete Record
Next
For Last
Last.Invoiceno = Last.Invoiceno - 1 : Update record
Next
Run SelectCustomer
End if
For LineItems new record
Copy all from Input
Next
..............................................
The third procedure "PrintInvoice" is run when the user presses
F4 and has the Following code.
Declare output fields
Customers.Name : Customers.Address
LineItems.StockID : LineItems.Descrip : LineItems.Qty
LineItems.Price
LineTotal : SubTotal : Tax : GrandTotal
InvoiceNo : CustomerID
End
'............Get Nos from Current
For Current
InvoiceNo = Current.Invoiceno
CustomerID = Current.CustomerID
Next
- 71 -
................................................................................
Invoicing/Ordering Invoicing/Ordering
'.......Print Customer details to invoice header
For Customers with ID = CustomerID
Print Report Header
Next
'.................Print Invoice Lines...
For LineItems with InvoiceNo = InvoiceNo
LineTotal = LineItems.Price * LineItems.Qty
SubTotal = Subtotal + LineTotal
Print List Items
'........Update Stock on hand
For stock with ID = LineItemsID
Stock.Qtyonhand = Stock.Qtyonhand - LineItems.Qty
Update Record
Next
Next
,..................Report Footer
Tax = VATon(SubTotal)
GrandTotal = Subtotal + Tax
Print Report Footer
Page Feed
Notice that the Quantity on hand field in the stock form is not
updated until you actually print the invoice. You could have
done it while you were entering the Line Items but it would
make the tidying process more complicated if the invoice were
cancelled with F10 after items had been written.
- 72 -
................................................................................
Keyword/Text Search Keyword/Text Search
If you have a database with a large number of items where the
user would be unlikely to know exactly what he is looking for
you will need to provide a search facility based on text
supplied by the user. There are two main ways to do this and
both have advantages in different situations.
Suppose you have a form for technical publications. There are
fields for Name, Publisher, Price, Short Description Etc. A
user wishing to search this form will not know the contents of
any of the fields - he will only know the topic or subject
which he wants to look up.
You need to get some search text from the user, find the names
of any publications which may cover the subject then make a
short list of them in the PickList form.
The simplest way is to have an input screen field where the
user can enter search text, then search the "ShortDescrip"
field for the occurrence of the text he has entered. Wherever
his text is found you add a new record to the PickList form.
The user can then mark the titles which interest him and you
can print out the short descriptions of the publications he has
chosen.
Clear records from PickList
for Publications
If intext(shortdescrip,input.searchtext) > 0 then
for PickList new record
PickList.Item = Publications.Name
next
end if
next
Show Picklist
For PickList with Mark = Chr$(251)
For Publications with Name = Picklist.Item
Print List Items
next
next
The advantage of this method is that the user is free to enter
any text and will get a "Hit" if it exists anywhere in the
description. The disadvantage is that every record in the
publications form has to be searched. This form of searching
becomes too time consuming if there are many thousands of
records. You can overcome the time problem in a large database
by adding a KeyWord form.
A KeyWord form has two fields, one for the publication name and
one for a key word. Each publication can have several entries
in this form with different key words. The Keyword field is
indexed so if you now search this form for the entered text you
will get a list of publications with the entered keyword very
- 73 -
................................................................................
Keyword/Text Search Keyword/Text Search
quickly. The disadvantage of this method is that the user will
only get a "Hit" if he enters a word that you have chosen as a
KeyWord.
You can optimize this method by choosing Keywords that might
contain text the user might enter within them. Eg use the
keyword "Installation" rather than "Install" and make your
routine select with >= rather than =
Declare variables
Len as number
end
Len = lengthtext(input.searchtext)
For Keywords with Key >= input.searchtext
if lefttext(keywords.Key,Len) <> input.searchtext then
exit for
end if
for PickList new Record
Picklist.Item = Keywords.Publication
next
Next
Show Picklist
For PickList with Mark = Chr$(251)
For Publications with Name = PickList.Item
Print List Items
Next
Next
Entering Keyword records can be incorporated into the procedure
which writes the Publications record to save time when entering
data.
For Publications new record
Copy all from input
Next
for Keywords new record
Keywords.Publication = Input.Name
Keywords.Key = Input.Keyword1
next
If Input.Keyword2 <> blank then
For Keywords new record
Keywords.Publication = Input.Name
Keywords.Key = Input.Keyword2
Next
End if
Repeat last section for the number of keywords on the input
screen.
- 74 -
................................................................................
LINKING APPLICATIONS LINKING APPLICATIONS
Procedures in one directory can access forms in another
directory or disk by placing the external forms path in
brackets immediately after the form name at the start of a For
Loop.
Ex.
For payroll (c:\pay) with posted = "No"
for purchaseledger new record
copy all from payroll
next
payroll.posted = "Yes"
update record
next
The above procedure, in an accounts application, imports data
from a payroll application in C:\PAY and updates the "Posted"
field in the payroll application.
Ex.
for sales (A:\) alias import
for sales new record
copy all from import
next
next
The above procedure is used to import data transferred from one
machine to another on floppy disk.
Note:-
1. If transferring data on floppy disk the floppy must hold
the forms .DAT and .DEF files together with the BASE.DIR from
the source application. If you need to move large amounts of
data on floppy it is much quicker to simply overwrite an import
forms .DAT file and then pack it to rewrite the indices.
- 75 -
................................................................................
MAXIMIZING SPEED MAXIMIZING SPEED
Because the procedures you create in Easy Base have to be
interpreted each time they are run they will tend to be slower
than similar routines created in a compiled system. This is the
unavoidable cost of ease of use. You can increase speed vastly
by having the best DOS environment and by the way in which you
write procedure code.
DOS Environment.
1. Do not use a disk compression system.
2. Always load "Fastopen" - The default settings are fine -
just add the line "fastopen C:" to your AUTOEXEC.BAT file.
3. Use a Disk Cacheing system - The more memory you can
allocate to it the better. Easy Software recommends
PC-Cache from Centre Point with 2 Megabytes of expanded
memory allocated. Smartdrive (Version supplied with
Windows 3.1) was slightly faster but caused widespread
disk corruptions during test "Power Failures".
4. Do not run any TSR programs (Especially Virus Checkers).
Procedure Code.
Avoid making calculations and derivations within "For" loops in
procedures.
If, for example, you had a form in which was recorded the
length, breadth and depth of various blocks and you knew that
at some point you would write a procedure which listed their
volume. Add a field for volume to the form and derive it from
the other fields. When you write the procedure you will simply
list this field. If the field had not been added to the form
then you would have to calculate its value on each iteration of
the "For" loop.
The time taken to derive each individual "Volume" field during
record entry will not be noticeable but the time taken to
derive the volume for every record during the procedure will.
Keep "Running statistics". If your program requires statistics
derived from many hundreds or even thousands of records then
having to wait for a procedure which calculates them each time
you want up to date figures is a real pain.
To keep "running statistics" create a form with a field for
each statistic you require and enter a single record with zero
values in each field. Make all entries, modifications and
deletions to your data via procedures and you can update your
statistics each time a record is added, modified or deleted.
Example on next page.
- 76 -
................................................................................
MAXIMIZING SPEED MAXIMIZING SPEED
The following procedure code enters a record (collected via the
input screen) to a purchases ledger and updates statistics used
in the profit and loss account. It also updates the balance for
the suppliers account.
pause off : Escape off
for purchases new record
copy all from input
next
for stats
if input.type = "Invoice" then
stats.creditors = stats.creditors + input.amount
end if
if input.type = "CreditNote" then
stats.creditors = stats.creditors - input.amount
end if
if input.type = "Payment" then
stats.creditors = stats.creditors - input.amount
if input.paidby = "cash" then
stats.cashbalance = stats.cashbalance - input.amount
else
stats.bankbalance = stats.bankbalance - input.amount
end if
end if
next
for ACbalances with supplier = input supplier
if input.type = "Invoice" then
ACbalances.balance = ACbalances.balance + input.amount
else
ACbalances.balance = ACbalances.balance - input.amount
end if
next
Whenever you need to know statistics for "Debtors", "Cash
Balance" etc you can produce them instantly with a procedure
which simply lists data from the statistics forms.
Whenever you use running statistics in this way you should also
create a procedure which does calculate them from the raw data.
If you ever, for one reason or another, have to edit data
directly in "Data entry" then your "running statistics" will no
longer be accurate. You can run this procedure to correct them.
- 77 -
................................................................................
MULTIPLE COLUMNS MULTIPLE COLUMNS
You may occasionally need to list data in order but in more
than one column. Indexes for technical manuals are a common
example. It would be nice if you could send the printer head
back to the top of the page for each column but you can't. You
must therefore get all the data for each horizontal line into
memory at the same time and then print it.
The following example prints the "Title" field from a "Films"
form in alphabetic order in two columns with fifty lines on
each page. To do this a field "No" is added to the form. This
is an integer field and it is indexed.
declare output fields
films.title : righttitle
end
declare variables
x as number : y as number : lasttitle as text
end
'................UPDATE THE No FIELD......
for films with title in order
y = total records
x = x + 1
display status "Updating No field record" + x + "of" + y
films.No = x
update record
next
'.................PRINT IN TWO COLUMNS.................
x = 0 'reuse x as counter
do
for films with title > lasttitle
x = x + 1
for films alias col2 with No = films.No + 50
righttitle = col2.title
next
print list items
lasttitle = righttitle : righttitle = blank
if mod(x,50) = 0 then
page feed : Exit for
end if
next
if lasttitle = blank then exit do
loop
........................Format..................
.list items
{ Films.title field } { Righttitle Field }
.end
- 78 -
................................................................................
Q AND A INPUT SCREEN Q AND A INPUT SCREEN
If, for a procedure you have to collect many items of data via
an input screen, then presenting all the fields and their
labels at once can be confusing to an operator. You can start
with an empty screen other than the first field and its prompt
then have each subsequent prompt "Pop up" when the previous
field has been filled.
To do this you make all your input fields without a background
(Text, Alt1 or Alt2) and you create fields for the prompts
which have no user entry and also show no background.
Ex.
To collect data for paymethod, customer, and amount lay out the
following fields:-
Enter Method of payment.... { Paymethod Field }
{ Pop1 Field } { Customer Field }
{ Pop2 Field } { Amount Field }
The "Pop1" field is derived:-
If(Pop1 = blank and paymethod = blank,blank,"Enter Customers
name.........")
and the "Pop2" field is derived:-
If(Pop2 = blank and customer = blank,blank,"Enter Amount...
...............")
- 79 -
................................................................................
RUNTIME AUTO START RUNTIME AUTO START
If you intend to distribute an application using the Easy Base
Runtime Module, you can have the module start automatically on
a particular user menu by giving that menu the sign on password
"Autostart".
Each time the runtime module starts it searches for a menu with
this password. If it finds one, it skips the sign on screen and
starts automatically on this menu.
The "Autostart" password has no significance while developing
in Easy Base. It is treated as any other sign on password.
- 80 -
................................................................................
SET SYSTEM VALUES SET SYSTEM VALUES
The System values System date, System Time and Output can be
set within procedure code.
Ex.
System Date = input.date
Ex.
If input.print = "Yes" then Output = "Printer"
Setting the output from an input screen field means that the
user can change the output destination without having to exit
back to the menu in procedures which have repeating input
screens.
If you have several procedures which are individually run to
the screen but you also wish to batch execute them to the
printer, you can achieve this by including the line:-
If Global number = 2 then output = "Printer"
then placing the procedures on a batch execute menu which
begins with a procedure setting Global Number to 2. and ends
with one re setting it to zero.
- 81 -
................................................................................
TABULATION TABULATION
To create a printout in which fields are enclosed within a
lined table use the linedrawing facility in the format editor
to create a page header and page footer containing the top and
bottom of the table and insert only the vertical lines between
the fields in the list items section.
Ex.
Declare output fields
stock.name : stock.price
end
print page header
for stock with name in order
if bottom margin < 0.7 then
print page footer
page feed
print page header
end if
print list items
next
print page footer
Page feed
........................format.........................
.page header
╔════════════════════╤═══════════════╗
║ Name │ Price ║
╠════════════════════╪═══════════════╣
.list items
║ {Name Field } │ {Price Fld. } ║
.page footer
╚════════════════════╧═══════════════╝
.end
- 82 -
................................................................................
TOTALS & SUB TOTALS TOTALS & SUB TOTALS
To produce totals and sub totals in printouts use ad hoc fields
to hold the values and increment them during each iteration of
the output loops. The following code lists all entries in a
clients time sheet form with the cost of work in hand totalled
and sub totalled for each client.
Declare output fields
Clients.Name:Timesheet.Hrs:Timesheet.Mins:Timesheet.Amount
Timesheet.date : Subtotal : Grandtotal
end
Print Report Header
for Clients with name in order
Print Group Header
Subtotal = 0
For Timesheet with Acno = Clients.Acno
Subtotal = Subtotal + timesheet.amount
Grandtotal = Grandtotal + Timesheet.amount
Print List Items
next
Print Group Footer
next
Print report footer
.......................Output Format.........................
.Report Header
═════════════════════════════════════════════════════════
Work in Hand Totalled by Client
═════════════════════════════════════════════════════════
.Group Header
██████████████████
.List Items
████████ ██Hrs ██Mins ██████
.Group Footer
──────────
Total for ██████████████████ ██████████
══════════
.Report Footer
═════════════════════════════════════════════════════════
Total Work In Hand ██████████
═════════════════════════════════════════════════════════
.end
The field in the Group Header is Clients.name
The fields in List Items are Timesheet.date, Timesheet.Hrs,
Timesheet.Mins and Timesheet.amount.
The fields in Group Footer are Clients.name and Subtotal.
The field in Report Footer is Grandtotal.
- 83 -
................................................................................