Beruflich Dokumente
Kultur Dokumente
Jumpstart 4D
especially
if you come from a FileMaker Pro ®
to 4D on an enlightening and
highly readable journey to a
Press ™
Learning to program within one of the world's most renowned • The most comprehensive
development environments just got easier. Jumpstart 4D, the newest beginner's guide to 4D
book by longtime 4D developer Steve Hussey gives those who are new available
to 4D the strong foundation they need to successfully develop and
strengthen their 4D development skills. Hussey's expertise in 4D shines • Easy to read, step-by-step
through his insightful explanations of the basics of 4D development. format
Step-by-step, Hussey takes readers through all of the features that
4D has to offer, from creating a new database to adding related tables
to refining an end application. Whether you're new to database
programming or just new to 4D, Jumpstart 4D is the perfect guide for
exploring and realizing the possibilities of one of the richest database
• Written for people new to 4D
and programming
• Teaches you all you need to
Jumpstart 4D
applications around. know to start developing
your own databases in
"I really enjoyed Jumpstart 4D. It gave me a great minutes
start in understanding and using the basics of 4D • Loaded with time-saving tips
Steve Husseys
development. This is an excellent book for 4D users and useful hints to make
who are just starting out." ~ Robert Reed database programming a
University of Texas, Austin
snap
•••••
• Build a powerful working
"Jumpstart 4D delivers what you need to get going
Steve Hussey
application using 4D in a few
in a simple, no-nonsense way." ~ Nicholas Daum
RDBMS Consultant hours
••••• • Covers the entire process of
"After working through the book you'll have a very creating a 4D database appli-
respectable knowledge of 4D as well as a really cation including developing,
compiling, and deploying
clever invoicing system that you created yourself."
~ Kim Kohen
and much, much more...
Steve Hussey is a prolific author on the subject of 4D; in addition ISBN 0-9712895-1-4
to many books on 4D, he has written numerous articles for 90000
Dimensions: The Journal of 4D and 4D WebSTAR, and
technical notes for 4D, Inc. He is a popular speaker at
the 4D Summit conferences, and regularly trains people
in 4D across the United States and Canada. In March 2001, Steve
Press ™
PRESS.4D.COM
became the editor and publisher of Dimensions. He lives on a small
island off the coast of Washington state.
9 780971 289512 Press ™
Jumpstart 4D
especially
if you come from a FileMaker Pro ®
to 4D on an enlightening and
highly readable journey to a
Press ™
Learning to program within one of the world's most renowned • The most comprehensive
development environments just got easier. Jumpstart 4D, the newest beginner's guide to 4D
book by longtime 4D developer Steve Hussey gives those who are new available
to 4D the strong foundation they need to successfully develop and
strengthen their 4D development skills. Hussey's expertise in 4D shines • Easy to read, step-by-step
through his insightful explanations of the basics of 4D development. format
Step-by-step, Hussey takes readers through all of the features that
4D has to offer, from creating a new database to adding related tables
to refining an end application. Whether you're new to database
programming or just new to 4D, Jumpstart 4D is the perfect guide for
exploring and realizing the possibilities of one of the richest database
• Written for people new to 4D
and programming
• Teaches you all you need to
Jumpstart 4D
applications around. know to start developing
your own databases in
"I really enjoyed Jumpstart 4D. It gave me a great minutes
start in understanding and using the basics of 4D • Loaded with time-saving tips
Steve Husseys
development. This is an excellent book for 4D users and useful hints to make
who are just starting out." ~ Robert Reed database programming a
University of Texas, Austin
snap
•••••
• Build a powerful working
"Jumpstart 4D delivers what you need to get going
Steve Hussey
application using 4D in a few
in a simple, no-nonsense way." ~ Nicholas Daum
RDBMS Consultant hours
••••• • Covers the entire process of
"After working through the book you'll have a very creating a 4D database appli-
respectable knowledge of 4D as well as a really cation including developing,
compiling, and deploying
clever invoicing system that you created yourself."
~ Kim Kohen
and much, much more...
Steve Hussey is a prolific author on the subject of 4D; in addition ISBN 0-9712895-1-4
to many books on 4D, he has written numerous articles for 90000
Dimensions: The Journal of 4D and 4D WebSTAR, and
technical notes for 4D, Inc. He is a popular speaker at
the 4D Summit conferences, and regularly trains people
in 4D across the United States and Canada. In March 2001, Steve
Press ™
PRESS.4D.COM
became the editor and publisher of Dimensions. He lives on a small
island off the coast of Washington state.
9 780971 289512 Press ™
To all the staff at 4D, Inc. in San Jose, and 4D SA in France, with a special
mention to Doris Beaulieu, Brendan Coveney, Ray Manley, and Tim
Tonooka. A special thanks to John Beaulieu at PDM Inc. for Monkey-
werks and hosting the 4D NUG.
As always thanks goes to the people who selflessly donate their time and
wisdom to helping others via the lists: Dave Adams, Liz Delgado, Jeff
Kain, Doug Blew, Steve ‘Bad Chickens’ Willis, and too many others to
mention.
Jumpstart 4D
Table of Contents
Label Wizard 4 – 16
Final Thoughts 4 – 18
Improving the Custom Menus Environment 5–1
Creating a Splash Screen 5–1
Calling 4D’s Editors from Your Menus 5–3
Creating a Quick Find 5–5
Tidying Up Your Forms 5 – 17
Adding a Non-Related Table 6–1
Creating the New Table 6–2
Creating the Object Method 6–8
Changing the Data Entry Order 6 – 11
Summary 6 – 12
Adding Related Tables 7–1
Adding the Key to the Contact Table 7–3
Defining the New Tables 7–4
Creating the Invoice_Item Subform 7–8
The Invoice Detail Form 7 – 10
The Invoice Subform 7 – 12
Modifying the Contact Form 7 – 13
Adding Code to Manage Everything 7 – 17
Enhancing the Invoice Form 7 – 22
Looking Up a Service Description from Another Table 7 – 31
Finale 7 – 34
Passwords 8–1
Creating a New User 8–2
Assigning a Password 8–2
Creating Groups 8–5
Controlling Access 8–8
Refining Your Application 9–1
Setting the Application Title 9–1
Setting Input and List Window Positions and Titles 9–4
Working with Invoices 9–9
Listing Invoices 9 – 12
Finding Past Due Invoices 9 – 16
Printing a Batch of Invoices 9 – 17
Assigning Menus When a User Logs In 9 – 20
Summary 9 – 22
Compiling a 4D Application 10 – 1
Preparing a Database for Compilation 10 – 2
Compiling an Application 10 – 5
Jumpstart 4D
sion, or at least read as far as Chapter 10. (Whatever you do, don’t attempt
a conversion while under time or cost restraints, or under pressure from a
customer!)
Everyone learns in a different way
Feel free to use this book in the way that suits you best. Find your own
way to learn. If you are interested in interactive, computer-based learning
materials for 4D, e-mail Steve Hussey ar shush@harborside.com.
Opening and Editing the Sample Databases
Some chapters have an accompanying database. These databases contain
the code that matches the relevant chapter. You can either create each
chapter’s sample database by following the instructions or use the sample
databases provided.
Some of the databases open in the Design Environment (this is the mode
where you edit the database) and some later databases are set to open in
the Custom Menus Environment (where you run the database but can-
not edit it). If you need to edit one of these databases, you can switch from
the Custom Menus Environment to the Design Environment as fol-
lows:
Mac OS
Option+f (lowercase f ) to move from Custom Menus Environment to
User Environment.
Command+Y (not case-sensitive) to move from User Environment to
Design Environment.
Windows
Alt+F4 (Function key 4)to move from Custom Menus Environment to
User Environment.
Control+Y (not case-sensitive) to move from User Environment to
Design Environment.
Inadvertently Launching 4D Runtime
If you install the full 4D package from the CD, you may have also
installed 4D Runtime.
1–2 Using Jumpstart 4D
Jumpstart 4D
If you are new to computers, you should become proficient in basic com-
puter tasks before you attempt to learn 4D. Trying to master the intrica-
cies of your computer and programming at the same time may cause
unnecessary anxiety!
Can You Use Your Computer?
Are you comfortable using your computer? Do you know how to do the
following?
+ Launch an application (program)?
+ Create an alias to it (on Mac OS) or a shortcut (on Windows)?
+ Copy files from CD to your hard disk, and move them from folder/
directory to another folder/directory?
+ Create new folders/directories and name them? (And find them
later?)
+ Delete files?
+ Use the mouse to select files (click once) and open them (double-
click)?
+ Navigate through folders/directories and save files from within an
application program?
Have you installed the Operating System (OS) correctly on your com-
puter, and do you have sufficient free hard disk space and RAM?
Installing 4D
Before you start to follow the examples in this book, you should install 4D
v6.7 and test it to see that it works. You can use one of the demonstration
applications provided on the CD to do this.
+ Install 4D, either from a copy downloaded from the 4D, Inc. Web
site, or from the product CD.
- You can use the trial version of 4D to complete the exercises in
this book.
+ Enter the Serial and Product ID numbers as required.
+ Set the memory usage on Mac OS, or use Customizer Plus to do the
same on Windows.
Absolute Beginners: Start Here 2–1
Jumpstart 4D
There is no hard and fast way to calculate how much memory you should
assign to 4D. As a rule of thumb, you could start by adding 8 to 16 MB to
the minimum size that 4D has set. If you experience crashes or unusually
slow performance, you can increase this setting. If you increase the
amount of memory, 4D can use any unused space for caching records –
this will speed up some database operations.
What is a Database?
Non-electronic databases have existed for hundreds of years. A dictionary
is a simple, printed database that allows you to look up the meaning of
words easily (as long as you have some clue as to how they are spelled). A
Rolodex card collection is another form of database. A very commonly
used database is a telephone directory. In a directory, the telephones are
listed by the last name of the subscriber. Immediately a major disadvan-
tage becomes clear: What happens if you don’t know the last name of the
person you are looking for? With a printed directory you would have to
start looking for the name from the beginning and read every entry until
you found the person you wanted.
Computer databases are a structured collection of data that can be
searched, usually by different criteria. In a computer database the data
would be split into separate fields: the first name, last name, address, city,
zip code, and phone number. This way you could search for the person by
any known value.
Some early databases were single file: Only one type of data could be
stored. These databases function like Rolodexes and are usually used as
such. They have limited use.
Later FileMaker Pro introduced the idea of having several files that could
share data between themselves. Data could be organized into logically sep-
arate files (known in FileMaker Pro terms as databases), but this data
could be copied from one file to another when needed. These types of
databases were an improvement from their predecessors but were still inef-
ficient as they duplicated a lot of data. If the data in one file changed, you
needed to decide whether the changes should be copied to the other files.
Relational databases moved down onto personal computers from main-
frame and mini computers. Relational databases were designed to be more
efficient since they split data into many tables that were related to each
specific data and so on. Some times it is not easy to decide what needs to
go into each table, and sometimes data is duplicated from one table to
another. In the strictest definitions of relational databases, you would
never repeat data, but sometimes it is more efficient to repeat it, especially
when generating reports.
To start the contact database you are going to create a single table to store
the contact details. You will name this table Contact. (Database tables are
normally named in the singular, using plurals does not cause any problems
but choose a standard and stick with it. Consistency is always good.)
Within this table you will be storing different fields about a single contact:
their name, address and so on. Each different item of data is stored as a
separate field. 4D can store up to 511 fields per table (probably more than
you would need). One way of defining your database is to create either an
outline or spreadsheet of your database, or use a design program such as
Visio (on Windows), to define the tables and fields.
Finalize the design before you start creating the tables and fields!
Once you have created a table or field in 4D it cannot be deleted.
Tables and fields can be renamed (without breaking anything), and
in most cases a field’s type can be changed (except subfields). The
name that you give a table or field affects where the name will
appear in some views (as many objects are listed in alphabetical
order). If you choose to rename tables or fields you should do this
after closing all open method windows.
The first list of fields for your contact table may look something like this:
Table 3-1: First List of Fields
Field
Name
Address
City
State
Zip code
Telephone
Field
Fax Number
Fields
Company Name
First Name
Last Name
Address Line 1
Address Line 2
City
State
Zip Code
Country
Telephone
Fax
By storing the company field and first and last names in separate fields you
will be able to search for them more easily later on. It is more efficient to
split an individual’s name into first and last. You will understand better
later when you have to query the database.
You may have noticed from the 4D documentation that 4D has different
field types for storing data: Integer, Longint and Text for example. There
are different field types to make storage and calculations more efficient. At
times you may be able to use one of several different formats. For example,
Integer, Longint and Real can all store numbers. There are differences
between all the field types that must be understood before defining the
field type.
Some field types can be changed at a later date. For example a field that is
defined as Alpha (80) can easily be changed to a Text field later, with no
consequences. (In most cases 4D will automatically convert the data.) If
you change a picture field to a text field however, you will lose the data in
existing records.
Subfields cannot be changed to a different field type. Think twice
before you create subfields!
Alpha (also known as alphanumeric or string) fields can contain letters,
numbers, and anything else you can type on the keyboard. Numbers that
are entered cannot be used in calculations unless you convert them to a
number first (unlike FileMaker Pro). The maximum number of characters
that can be entered into an alpha field is eighty while the minimum alpha
field length is two characters. Example: Jack Russell, Meat Loaf, 123 Main
Street. You would use alpha fields to store data like names, addresses, zip
codes, product names, short descriptions, and so on.
Text fields have the same limitations as an Alpha field, except that a text
field can contain up to 32,000 characters. Text fields cannot be indexed,
therefore searching text fields can be slow. Text fields are used where you
need to store lots of text – long descriptions, driving directions, the con-
tents of an e-mail message and so on.
4D v6.7 text fields are limited to 32,000 characters, not 32,767 (32
KB).
Real fields can contain any number with any number of decimal places.
You can use real numbers in mathematical calculations. Examples: 5, -45,
3–4 Creating a Single Table Database
Jumpstart 4D
7843, 600, 450.586. They require 8 bytes per field to store. Real numbers
are used in calculations where you need a precise answer – dollar values,
temperatures, sizes, volumes, and so on.
Integers can contain only whole numbers (no decimal values are stored)
that are within the range -32,768 to +32,767. Examples: 45, -68, 32,000.
Integers require two bytes per field to store. Integers are not often used
since Longints (see below) have the same properties except they can store
much larger values. Integers were used to save RAM and disk space when
computers were short of both. You might use them to store values that you
know will always be small – days in a week or year, for example.
Longint (Long Integers) can contain only whole numbers (no decimal
values are allowed) that are within the range -2,147,483,648 and
+2,147,483,647. Examples: 5, 700, 44,895. Long integers require 4 bytes
per field.
Date fields can store dates in MM/DD/YYYY format (in the US). While
the dates are entered and stored in this format, they can be displayed in six
different formats. Dates must be within the range 01/01/100 to 12/31/
32767. Examples: 8/19/55, 12/31/99, 1/1/2000. (Note for users outside
the US: 4D stores dates based on your system’s date format.)
Time fields can store time in HH:MM:SS format. While the times are
entered and stored in this format, they can be displayed in five different
formats. Time values must be within the range 00:00:00 to
596,000:00:00. Examples: 1:11:00, 13:01:05, 315:35:52.
Boolean fields store true or false values. By default, a Boolean field is
false. Use a Boolean field when you need to store one of two values.
Examples: True or False, Male or Female, Paid or Unpaid.
Picture fields can store bitmaps and PICT images such as those created
with graphics applications like Adobe PhotoShop. Picture fields cannot be
indexed. Picture fields are also used to store documents created by some
4D plug-ins such as 4D Write (4D Write v6.5 and higher can also store its
documents in BLOBs with some advantages).
Subtable is not really a field type. A Subtable is a connecting point for
another special table that has its own subfields. The records entered into a
Subtable are part of the record that the Subtable belongs to. These are use-
ful for keyword indexes, for example, but can create many complications
Creating a Single Table Database 3–5
Jumpstart 4D
in your code. For example, data is harder to import, and export, and
report on.
BLOB (Binary Large Object) fields store raw, unformatted data. This
means you could use a BLOB field when none of the other field types are
appropriate. Because BLOB fields can hold any type of data in practically
any amount, they can be very useful once you understand some of the
commands in 4D’s programming language that allow you to manipulate
them. BLOBs are often used to store images, movies and sets. BLOBs
cannot be indexed or viewed. Each BLOB can store up to 2GB.
A BLOB requires the same amount of RAM as its size: a 2 GB
BLOB would require 2 GB of free RAM on your computer. Ouch!
The following table summarizes field types:
Table 3-3: Field Type Summary
Default
Field Type Minimum Maximum Indexable
Value
Launching 4D
Make sure that you have enough memory allocated to 4D before using it.
With the default memory allocation you will probably be able to open a
database and perhaps view a few records, but performance will be very
sluggish. The application will probably quit sooner, rather than later, with
a Type 2 memory error. (Type 2 errors are usually indicative of too little
application RAM.)
Opening an Existing 4D Database
If you choose to open an existing 4D Database you can do this two ways:
+ Launch 4D, then open the database using the File ¬ Open menu
item.
+ Double-click the database structure file.
You may wish to open one of the sample databases using either of these
methods.
If you are using a sample database from the CD you need to copy it
to your hard drive first. Files on CD are read only, since CD’s are
read-only media. You can view a database that is on a CD, but you
will be unable to add or modify records, or make any changes to the
structure. If you are using Windows, and you copy files from a CD,
you need to ensure that the file’s properties are not set to Read
Only.
Creating a New Database
Double-click 4D to launch it. 4D then displays a dialog offering you the
choice of creating a new database or opening an existing one:
Figure 3-1: Creating a New Database (Mac OS)
You now have a single table database. You can modify this empty shell to
create your own application.
Creating Tables and Fields
Since the first table was already created for you, you can modify this to
represent your contact table. The first task is to change the name. There
are two ways to do this:
+ Right-click on the name of the table (on Windows, or Con-
trol+Click on Mac OS), then select Table Properties...
+ Double-click on the name Table 1
In either case the Table Properties dialog is displayed.
Creating Fields
Your first task is to decide on your field types for each field.
Table 3-4: Field Types
Field Type
Company_Name Alpha 40
First_Name Alpha 40
Last_Name Alpha 40
Address_Line_1 Alpha 40
Address_Line_2 Alpha 40
City Alpha 30
State Alpha 2
Zipcode Alpha 10
Country Alpha 30
Telephone Alpha 14
Fax Alpha 14
In this case all the fields have been defined as Alpha fields of varying
lengths. These are only suggestions – you can choose different lengths if
you need to.
4D uses variable length fields. If you define an Alpha field as (say)
80 characters, 4D will only store the amount of data actually used,
rather than the full 80 characters. If you later edit the field so that it
contains a greater number of characters, 4D will expand the record
size to store the new, larger amount of data. This is efficient in terms
of storage but causes a slight performance penalty. Defining the
length is really determining the maximum amount of data the field
will store. For instance, using Alpha 10 to store a nine digit zip code
(plus the hyphen) prevents the user from entering too many charac-
ters.
You can now type the first field name, Company_Name in the field name
area. Then tab to, or click into, the area next to the drop-down menu for
the type and overtype 20 with 40.
Alpha Yes
Text No
Date Yes
Time Yes
Real Yes
Integer Yes
BLOB No
Picture No
You can click and drag the lower border of the table to expand its size.
Figure 3-11: Table Without All Fields Showing
When the table does not show all the fields 4D will display up and down
arrows in the header area. You can use these to scroll up and down the
field definitions.
A practical hint: leave a blank line showing after the last field. When
you are viewing the tables in the structure editor you can easily spot
which is the last field.
Now that the table and field definitions are complete you will need to cre-
ate forms so that you can enter, view and edit data.
If you switch to the User Environment (Command+U on Mac OS or
Control+U Windows) 4D will attempt to create the forms for you, by dis-
playing the following dialog:
Figure 3-12: Form Creation Dialog
Click No for All to not create any forms for all the tables in the
database.
Click Yes for All to create both an input and output form for each
table you have.
Click No to not create any forms for this table only.
Click Yes to create both forms for this table.
If you have any tables that do not have an input and output form this will
happen every time you switch from the Design Environment to the User
Environment. Since this can get very irritating, you can stop this behavior
by setting a Database Property.
+ Select File ¬ Database Properties…
If the Forms tab is not the frontmost tab, then click it to bring it to the
front. (The Explorer is 4D’s way of navigating around some of the differ-
ent design tools.)
All defined tables are shown in the list (in this case only one). Currently
there are no forms for this table (if there were there would be a disclosure
triangle (on Mac OS or a “+” symbol on Windows) next to the table
name.
Creating a detail form
+ Click New to create a new form.
The New Form Wizard now appears. At this point you can type in a
name for the form. (Hint: append _dtl to the name if it is a detail form,
_lst if it is a list form, _dlg for a form called as a dialog and _prt for forms
used with print form.)
+ Make sure that Detail Form is selected from the Form Type drop-
down menu.
+ From the list of Available Fields on the left, drag and drop them
to the Selected Fields list on the right.
- Clicking the single right pointing arrow will move the selected
field to the Selected Fields list.
- Clicking the double right pointing arrow will move all the
fields to the Selected Fields list.
- Clicking the single left pointing arrow will move the selected
field from the list back to the Available Fields.
- Clicking the double left pointing arrow will move all the fields
back to the Available Fields list.
Notice that the available fields are listed in alphabetical rather than cre-
ation order. You can either move the fields over in the order you desire, or
move the fields and change their order afterwards (by dragging and drop-
ping).
Any fields shown as bold are indexed (you selected the Indexed attribute
when creating the field).
At this point you have two choices:
+ Click Advanced… to define further options for the form.
+ Click Edit to start editing the form immediately. (4D creates a sim-
ple form for you to start with.)
You can also click Use to start using the form immediately. (Again 4D
creates a simple form for you to start with.)
+ Click the Advanced… button to define further options.
Notice that the Form Wizard previews your form in the right-hand pane.
If you had chosen a different template in the previous step, you would see
a form with a different appearance.
Fields Tab
The first tab allows you to edit the fields to be displayed on the form and
also allows you to edit their order (if you haven’t already done so). As
before, you can either move, or drag and drop the required fields from the
Available Fields to the Selected Fields list.
Styles Tab
+ Click the Styles tab.
You can use the Styles Tab to define the styles for any of the form objects
listed on the styles drop-down menu:
Figure 3-19: Styles Drop-down Menu
Then in the Edit group area you can toggle between the fields and their
labels.
+ You can select a font, size, style, and justification for your fields
and labels.
+ You can select the Platform Interface for the fields/labels. This
determines the Operating System’s Graphical User Interface (GUI)
style to display the objects in.
+ You can then select an appearance for the objects. Enterable fields
are often set to Sunken.
You can easily create multiple style sheets. These also apply to any form
object that displays text such as labels, buttons, group objects, combo
boxes etc.
Options Tab
Figure 3-22: Options Tab
Buttons Tab
The Buttons tab allows you to automatically place 4D’s buttons on the
form. You can decide which buttons to place, and their position.
Figure 3-23: Buttons Tab
+ You can modify the form name before finally creating the form.
(The name must be unique to this table).
+ You can make a template from your form to speed up the creation of
new (detail) forms in the future. Templates help you create forms
with a consistent appearance.
+ Click Edit to create the form and open it in the Form Editor if you
need to make any minor adjustments).
You now have a detail (input) form ready to use. If you bring the Explorer
to the front, notice the Contact table now.
Figure 3-25: 4D Explorer: Forms Tab
There is an I next to the form name – this denotes that it is the default
input form. The Input Form option is checked when this form is selected.
If you have more forms you can select (highlight) one and select the Input
Form. That form will now be the default input form.
A form can also be both the Input and Output form – there will be a “B”
next to a form that is set up that way. To set this, select the form and check
both Input Form and Output Form. (This is not used very often.)
Tables do not have to have any forms. However once you have created a
form for a table you must have at least one, that is you cannot delete the
last form. The last form can be empty though. Empty forms take up little
space.
When you select a form, it is previewed in the right-hand pane. You can
toggle the preview pane on and off by clicking the preview switch:
Figure 3-26: Preview Toggle
Notice that since you have the Form Type set at Detail Form, 4D lists
your template in the Template used drop-down.
+ Change the form type to List Form.
+ Copy the desired fields from the Available Fields list to the
Selected Fields list as before.
+ Click Advanced… to use the Form Wizard.
The first two tabs, Fields and Styles, would be used in the same way as
when you created the detail form. The Options tab is slightly different for
list forms:
Figure 3-29: Options Tab
+ You need to set the target width for the list form: normally this
would be the same size as the detail form.
Now click the Buttons tab.
Again you can choose from several different styles of buttons, select which
button actions you need and decide on their placement.
+ Delete Selection – Deletes any records the user has selected.
+ Order By – Displays the Order by… Editor (sort editor) allowing
the user to sort The Records Being Displayed By Any Criteria.
+ Query – Displays the Query… Editor. Allows the user to find
records by any criteria. Also displays the new selection automatically
in the open list window.
+ Report – Displays the Quick Report Editor. Allows the user to cre-
ate quick reports based on the selection of records in the open list
window (probably after they have been found and sorted).
+ Show All – Lists all records in the table in the open list window.
+ Show Subset – Reduces the selection to display only those records
that the user had selected in the current list window.
+ Done – Closes the window and returns to 4D’s splash screen.
Click OK to close the form, and then Edit. You can now review or edit
your form as necessary.
+ Note that the buttons are all sized to fit the text, rather than being
the same size. You can correct this later.
3 – 30 Creating a Single Table Database
Jumpstart 4D
+ Note that the buttons have a black triangle through their upper left
corner. This indicates that the object (a button in this case) has an
object method attached.
A method is a set of programming instructions (like a script in FileMaker
Pro) that executes when something happens. In the case of a button, that
is (usually) when the button is clicked. You can examine the code for the
buttons:
+ On Mac OS Option+Click on the button (or object).
+ On Windows Alt+Click on the button (or object).
Remember it is not the buttons that execute the actions, but the code that
4D automatically inserted into these buttons. You can copy and paste the
buttons to other forms, or copy and paste the code within them to other
objects.
You should now have two forms completed. You can view them in the
Explorer. You need to check that one is defined as the Input Form, and
the other as the Output Form:
Figure 3-31: Input and Output Forms
If the forms are not set correctly for input/output, you can select the form,
and check the appropriate box.
Entering Data
You should now have two forms: one for input and one for listing data.
4D’s method for handling data entry is different from other programs
such as FileMaker Pro. 4D uses two different types of forms to display and
enter data:
+ List forms are for viewing data. They present data as a list of records,
where each line represents one record. Generally you will be able to
list a number of records using a list form.
+ Detail forms are for entering data. Double-clicking any record in the
list view opens the default detail form for that record. You will nor-
mally only edit one record at a time.
You can enter the User Environment to enter data into 4D. 4D will dis-
play the first table in the database using the default list form. The User
Environment is suitable for entering limited amounts of data, for exam-
ple for testing purposes. You can use the Enter ¬ New Record menu
item (Command+N on Mac OS or Control+N on Windows) or you can
use the Enter in List mode (Command+, on Mac OS or Control+, on
Windows) to enter records quickly but you lack control over what the end
user can do here. By pressing Command+Spacebar (on Mac OS or Con-
trol+Spacebar on Windows) the user can display a list of tables in the data-
base and switch to other tables. They could then add, edit or delete
records.
To present the user with a better interface, and to control what damage
they could do, you could create menus that would offer the user all the
options they needed, while restraining them from causing damage. After
you have created at least one menu, you can use the Custom Menus Envi-
ronment. This is the best environment for users to work in. Using the
Custom Menus Environment you can:
+ Display custom menus.
+ Display a custom splash screen. This image will be displayed when
that particular menu is current.
When an end user selects a menu item (or uses the defined keyboard
shortcut) 4D will automatically execute the project method that is
attached to the menu item.
+ On Mac OS 4D automatically adds both the Apple and the stan-
dard Edit menu (in fact you cannot delete them).
+ On Windows, 4D adds the standard Edit menu with the keyboard
shortcuts.
4D’s menu bar editor has not kept pace with the general development of
4D and has some restrictions:
+ Menus are numbered from 1 onwards. Menus cannot have names
but menu items do. When you delete a menu all subsequent menus
are renumbered. This means that code that refers to specific menu
numbers may break.
+ Menu items can only be one level deep: there are no hierarchical
menus.
+ Menu items can only have single letter keyboard shortcuts. Since
you should not use the standard five shortcuts (C,V, X, P, S) that
only leaves you with 21 other alphabetic characters. (You can also
use certain punctuation symbols, but certain symbols are treated as
meta characters and do not display, but do affect the appearance of
the menus.)
Menu bars and their associated menus and menu items are easy to set up,
but can be difficult to manage.
Remember that to use the Custom Menus Environment you must have
at least one menu bar defined. Also when you have finished your applica-
tion you will need to set a database property so that the database will start
up in the Custom Menus Environment, rather than the Design Envi-
ronment.
Creating a menu
Select the Menu Bar Editor from the Tools menu (there is no keyboard
shortcut):
Figure 3-32: Tools Menu
This will display the Menu Bar Editor (which can be resized):
Notice that 4D has also created the first menu (File) and an associated
menu item (Quit).
Any Menu Bar can have many Menus, and each Menu can have
many Menu Items.
These two items are italicized because they are special. If you Com-
mand+Click (on Mac OS) or Control+Click (on Windows) on the Menu
name (File) you will see the following:
Figure 3-35: Menu Names
The special format :79,1 means that 4D will open resource number 79
and use the contents of the first item in the resource as the name of the file
menu. By storing the names of the Menus and Menu Items in resources
you can more easily localize an application into a foreign language. Quit is
set up likewise. Understanding resources (especially for Windows users) is
beyond the scope of this book, therefore you can delete the string and type
File instead. Edit the Quit menu item likewise.
+ Select the Quit menu item and type Quit in the Method Name:
field.
+ Select Shortcut.
+ Type Q in the field next to the shortcut checkbox.
+ Leave Enabled checked (or the menu item will be disabled, and it
will appear grayed out in the menu).
+ Click OK.
The Quit project method opens:
Figure 3-39: Quit Project Method
Select QUIT 4D. This method is now complete (and it would be nice if
all methods were this easy). You can now close the method. You will now
see the 4D Explorer:
Environment. Now you will need to add further methods to enter and
edit data.
Creating a method to add a record
+ Select the Menu Editor from the Tools menu.
+ Click Add Menu.
+ Type Contact.
+ Click the Add Item button.
+ Type Add Contact as the name of the menu item.
+ Type CNT_Add in the Method Name: field.
+ Select all (Command+A on Mac OS or Control+A on Windows).
+ Copy to the clipboard (Command+C on Mac OS or Control+C on
Windows).
+ Command+M (on Mac OS or Control+M on Windows) – opens
the method editor.
+ Paste (Command+V on Mac OS or Control+V on Windows).
+ Click OK.
You now have an empty method window in which to create your own
method. Why the CNT_ to prefix the Add in the method name? 4D Lists
its methods in the 4D Explorer in alphabetical order. If you prefix your
contact methods with something like CNT_, they will all be listed
together in neat modules. Later when you add code to deal with invoices
you can prefix those methods with INV_ and so on.
What you use as a prefix is matter of taste, but consistency is good.
Type the following code:
repeat
add record ([contact])
until (ok=0)
At the end of each line press the Enter key. Note what happens.
When you press the Enter key, 4D tokenizes the line you have
typed. Tokenizing first checks that you have typed the command
correctly. If you have, it changes the command to bold text to show
that it has been recognized. Next the command you have typed is
stored internally as a token (symbol). This means that 4D does not
have to check each line of code as it executes it, it just executes the
+ Repeat will repeat all the code between it and the next Until com-
mand, until the condition is met.
+ ADD RECORD adds a record to the [Contact] table using the cur-
rent default detail (input) screen.
+ Until (ok=0) is a condition that keeps repeating the code between it
and the previous repeat command until the condition is met (that is
when the system variable ok becomes equal to zero).
The OK Variable
In the code above, you are testing the value of the OK Variable. This is a
special system variable that 4D sets in many different circumstances – if
the operation is successful OK is set to 1; if it fails it is set to 0. You can
test the value of the ok variable to see if the action succeeded or not. Vari-
able names are not case-sensitive in 4D: ok is the same as OK.
For example, on a detail form you can have 4D automatic action buttons
for Accept and Cancel. When you click the Accept button (to save the
record) the OK variable is set to 1. If you click the Cancel button (to dis-
card the changes) the OK variable is set to 0.
+ Each time the user clicks the Accept button 4D will accept (save)
the record. Since the OK variable is set to 1 the condition ok=0
evaluates as false, and the loop will be repeated.
+ When the user clicks the Cancel button (because they do not want
to create any more contact records) the OK variable is set to 0 and
the condition ok=0 will evaluate as true.
3 – 42 Creating a Single Table Database
Jumpstart 4D
The repeat loop ends. If there was another line of code after the Until
(ok=0) it would be executed next. Since there are no further lines the
method terminates. The user will now return to the splash screen and the
menus.
Creating a method to list records
+ Select the Menu Editor from the Tools menu.
+ Select the Contact menu.
+ Click Add Item.
+ Type List Contacts.
+ Type CNT_List in the Method Name: field.
+ Select all (Command+A on Mac OS or Control+A on Windows).
+ Copy to the clipboard (Command+C on Mac OS or Control+C on
Windows).
+ Type Command+M (on Mac OS or Control+M on Windows) to
open the method editor.
+ Paste (Command+V Mac OS or Control+V on Windows).
+ Click OK.
You now have an empty method window. Type the following code:
ALL RECORDS([Contact])
ORDER
BY([Contact];[Contact]Company_Name;>;[Contact]Last_Name;>;[Con
tact]First_Name;>)
MODIFY SELECTION([Contact])
This code:
+ Makes all records part of the current selection for the Contact table.
+ Sorts any records by Company_Name, then Last_Name, then
First_Name.
+ Displays the selection in the default list window (allowing the user
to modify those records).
Entering and Reviewing Sample Data
When you are in the Design Environment: you are able to make changes
to the design of the database.
+ Switch to the User Environment (Command+U on Mac OS or
Control+U on Windows).
Creating a Single Table Database 3 – 43
Jumpstart 4D
to
MODIFY SELECTION([Contact];*)
Summary
Parts of a 4D database
A typical 4D application consists of:
+ A number of tables (max 255) with field definitions for each table
(Max 511 per table).
+ Forms for viewing, entering, and printing data. Each form contains
objects such as fields, variables, buttons, etc.
+ Menus to provide an interface to the user. Menus call project meth-
ods.
+ Project methods to process the data and manage the forms.
So far you have created examples of all these different types of objects.
Now it’s time to let the old brain rest...
+ You query the table for all customers that have spent more than
$1,000 with you. None are found. The current selection is 0 (zero).
+ You query the table for all those customers who have purchased an
item this week. You find 10. The current selection is 10.
+ You list all contacts to print a telephone list. The current selection is
100.
Therefore for any table the current selection can be:
+ 0 records
+ 1 record
+ n records
+ All records
4D always has a current selection for all tables (and for all current pro-
cesses), even if this is zero records.
When you perform many tasks, they are applied to the current selection.
For instance, if you print a quick report it will print all the records in the
current selection, likewise if you print labels.
You normally create a current selection by performing a query. A query
performs some form of search on the records in your table and creates a
current selection based on the search criteria. For example, a query for all
contacts in San Jose builds a current selection of records from the entire
table that contains only those records for customers in San Jose.
Each table in the database can have only one current selection per pro-
cess. (This is a very important concept.)
If you are using a list form to display records, the list form will display all
the records in the current selection for that table. A detail form will only
display one of those records at a time. Just because you cannot see the cur-
rent selection does not mean that it is not there.
Most of 4D is about building current selections and then applying some
operation to the data in them. You will learn more about this essential
concept in further chapters.
One way of creating current selections is to use 4D’s query editors on the
Queries Menu in the User Environment.
Queries Menu
Query…
The Query… Editor is a general-purpose query (search) dialog that can
be used to perform simple or compound queries. You specify compound
queries using conjunctions between each query line. You can also save
queries to disk, and also restrict the query to the current selection of
records.
+ You can create compound searches linked with the And, Or, or
Except conjunctions.
+ You have the choice of searching the Current Selection of records or
all the records in the table. (The other three search methods always
search the entire table.)
+ You can save queries to disk and open them when you want to
repeat the query.
+ The Query… Editor remembers your last query. You can edit the
query or clear it and enter a new query.
+ You can search on fields in the current table or in related tables.
+ You can search on subfields in the current table or subfields in
related tables. If your database includes subtables, you can use sub-
fields in your queries. A query on subrecords creates a new current
selection of parent records, not subrecords. This group of parent
records contain at least one subrecord that meets the query criteria.
However, the query does not remove the other subrecords from the
parent record. All subrecords stay attached to their parent records.
The Query… Editor contains the following areas:
Criteria Area
This area displays the query as you create it, or after you load it from a
disk file.
Available Fields menu
This allows you to select the table or tables from which you want to dis-
play fields in the Fields List. You can display fields from the Master table,
the Related table, or All tables.
Fields List
Displays a hierarchical list of the fields in the selected table or tables.
Indexed fields are shown in bold.
Comparisons Area
Displays a list of comparison operators.
Conjunction Buttons
This area contains three buttons that correspond to the conjunction oper-
ators you can use to join the current simple query to the previous simple
query.
Value Area
You enter the value for which you want to search in this area.
Query in selection button
This button performs the query only on the records in the current selec-
tion.
Query editor buttons
You use these buttons to save your queries, load other queries from disk,
cancel the query, or execute the query.
+ If the field you selected is associated with a Choice List, 4D displays
the list and prompts you to select a value.
+ If the field you selected is a Boolean field, 4D displays a pair of
radio buttons.
+ If the field you selected is a subtable, a window listing the subfields
is displayed.
When you build a compound query, 4D evaluates the simple queries in
the order in which they appear in the Query… Editor (i.e., from top to
bottom). There is no precedence among the conjunctions. If you use more
than two simple queries in building the compound query, the order in
which you enter the simple queries can affect the results of the query.
If you need to add a third simple query, you can choose to either add the
condition to the existing compound query or insert the new simple query
The User Environment 4–5
Jumpstart 4D
between the first two simple queries. To add the new query to the end of
the existing queries, click Add Line. To insert the new query, highlight
the last query and click Insert Line. The new query is inserted above the
line you highlighted.
As you build the compound query, you can modify existing parts of the
query by clicking the line you want to change and clicking a new field or
operator or typing a new value.
You can remove a simple query by selecting the line and clicking Del
Line. In a compound search condition, you can remove one line of the
condition by clicking the Del Line button.
You can use the Query… editor to search on related tables and subtables.
If the field you want to search on is in a related table, choose Related
Tables in the Available Fields menu, or select All Tables and expand the
foreign key field in the master table to display fields from the related table.
Saving a Query to Disk
If you frequently perform the same query, you can save it to disk for later
use:
+ Click the Save button. 4D displays a save-file dialog box where you
can enter a filename.
+ Click OK.
Query by Example…
This menu displays the current detail form for use as a query dialog. You
specify a query by typing the values for which you want to query, in the
areas corresponding to the fields to be queried. You can specify compound
queries by typing values into more than one area. If you execute a com-
pound query, Query by Example… uses the And conjunction.
For example, if you enter Smith in the last name field, and San Jose in the
city field, the query will find only those records where the last name is
equal to Smith AND the city is equal to San Jose. You cannot use this
query to find those records whose last name is equal to Smith or whose
city is equal to San Jose.
+ The results of your query are displayed in the current output (list)
form.
4–6 The User Environment
Jumpstart 4D
Comparison Operator
is not equal to #
You can create a Begins with query by placing the wildcard character @
after the value to be searched for.
Query and Modify…
This menu also displays the current detail (input) form for use as a query
dialog. You specify a query by typing the values for which you want to
query in the areas corresponding to the fields to be queried. You can spec-
ify compound queries by typing values into more than one area.
Unlike Query by Example…, the results of your query are displayed in
the current input form.
When you accept the record, you are returned to the output form.
Query by Formula…
This menu displays the Formula Editor. You use the Formula Editor…
to construct a query that uses a formula as the query. The command is
useful for writing queries that involve operations such as the following:
+ Performing operations or evaluations on alphanumeric strings.
+ Searching on the results of date computations.
The User Environment 4–7
Jumpstart 4D
Saving Formulas
You can save formulas to disk and load saved formulas into the Formula
editor.
Order by...
You can use the Order by… command in the Queries menu to sort the
records in the current selection. Sorting the current selection changes the
order in which records are displayed or printed. This is a temporary sort;
and it does not affect the order in which the records are stored on disk.
Figure 4-2: Order by… Editor
Ordered by Fields/Formulas
This area displays the sort fields or sort formulas and the direction of each
sort. The arrows on the right of this area are used to specify an ascending
or descending sort. You can toggle each fields sort order independently.
You can either drag and drop the fields from the Available Fields list to
this list, or use the arrow keys to move them.
Add Formula button
You use the Add Formula button to create a formula as one of the sort
criteria. You use a formula when you want to sort on something that is not
a field — such as a calculated value or a portion of a field. You could sort
on partial zip codes, length of name, a calculated age, how many days
overdue an invoice is, etc.
Modify button
When you click the Modify… button, it displays the selected sort crite-
rion in the Formula Editor. If the selected criterion is a formula, the for-
mula is presented for editing. If the criterion is a field, the field name
appears in the editing window of the Formula Editor.
Sorting the data
After you have built your sort criteria, you can click the Order by… but-
ton to sort the data.
+ The data sort is only in memory, so the records on disk are not
affected.
+ Only the records displayed in the current selection are sorted.
Charts
4D allows you to create a wide variety of two- and three-dimensional
charts without having to export the data to a graphics package or spread-
sheet. You can create charts from the data in your database or from data
that has been copied to the Clipboard from another application.
You can chart data directly from fields or you can chart the results of cal-
culations on data. You create charts in 4D using the built-in 4D Chart
plug-in. 4D Chart documents can be created in plug-in areas on forms or
in separate plug-in windows.
4 – 10 The User Environment
Jumpstart 4D
Apply by Formula
You can do a global update to the data when you want to make a specific
change to a selection of records. To do a global update, you use the Apply
Formula… editor to write a formula that is applied to each record in the
current selection.
+ Select Enter ¬ Apply Formula…
The Formula Editor is displayed:
Figure 4-3: Formula Editor
You create a formula in the upper area that can consist of fields, 4D com-
mands, operators, and data. Click OK to apply the formula to each record
in the current selection. (Some records might be locked if another user or
process is modifying them. Locked records will not be updated.)
+ You can drag and drop fields from the left-hand list to the formula
area, or type them.
+ You can place the cursor at a suitable insertion point and then click
on one of the operators to insert it, or you can type the operator.
+ Clicking on any 4D theme will display a drop-down list with all the
commands in that theme: selecting a command and releasing the
mouse button will place the selected command or function at the
cursor location in the formula area. Alternatively you can list the
+ Drag and drop field names from the left-hand list to the report area
at the bottom, in the order you want the fields to appear in the final
report.
+ Drag field names to the sort order list, in the order you want the
records to be sorted for printing.
Figure 4-5: Defining the Fields
Clicking on any column will display the column options to the right:
+ Sorted – values will be sorted on printing.
+ Repeated Values – if the field value is the same as the previous
field it will not normally be shown. If you check this option, all val-
ues will be shown.
+ The Printer icon prints the report. (4D needs you to have a default
printer set for your system.)
+ The Stop icon aborts the preview/print process.
+ The Right and Left arrows take you to the next/previous pages.
+ The Magnifying Glass lets you examine areas of the report at actual
size (a zoom facility).
Notice how USA is printed only once and for the first record that has the
country field equal to USA. If you had checked the Repeated Values
option for the Country column, USA would have been printed for every
row that was in the USA, instead of just on the first line.
You can use the Edit menu to Insert, Edit, or Delete columns.
You can select File ¬ Headers & Footers… to define a header and
footer for the report.
You can use the File ¬ Open… command to open Quick Reports that
have been previously saved.
Print Destination
You can print Quick Reports to three different destinations:
+ Printer (default)
+ Disk File (to save as an ASCII text file)
+ Graph (sends to 4D chart)
You select the print destination first, then select File¬ Print… to print to
that destination.
In the case of Disk File you will be prompted for a file name. The disk file
will contain tab delimited fields with carriage return delimited records.
The delimiters can be changed using 4D code to set the delimiter con-
stants.
Label Wizard
You can use the Label Wizard to define and print labels.
+ Select Report ¬ Labels or Command+J (on Mac OS or Control+J
on Windows).
Figure 4-9: Label Editor
+ You can drag and drop fields from the List of Fields to the label
area. You can then arrange them as you want, using the tool palette
above the blank label to align fields, space them evenly, and so on.
+ You can set the normal range of attributes for the fields such as font,
size, justification, and style.
+ Static text and objects can be defined on the label.
If you want to concatenate fields so that there are no spaces between them
when printed, you can drag and drop the second field directly onto the
first field. 4D places a “+” between them to indicate that the fields are
concatenated. You would normally do this with fields like first and last
name, and city with state.
Figure 4-10: Layout Tab
The Layout Tab allows you to define the size and positions of the labels
on the sheet. After clicking the Label Size radio button, you can define
the label sizes, and then click the Page Size button to set the actual
paper size.
If Automatic Resizing is checked, the values in the Label Width and
Label Height entry areas are set automatically.
You can define the number of labels across and down the page, the space
between them, and whether they are printed across the page first, then
down, or vice versa. You can print any number of labels per record.
If you are printing onto an incomplete sheet of labels you can click on the
first label at which you should start printing – any previous labels will be
ignored on the first sheet only.
You can specify the design of the label paper using the entry areas on the
Layout page or choose a standard design from the Standard Code drop-
down list. This drop-down list contains specifications for a wide variety of
standard commercial label sheets.
Method to apply: This control lets you choose a method that will be run
at print time. For example, you can execute a method that posts the date
and time that each label was printed.
Apply Once: These radio buttons are used to specify whether to run the
method once per label or once per record. This control is only valid if you
are printing more than one copy of each label and also executing a method
at print time.
Label Wizard: Lets you save each label design as a file that you can open
later. By saving label designs, you can maintain a library of labels that you
can use according to your needs.
Final Thoughts
+ The Current Selection is essential to your understanding and use of
4D. You create a Current Selection using 4D’s query editors.
+ The Current Selection can then be sorted using the Order By…
Editor.
+ You can update data in the Current Selection using Apply For-
mula…
+ You can print the Current Selection using the Quick Report Edi-
tor.
The User Environment should however only be used in single-user mode
for updating the values of records. It’s a quick and dirty area to manipulate
records, print labels, create charts, run queries, and sort data.
Later you will learn how to carry out all of these tasks from within the
Custom Menus Environment. Here you will maintain full control over
the data.
By the way, did I mention the Current Selection?
The User Environment is not where you would want your untrained
users to be working. It is possible for users to import or delete records,
and view data that you may not wish them to see. The User Environment
only uses 4D’s standard menus.
A better solution is to use the Custom Menus Environment. Here the
user will see only your predefined menus and splash screen. This way you
can control what they can do.
Earlier you created a simple Custom Menus Environment consisting of
the File menu and the Contact menu. 4D automatically added the Edit
and the Apple menu on Mac OS. On Windows, it automatically adds
only the Edit menu, (or there would be some serious grumbling).
In this chapter you will:
+ Create a custom Splash Screen to replace the 4D logo.
+ Create menu items that allow the user to access some of the User
Environment editors.
+ Create additional project methods that execute your code from
menus.
+ Create a Quick Find menu item that displays a custom dialog to
search for contacts.
These will combine to make your application look like a professional pro-
gram. (At first many users may not even realize that it is written in 4D, and
may assume you have become a “real” programmer.)
To create an application that runs in the Custom Menus Environment,
you must have at least one menu bar defined (even if it has no menus).
You created this previously.
Creating a Splash Screen
By default 4D will display the 4D version logo in the default splash screen.
Each menu bar has its own splash screen. Depending on which version of
4D you are using, the splash screen will look something like this:
Improving the Custom Menus Environment 5–1
Jumpstart 4D
You can change the picture that is displayed using the menu bar editor:
+ Copy a suitable image to the clipboard of your computer.
+ Select Tools ¬ Menu Bar Editor while in the Design Environ-
ment.
+ Select a Menu Bar (if you have more than one defined).
+ Select Menus ¬ Show Custom Menus
+ Paste your image (Command+V on Mac OS or Control+V on Win-
dows). Select Edit ¬ Clear if you change your mind.
+ Click anywhere in the screen to close the window.
Your splash screen now has your custom image. Whenever that menu bar
is displayed, it will display your custom image. If you are creating an
application that uses multiple menu bars, you can have a different image
for each menu.
Figure 5-2: Custom Splash Screen
One use for this is if you have different levels of users. You can have differ-
ent splash screens with custom images for the different levels.
Calling 4D’s Editors from Your Menus
To save yourself from writing your own query, order by, quick report or
label editors you can call the standard 4D editors from your own menu
items:
+ You need to be in the Design Environment if you are already in the
Custom Menus Environment.
- Option+F (on Mac OS or Alt+F on Windows), then Com-
mand+Y (on Mac OS or Control+Y on Windows).
+ Select Tools ¬ Menu Bar Editor
+ Add the new menu items.
Figure 5-3: New Menus
+ Start by clicking on List Contacts and then click Add Item. This
adds a new item below the selected item.
+ Type the name of the new menu item.
+ The first new menu item, in this case, has been defined as a line.
(You can either select the Line checkbox in the Current Menu Item
area, or you can type ‘-’ as the menu item name. 4D interprets this
as a dividing line.)
+ Repeat the process to create the other menu items.
Improving the Custom Menus Environment 5–3
Jumpstart 4D
+ Click on the Find menu item and type CNT_Find in the Method
Name field.
+ You can optionally select the method name and copy it to the clip-
board. (This avoids spelling errors.)
+ Type Command+M (on Mac OS or Control+M on Windows).
+ Type (or paste the previously copied method name) CNT_Find for
the method name.
+ Click OK.
+ Type the following code in the method:
QUERY([Contact])
If (ok=1)
MODIFY SELECTION([Contact])
End if
QUERY will display the 4D Query Editor, where you can create any
query. MODIFY SELECTION will list any records found in the default
list form after you have clicked the Query button. This sets the OK vari-
able to 1. Clicking cancel sets OK to 0.)
Next you should create a project method CNT_Sort for the Order by…
menu. The code for this is as follows:
ALL RECORDS([Contact]) ` Optional
ORDER BY([Contact])
If (ok=1)
MODIFY SELECTION([Contact])
End if
When you select this menu item, 4D will first find all records, then display
the Order by… editor. After creating a sort order, if you click the Order
by… button 4D will sort (order) the records in the current selection, then
display them using the default list form.
Next you can create the method for calling quick reports – CNT_QR:
ALL RECORDS([Contact])
REPORT([Contact];Char(1))
The code for this is slightly obscure: when you use the REPORT com-
mand in 4D it expects a table name, followed by the name of the previ-
ously saved report format to use. By using a name that does not exist (e.g.
ASCII Character 1) 4D is forced to display the standard Quick Report
5–4 Improving the Custom Menus Environment
Jumpstart 4D
Editor without loading any predefined reports. (Unless of course you have
a report whose name is ASCII character 1. That’s why you choose a very
unlikely, and hard to type, file name.)
The last method to be created will be used to display the label editor:
CNT_Label:
PRINT LABEL([Contact];Char(1))
This works the same way as the Quick Report Editor. Once the label edi-
tor is displayed you can create new labels or load previously saved label
definitions. You will be able to print the current selection of contact
records – therefore you would probably want to run a search before print-
ing them.
When you type the name of a method into the Method Name field
to assign it to a menu item, you must press the Return key to assign
it to the menu item, or click onto another menu item. Otherwise, if
you switch to the Custom Menus Environment and select that
menu item, it will not call the corresponding method.
Creating a Quick Find
Using 4D’s Query Editor may be confusing for some users, or slow since
you have to build the query each time, or save and load them. You might
want to build a quick query that lets users search for the most common
items, and let them use 4D’s Query Editor for less frequently used queries,
or to build more complex queries than you have allowed for.
To do this requires a few steps:
+ Create a menu item to call the project method.
+ Create a project method to display a query form and process the
query.
+ Create a form for the query.
Before you create this specific code you will need to create two generic 4D
project methods that you will find useful for managing windows. One will
open a window of a specific type in the center of your screen, irrespective
of the screen resolution. The other method will close windows when you
click on their close box (assuming that the window type displayed has a
close box).
WND_Cls
Create a project method named WND_Cls and enter the following code:
CANCEL
Screen width and screen height are two special 4D constants. They
hold the width and height of your primary screen in pixels. (4D detects
these values automatically from your OS.)
$sw:=Screen width/2 ` Center of the screen (horizontally)
$sh:=Screen height/2+10` Center of the screen (vertically) -
allowing for menu bar
Open window($sw-$ww;$sh-$wh;$sw+$ww;$sh+$wh;$3;$4;$5)
To create the variable (where your user will enter their search criteria) you
drag and drop a variable from the tool palette onto the form.
Select:
+ Form ¬ Display ¬ Properties List or
+ Form ¬ Display ¬ Object Properties
If you double-click the object, its properties will be displayed in either one
of these dialogs. See which you prefer.
+ Double-click the variable to edit its properties.
If you have the Property List palette displayed, it will display the various
properties for an object that is selected. You can use this palette to set the
selected objects properties.
You can select multiple objects, and display the properties that they have
in common. For instance, if you select three variables, and they are all
enterable, you will see that the Enterable property is set (it will be
checked), but you will not see anything for the Variable Name, since it is
different for each variable. Therefore you can select multiple objects and
set certain properties for all of them.
You can select multiple objects of the same type by Com-
mand+Clicking on any object (on Mac OS or Control+Click on
Windows). This will select all objects of the exact same type on the
same page.
Alternatively you can set the properties using the Object Properties dia-
log:
The button variable is named btn_OK, and its text is set to Query. The
Accept action is set. (Accept closes the current window and sets OK to 1.)
A button in 4D has two forms: it is both a graphic object and a variable
that has a value. When you click this button its value is set to 1. Before it
is clicked its value is 0. This is a very important concept to remember.
In your code you can test the value of this variable to determine which
button (of many) a user clicked on a form. If the button is an Accept
button, the OK variable is also set to 1.
By clicking the Keys… button you can also associate a key, and modifier
key[s], with a button. For example, you could associate Command+.
(period) with the Cancel button. (In this case 4D also automatically asso-
ciates Control+. with the button for use on Windows.)
Figure 5-9: Cancel Button Properties
Since the Accept and Cancel buttons are 4D automatic action buttons
they will set the OK variable to 1 or 0 when clicked. Both will also close
the open window.
Next create a new menu item: in the menu bar editor add a new menu
item below the Find item in the Contact menu. Name it something like
Quick Find.
Create a project method called CNT_FindQuick and type the code below
(you should know how to do this by now).
The following line opens a window 400 pixels wide, by 200 high, of type
5, titled Find Contacts and the method WND_Cls will be executed if the
user clicks the close box:
WND_Cntr (400;200;5;"Find Contacts";"WND_Cls")
These values are the parameters you defined in the WND_Cntr method.
You must pass them in the same order as they are defined.
+ The group of parameters are enclosed within parentheses.
+ Each parameter is separated by a semi-colon.
+ Text is passed between straight double quote characters.
Display the custom query form in the open window:
DIALOG([Contact];"Contact_QuickFind")
Close the dialog window when the user clicks either of the buttons that
are on the dialog (Cancel or Query):
CLOSE WINDOW
If the user clicked the Query button (which sets the OK variable to 1):
If (ok=1)
The Case statement tests to see which radio button had been clicked by
the user (see below):
Case of
: (rbtn_Last=1)
QUERY([Contact];[Contact]Last_Name=text_SearchValue)
: (rbtn_Company=1)
QUERY([Contact];[Contact]Company_Name=text_SearchValue)
: (rbtn_City=1)
QUERY([Contact];[Contact]City=text_SearchValue)
5 – 12 Improving the Custom Menus Environment
Jumpstart 4D
: (rbtn_State=1)
QUERY([Contact];[Contact]State=text_SearchValue)
End case
The Case statement is used to test situations where there are multiple con-
ditions. In this case there are four radio buttons, any one of which could
be on. (When you click a radio button the others in the same set are auto-
matically turned off. Sets of radio buttons are created based on their first
letter, so all radio buttons that start with r belong to the same set. You
could have another set starting with s and so on.)
When you select Contact ¬ Quick Find 4D will display the query dia-
log:
Figure 5-10: Quick Find Dialog
The user types a name to search for (the @ wildcard can be used), clicks
the Company Name radio button, and then clicks the Query button. The
method will find all company names that start with pana.
4D queries are not case-sensitive.
You might want to improve the method slightly: one possible problem
could occur because the code does not deal with the situation where the
user clicks none of the buttons. You could either:
+ Add code to the method to deal with this (hint: use the Else state-
ment).
+ Set one of the buttons before the form is displayed.
Another problem will occur if the user does not enter any text into the
search value variable, and then executes the query. Since you haven’t told
4D what type of variable text_SearchValue is, 4D will guess when you
enter some text later. If you don’t enter any text 4D will trigger an error.
There are two ways to fix this:
+ Declare text_SearchValue using a compiler statement.
C_TEXT(text_SearchValue)
+ Initialize text_SearchValue to a null value.
text_SearchValue:="" ` Sets the variable to the empty string -
use straight quotes only
If none of the above conditions apply, then this code is run, displaying a
friendly warning:
Else
ALERT("Bozo! Click a radio button first!!")
5 – 14 Improving the Custom Menus Environment
Jumpstart 4D
End case
This test checks whether any records have been found. If there are any
records they are displayed, otherwise an alert is displayed.
If (Records in selection([Contact])>0)
MODIFY SELECTION([Contact])
Else
ALERT("No records found!")
End if
End if
There is a still a problem with this method though. If the user has not
clicked any radio buttons none of the queries will run. There could still be
records in the selection from previous queries: these would be listed.
Therefore after the bozo alert you would need to ensure that no records
were in the current selection, by using the REDUCE SELECTION com-
mand.
REDUCE SELECTION([SomeTable];0)
Of course an easier way of dealing with this is to set one of the radio but-
tons on. You can do this using a Form Method. A Form Method is a spe-
cial type of method that runs when certain events happen to the form, a
typical example being when the form is loaded.
Creating a Form Method
+ While in the Design Environment bring 4D’s Explorer to the front
(Command+Spacebar on Mac OS or Control+Spacebar on Win-
dows).
+ Click the Methods tab.
+ Expand Form Methods & Triggers by clicking the disclosure trian-
gle or plus symbol.
+ Expand the Contact Table.
+ Select the Contact_QuickFind form.
+ Click the Edit button to create a new form method for this form (or
open an existing one). Click OK to accept listing.
+ Type the following code:
Case of
: (Form event=On Load )
rbtn_Last:=1
End case
+ Close the form method.
+ Open the form again.
+ Select Form ¬ Form Properties…
The Form Properties dialog will be displayed:
Figure 5-11: Form Properties Dialog
In the code above, the Case statement looks to see if the On Load event
has occurred. This event occurs in the fraction of time between the form
being displayed with the DIALOG command and the user seeing it on the
screen. If it has occurred then rbtn_Last:=1 is executed.
A Case statement has been used because you will probably add further
events later. Remember that if you add further events to your code, you
must use the Form ¬ Properties… Event tab to set the matching form
event to “on” (checked).
Tidying Up Your Forms
4D’s Form Wizard creates usable forms, but not necessarily forms that are
good-looking or well laid out. You may wish to tidy up your two forms:
Detail Form
Figure 5-12: Revised Detail Form
The changes here are purely cosmetic: deleting the background images,
tidying up the field labels, and so on.
List Form
Open the list form in the Form Editor:
+ Delete the title.
+ Delete the box surrounding the buttons.
+ Select all the buttons – (Command+Click on Mac OS or Con-
trol+Click on Windows) on any button. This selects all form objects
of the same type.
Figure 5-13: Buttons Selected
In the Object Properties dialog you need to set the size in the Coordi-
nates tab, and the text in the Font tab.
These settings are applied to all the selected objects (in this case buttons).
+ Close either the Property List or Object Properties dialog.
+ Click the Horizontal Distribution button on the Tool Palette.
Figure 5-16: Horizontal Distribution Tool
+ Change the entry order of the data entry form so that the user tabs
from the address line to the zip code field, bypassing the city and
state fields.
+ Create an Object Method for the zip code field. When you type the
zip code in this field it will “look up” the city and state from the zip
code table and copy them into the appropriate fields in the contact
table. You can override this data if you need to. If the link between
the tables was relational, you would not be able to override this data
on a case-by-case basis.
This table will not be related to the Contact table by a 4D relation:
instead it will use the zip code as the key field. As you tab out of the zip
code field in the Contact data entry form, the method will query (search)
the zip code table for the matching zip code. When it finds the record it
will copy the city and state for that zip code to the matching fields in the
Contact table.
You could relate the Zip Code table to the Contact table, using 4D’s rela-
tion editor. However this would mean deleting the city and state fields
from the Contact table (since the purpose of the relation is to display
them from the zip code table) and using their equivalents in the Zip Code
table. This leads to potential problems:
+ Every time you load a Contact record 4D has to manage the relation
and load the city and state from the Zip Code table to display it in
the Contact form. This takes time (although not much on a fast
computer).
+ You cannot override a value if you need to.
+ How would you cope with multiple towns sharing the same zip
code?
The better solution, in this case, is to copy the value from the Zip Code
table to the Contact table.
Creating the New Table
You need to be in the Design Environment to create a new table.
+ Select Tools ¬ Database Structure.
+ Command+N (on Mac OS or Control+N on Windows) to create a
new table:
Click Done to close the dialog, then drag the new table to a suitable posi-
tion.
+ Double-click just below the table title, in the first empty cell.
Figure 6-3: Where to Double-Click to Create a New Field
+ This will create your first field definition. Type the field name Zip-
code and select the options as shown:
+ Click Apply.
Set up the State field:
+ Click Apply.
+ Click Done.
+ Switch to the User Environment Command+U (on Mac OS or
Control+U on Windows).
Click on the Zipcode table name in the List of tables. If the List of Tables
is not displayed you can display it by pressing Command+Spacebar (on
Mac OS or Control+Spacebar on Windows). This key sequence toggles
the List of Tables on and off.
Figure 6-7: List of tables
This makes the Zipcode table the current table. There are no records in
this table.
+ Select File ¬ Import Data…
The Import Table can be changed using the drop-down list. The table
selected lists the fields defined for that table. Alternatively 4D can create a
new table from the imported data if the Create Table option is selected.
The File field will display the path to the text file you just opened. This
will be truncated if the path is too long to display. You can use the
Browse… button to select a different file.
If you select the Append radio button 4D will add the newly imported
records to the logical end of your data in the table that holds the data
which you are importing. (If this table had records in it, and some had
been deleted, 4D would fill in the holes left by the deleted records with
the new records. So physically they could be anywhere in the data file.)
If you select Replace, 4D will replace the current selection of records in
that table, with the newly imported records. You will end up with the
number of records in the current selection equal to the number of records
imported. (If you had more records in the current selection than the
import file, you will lose them.) If you selected Replace you should have
either executed a query or ALL RECORDS [SomeTable] before import-
ing. There is no undo for this operation! (Which is a polite way of saying
be very careful when choosing this option.)
In the lower part of the form there are three drop-down menus that repre-
sent the fields that have been defined in the table. Set these (as above) so
that they match the data. The first few records are shown by 4D to help
you.
+ Click the Import button to import the data from the selected text
file. A progress dialog is displayed as the data is imported:
Figure 6-10: Progress Dialog
You could click the Stop button to halt the import process. Any records
imported so far will be saved.
As each line of data is imported, 4D will create a new record, parse the
data from the text field into the appropriate fields, update any indexes,
and save the records. Importing is usually very fast unless you have a lot of
indexed fields.
Since you do not have any forms defined for this table you cannot
see or edit the data. To use this data you do not need any forms, but
they might be convenient for adding new zip codes.
Creating the Object Method
Now you will need to create an Object Method. An Object Method is a
4D method that executes when a certain event happens to the object to
which the method is attached. In the case of buttons, this usually means
the button being clicked. In the case of fields or variables it is often when
data changes in the object, for example the user changes the value in a
field, when they click or tab out of the field 4D notices that the data has
changed from the original value.
You need to be in the Design Environment to create database objects of
any kind.
+ Open your Contact detail form.
+ Option+Click (on Mac OS or Alt+Click on Windows) on the Zip-
code field. (This is a shortcut for creating Object Methods on an
object.)
+ Click OK to accept a Listing type method. You cannot name this
type of method since it is associated only with that object. If you
copy and paste the object to another form, the Object Method is
copied with it.
You now have an open method. Type the following code into it:
QUERY([Zipcode];[Zipcode]Zipcode=[Contact]Zipcode)
The QUERY command searches the Zipcode table for a zip code that
matches the zip code entered in the Contact record.
Case of
If one record is found the data is copied into the appropriate contact table
fields. If there are zero records, or more than one record is found, an alert
is displayed.
6–8 Adding a Non-Related Table
Jumpstart 4D
: (Records in selection([Zipcode])=0)
BEEP ` Makes a beep!
ALERT("No zip code data!") ` Displays an alert dialog, with
a cancel button
: (Records in selection([Zipcode])>1)
BEEP
ALERT("More than one zip code record!")
You will need to decide how to deal with this situation at some point in
the future.
End case
+ Close the method.
+ Double-click on the field to display the Property List or Object
Properties dialogs.
+ Set the object events to On Data Change only.
Figure 6-11: Property List Dialog
On Data Change set using the Property List. This should be the only
event set. For example, if you also have the On Load event set, the code
will run every time this record is loaded. This is unnecessary, and if you do
this with lots of fields on a form, you may slow down the performance
considerably.
4D evaluates the first test inside the Case statement, for example:
:([Invoice]Invoice_Amount>100)
If it succeeds (in this case if the amount is greater than 100) then 4D exe-
cutes any code below this line and before the next test statement. This
could be one to many lines. These lines could include calls to Project
Methods. 4D does not execute any further test statements; it immediately
exits the Case statement after completing the code.
If the test fails, 4D proceeds to the next test statement, and repeats the
process.
6 – 10 Adding a Non-Related Table
Jumpstart 4D
Optionally you can include an Else statement before the End case. If all
preceding test statements have failed, 4D will execute any code between
the Else and End case statements. It is a good idea to handle error con-
ditions here.
In the Object Method there are three conditions that could occur:
+ The query doesn’t find any records.
+ The query finds one record (which is what you want).
+ The query finds more than one record.
The above situations could be solved using a series of If...End if tests but
it could get quite confusing to write, or lead to excessive code: a case state-
ment is a better solution in this case.
Since 4D skips the rest of the Case statement after it executes a successful
test, it makes sense to put the most likely test condition first in the case
statement, then the next most likely, and so on. Place any error handling
code after the Else statement .
Changing the Data Entry Order
You may wish to change the data entry order so that in normal use the
user tabs from the address_2 field to the zip code field, bypassing city and
state. You can do this in the Form Editor.
+ Select Form ¬ Entry Order: 4D displays the form’s entry order.
Figure 6-13: Entry Order (As Is)
Contact ID
Invoice
Contact ID
Invoice ID
Invoice Item
Invoice ID
With this arrangement you can find any Invoice for any Contact, and for
any Invoice you can find any Invoice_Item.
Fields which are used as keys must be indexed, and the primary key must
be unique (to avoid data ambiguity). You set these properties in the Field
Properties dialog.
Adding the Key to the Contact Table
You will need to add the Contact_ID field to the Contact table. It should
be of type long integer and it must be indexed and unique. (A field can
only be set as unique if it is indexed. 4D uses the index to quickly deter-
mine if the field is unique.)
Figure 7-2: Contact_ID Field Definition
(The attributes Mandatory and Can’t Modify are only used for fields
that are displayed on forms and entered by the user.)
You will need some code to automatically generate the Contact_ID value:
one place to manage this is in the Form Method for the Contact_dtl
(detail) screen.
In the Design Environment, create a Form Method from the Explorer
window.
Figure 7-4: Explorer Window: Methods Tab
If the Contact_ID field is blank when the form opens, the value is set to
the next available record number.
Defining the New Tables
In the Design Environment you will need to create the two new tables in
the structure view of the database. Name them:
7–4 Adding Related Tables
Jumpstart 4D
+ Invoice
+ Invoice_Item
After you have created them you will need to define the following fields
for each table:
Table 7-1: Invoice Table Field Definitions
PO_Number A20 -
Bill_Address_1 A40 -
Bill_Address_2 A40 -
Bill_City A40 -
Bill_State A2 -
Bill_Zipcode A10 -
Bill_Country A30 -
Invoice_Subtotal Real -
Invoice_Sales_Tax Real -
Invoice_Total Real -
Paid Real -
Amount_Due Real -
Service_Code A20 No
Service_Description A80 No
Hourly_Rate Real No
Number_of_Hours Real No
Extended_Price Real No
You will now need to create the forms to enter invoice items on each
invoice and create the invoice for each contact. The invoice line items will
be displayed on the invoice in a subform. The invoice will have a detail
form (for viewing) and will also be displayed on the contact form in a sub-
form. A multi-part form will be created for printing the invoice. This is to
handle the fact that there will potentially be many line items per invoice,
perhaps too many to print on a single page.
You can use 4D’s Form Editor to create forms in any order, but it is often
easier to start at the downstream end:
+ Create the Invoice_Item subform first.
+ Create the Invoice detail form next.
+ Add the Invoice_Item subform to it.
+ Create the Invoice subform.
+ Add the new tab (page) to the Contact form.
+ Add the Invoice subform to the Contact form.
+ Tidy up as necessary.
Creating the Invoice_Item Subform
A subform is a list form that displays a selection of records from one table,
on the input (detail) form of another table. When you create the form in
the Form Editor it is created as a list form. When it is placed on the input
(detail) form of another table it becomes a subform.
You use 4D’s Form Editor in the Design Environment to create and edit
all forms. You should be familiar enough with the Form Editor to be able
to create simple forms. You can use the New Form Wizard to create the
forms as you did before, or create your Invoice_Item form and drag and
drop a field icon from the Tool Palette onto the form. Double-click the
field to use either the Object Properties dialog or the Property List to
select which field is displayed. You can also set the field’s properties in
either of these two dialogs. Repeat the process for all fields.
The header labels can be created using the text tool. Like most applica-
tions you can duplicate, and copy and paste objects. The header labels
here have been given the raised appearance.
Select Form ¬ Display ¬ Markers to display the break lines, and then
drag them into the positions as shown below. Your subform should look
something like this.
Figure 7-8: INV_Item_sub Subform
+ The labels all lie above the Header line (H). This line will only
appear once in the subform.
- The Border Line Style is Raised.
+ The fields lie between the Header line (H) and the Data line (D).
These will repeat: one repetition per record.
+ The Break 0 (B0) and Footer (F) lines are dragged up onto the
Data (D) line as they are unused.
- You need to drag the B0 line up first, until it lays on top of the
D line.
- Then drag the F line up until it too lays on top of the D line.
+ There is a black triangle over the 100 pixel mark: this is used to
define the width of labels. You can ignore it for now.
Break lines are only significant on list forms. They have no effect on
input (detail) forms.
Adding Related Tables 7–9
Jumpstart 4D
You can make the fields any width you like: you can drag the selection
handles on any selected object to change the size of the object:
Figure 7-9: Selected Object with Selection Handles
The next step is to place the subform on the detail form. (This is not very
intuitive.)
+ Leave the Invoice input (detail) form open.
+ Command+Spacebar (on Mac OS or Control+Spacebar on Win-
dows) to bring the Explorer to the front, and then click the Forms
tab.
- Or Command+L (on Mac OS or Control+L on Windows) to
bring the Form Editor to the front.
+ Size the Explorer window so that the Invoice form is partially visible
behind it.
+ Click on the INV_Item_sub form name, and (while holding the
mouse key down) drag the name onto the Invoice form behind it.
Figure 7-11: Drag and Drop the Subform onto the Input Form
+ Release the mouse key to drop the form into place. The
Invoice_Item form is now on the input form and from now on will
be treated by 4D as a subform.
+ You can bring the Invoice_dtl form to the front (click on it) and
then drag the subform into the desired position, so it looks some-
thing like this:
You can drag the height of the subform to display as many rows (records)
as you wish. However it is trial and error: the subform does not show you
in the Form Editor how many records will be displayed, you need to view
the subform in the Custom Menus Environment, guess at how many
pixels to add and subtract, adjust the size, and repeat as necessary. (To
view it in the Custom Menus Environment you will need to view a con-
tact record, add an invoice, view the invoice, etc.)
While in the Custom Menus Environment you can use the scroll bar to
see more records.
The Invoice Subform
Your next step is to create a subform to display the invoices on the Contact
table input (detail) screen. This should look something like this:
Figure 7-13: Invoice Subform
+ Drag and drop a tab object from the Tool Palette to the form.
Figure 7-15: Tab Object
+ Resize the tab object to a suitable size (see the sample database).
Adding Related Tables 7 – 13
Jumpstart 4D
+ Double-click the object and use the Property List or Object Prop-
erties dialog to set the following properties:
Figure 7-16: Tab Object Properties
These two values will become the tab names, in the order that they are
listed. Click OK to close the dialog.
+ Close the Object Properties or Property List dialog.
Your tab should now look something like this:
Figure 7-19: Tab Object
When you are in the Custom Menus Environment and you click the
Invoices tab, 4D will display the second page automatically (as long as you
have created it). If you have three tabs, and you click the third, 4D will
display the third page (as long as there is one) and so on.
Now you can create the second page.
+ Move back to page 1 by clicking the Next Page icon on the Tool
Palette.
Figure 7-20: Next Page Icon
+ Click the icon again. Since there is no second page, 4D will prompt
you as follows:
Figure 7-21: Create Page Prompt
There is one final detail to attend to: the tab is much smaller than the
input window will be when it is displayed. You can keep tweaking the size
of the tab or you can let 4D do it for you. (Hint: this is much easier.)
+ Double-click the tab (in page 0) to display the tab’s properties.
+ Set the Resizing Options as follows:
Figure 7-23: Resizing Options
Grow Horizontally will grow the tab object close to the window’s right-
hand limit, Grow Vertically will grow the tab object close to the lower
window limit. (Inspect the buttons and note that they are set to move ver-
tically.)
Adding Code to Manage Everything
Using the Custom Menus Environment you can now list contacts. If you
double-click a contact record it will open in the default input window.
Click the Invoices tab and you will see the list of invoices for the contact.
But there’s no way to add an invoice for the contact.
There is a hidden shortcut for adding records to a subform.
+ Click anywhere in the subform. Note the flashing triangle next to
the subform, this indicates that it is selected.
+ Press Command+/ (on Mac OS or Control+/ Windows). (For now
do not repeat this a second time on any invoice subform.)
This adds a record to the related many table displayed with the subform.
Try this with the Invoice subform and note what happens. (The record is
created but no valid data is there.)
Form Methods
A Form Method is special type of method that executes when certain
actions (known as events) happen to the form. The most common event is
when the form loads. There are two parts to creating a Form Method that
works (and only one part for Form Methods that don’t work).
+ Create the Form Method with the code.
+ Set the Form’s Properties so that it recognizes the events that you
want to trigger your code. (This step is often forgotten, even by old
salts. Believe me…)
The Form Method is going to be added to the Invoice subform, not the
contact subform.
+ Open the Invoice subform in the Design Environment.
+ Select Form ¬ Form Method… or Command+K (on Mac OS or
Control+K on Windows).
+ Select Listing and click OK.
+ Type the following code (you can omit the comments after the `
symbol):
Case of
: (Form event=On Load ) ` Don’t forget that colon preceding
the left parenthesis
If ([Invoice]Invoice_ID=0) ` One way of testing for a new
invoice
[Invoice]Invoice_ID:=Sequence number([Invoice])
[Invoice]Invoice_Date:=Current date
[Invoice]Due_Date:=[Invoice]Invoice_Date+30
[Invoice]Bill_Address_1:=[Contact]Address_Line_1
[Invoice]Bill_Address_2:=[Contact]Address_Line_2
[Invoice]Bill_City:=[Contact]City
[Invoice]Bill_State:=[Contact]State
[Invoice]Bill_Zipcode:=[Contact]Zipcode
[Invoice]Bill_Country:=[Contact]Country
End if
End case
+ When the form loads, the code above will start executing. If the
Invoice_ID field is equal to zero the invoice must be a new invoice,
therefore all the fields will be completed by the code that follows.
7 – 20 Adding Related Tables
Jumpstart 4D
+ The due date is calculated as the Invoice Date plus 30 days. 4D can
do date arithmetic, taking into effect the correct number of days for
each month, leap years, and leap centuries.
+ You can also tab through the fields to enter/modify data.
Changing some values may cause problems. If you changed the value of
the Invoice number field you would either lose any related Invoice Items,
or connect the wrong items to the invoice. There are two ways to prevent
the user from modifying certain values:
+ Make the field non-enterable. The value can be calculated by 4D,
but not entered through this instance of the field. (The same field
could be made enterable on other forms.)
+ In the Field Properties dialog you can set the field attribute to Can’t
Modify. Once the value has been created or entered, it cannot be
changed.
In the Form Editor you can change the field to non-enterable by double-
clicking the field and selecting the Field tab. Then click the Enterable
checkbox to make the field non-enterable. (This can also be set under the
Objects list in the Property List palette.) The field has been set to non-
enterable in the sample database.
Enhancing the Invoice Form
After the user has clicked the button to add an invoice to the Contact
record, they can double-click the invoice in the subform to open the
invoice. When it opens, the Form Method completes many of the fields
such as the billing address, invoice date, and so on. The next step is to add
further buttons to the form.
You will need:
+ A button to cancel changes made to the invoice.
+ A button to save changes made to the invoice.
+ A button to print the invoice.
+ Buttons to add and delete line items.
These changes are all made in the Design Environment using the Form
Editor.
+ Drag and drop a button from the Tool Palette onto the form.
+ Edit its size, style, and fonts to the desired appearance.
7 – 22 Adding Related Tables
Jumpstart 4D
+ Set the Object Properties using either the Object Properties dialog
or the Property List.
+ Duplicate the button, or copy and paste it twice.
+ Move the buttons to a suitable location.
Figure 7-28: Three Buttons in Place
The first two buttons use 4D’s automatic actions. The first button will
cancel (close) the form without saving changes to it. (But changes to sub-
forms will have been saved.) The second button will close the form and
save changes. The third button does nothing for now, until you add an
Object Method to it.
While you are here you should perhaps make the Invoice_ID field non-
enterable. (Hint: Double-click and use the Field tab of the Object Prop-
erties dialog.)
Now when the user double-clicks an invoice in the invoice subform, the
invoice form will be displayed without 4D’s default buttons.
+ Your buttons can be positioned anywhere and have any appearance
you like.
+ You can now add the two buttons for the subform, in the same way
that you did earlier. One will be to add subrecords, the other to
delete them. Remember that they must have different names.
A final touch: make sure that the Invoice_Item subform is not set as dou-
ble-clickable in the Subform tab (Object Properties dialog).
Figure 7-34: Subform Object Properties
This code will set the Item_Number value sequentially, from 1 onwards.
+ Create an Object Method for the Number_of_Hours field. Type
the following:
LITEM_ExtendedPrice
This will be the name of the Project Method called from the field’s
Object Method. Double-click the line to select it, and copy it to your
computer clipboard.
+ Type Command+M (on Mac OS or Control+M on Windows) to
create a blank method.
+ Type Command+V (on Mac OS or Control+V on Windows) to
paste the name in (from your clipboard).
+ Click OK.
This has created a Project Method called LITEM_ExtendedPrice. Type
the following code in to the method window:
[Invoice_Item]Extended_Price:=[Invoice_Item]Number_Of_Hours*[I
nvoice_Item]Hourly_Rate
` That is the star character (Shift+8) between the fields
+ Close the method.
+ Create an Object Method for the Hourly_Rate field as before. Type
the following code:
LITEM_ExtendedPrice
+ Close the method window.
+ Double-Click the Hourly_Rate and Number_of_Hours fields.
Select both, then double-click either one.
+ Under the Events Tab make sure that only the On Data Change
event is checked.
Adding Related Tables 7 – 27
Jumpstart 4D
You can force 4D to display all Real number fields to the same number of
decimal places using the Form Editor.
+ Open the Invoice detail form in the Form Editor.
+ Select all the fields below the Invoice_Item subform. (Click on the
first, then Shift+Click on each of the others in turn.)
+ Double-click on any one of the selected fields.
+ Select the Data Control tab from the Object Properties dialog,
and select an appropriate format from the Display Format drop-
down list.
Figure 7-36: Setting the Field’s Format
After you have entered an amount in the [Invoice]Paid field, 4D will cal-
culate the amount due. You could set this form event to be On Data
Change only as well.
Printing the Invoice
If you expect your clients to pay your invoices, you will need to print them
a copy first. To do this you will need a form to use for the printing, and
some code to print the form.
+ Create a form belonging to the Invoice table. Name it something
like INV_prt.
+ You can copy all the objects from the INV_dtl form to the clip-
board, then past them into the new form.
+ Delete all the buttons.
+ Select the [Invoice]Paid field by clicking it, then select Object ¬
Clear Object Method.
- This will clear the object method from the selected field.
+ Select Form ¬ Display ¬ Markers.
+ Move the Header (H) line to the top of the screen.
+ Move the Data (D), Break (0) and Footer (F) lines to a suitable
position further down the screen.
+ Move the objects into a suitable position for printing.
+ Select all fields and change their Border Line Style to None (they
are set up to show as recessed on the screen, you might not want this
appearance on printed forms).
+ Add your logo if desired.
+ Add any text to tell the recipient where to make their payments etc.
You should end up with an invoice that resembles this:
Figure 7-37: Finished Invoice
Note that the subform is only one line high (plus the headers). 4D will use
as many lines as it needs when it prints the invoice.
Next you can add the following code to the Print button on the invoice
input form:
OUTPUT FORM([Invoice];"INV_prt")
PRINT RECORD([Invoice])
This code makes the print form the current output form, then prints the
record using it. You can tweak the position and appearance of the form
objects to your heart’s content.
Looking Up a Service Description from Another Table
If you frequently offer your clients the same services, it would be time sav-
ing to have a list of services with standardized codes. When you enter the
service code in the line item, 4D looks up the description and hourly rate
for you. You need only enter the hours worked for 4D to calculate the
extended price. Like the zip code example earlier, you do this in a non-
related table.
+ Create a new table named Service in the Structure Editor with the
following fields:
Table 7-3: Service Table Field Definitions
Service_Description Alpha 80 No
Hourly_Rate Real No
You can examine the list form in detail in the sample database.
These two project methods allow you to add new service items and list
existing ones. (The sample database contains two entries.)
Create an Object Method for the Service_Code field in the
Invoice_Item subform, it should contain the following code:
QUERY([Service];[Service]Service_Code=[Invoice_Item]Service_Co
de)
[Invoice_Item]Service_Description:=[Service]Service_Descriptio
n
[Invoice_Item]Hourly_Rate:=[Service]Hourly_Rate
LITEM_ExtendedPrice
This code queries the Service table to find a Service_Code that matches
what was typed in the line item. If a matching entry is found, the descrip-
tion and hourly rate are copied over, then the LITEM_ExtendedPrice
Project Method is called to update the extended price and the subtotals
etc.
What happens if no matching entry is found? In this case the current
selection for the Service table will be zero records and there will be no
values to copy over.
What happens if there is more than one matching service code found? 4D
will use the first record’s values. How do you know which record is first?
You don’t – that depends on the entry order of the records and whether
records have been deleted from the Service table and then new ones
added.
You could add a date field to the Service table, and then sort the records
after the query, by reverse date order. This would have the effect of allow-
ing you to update prices by adding new records, new invoices would
always use the latest price for any particular code.
Finale
There are a few rough edges to this solution which will be addressed in a
later chapter. Meanwhile you can experiment with different layouts for the
forms.
Chapter 8 – Passwords
You may wish to restrict access to your database for many different rea-
sons:
+ As the developer, you may wish to stop other people from changing
your code.
+ You may want to restrict access to a database to only authorized
users.
+ Within a database you may wish to restrict access to specific func-
tions, or restrict the viewing of certain data, such as salaries or medi-
cal data.
This can be achieved using 4D’s password system. In this chapter you will
learn how to:
+ Create new users within the password system.
+ Assign passwords to these users.
+ Create groups of users.
4D provides you with a number of tools to achieve these goals. The two
primary building blocks are:
+ Users
+ Groups
A user represents a single person who needs access to the database. A
group represents a collection of users, usually with a related job function.
Users are normally created with the goal of restricting access to the data-
base: each user has a name and a password which they use to log in to the
database. In some cases a user represents a single individual – for example
Sam Adams. In other cases a user might be a job function – for example
Shipping Clerk: several different users could log in (even simultaneously)
using this same user name.
A group is a collection of users that is used to manage access to specific
functionality within the database. Groups can consist of one to many
users.
Consider the example of a small mail order company: there is the boss,
two managers, four order-takers, and three people to package the goods
Passwords 8–1
Jumpstart 4D
and ship them out. You want to be able to control which tasks each of
them can do, perhaps by reducing the complexity of choices they face by
reducing menus and options. An easy way to do this, and reduce your pro-
gramming effort, is to create groups. You could create groups such as:
+ Boss
+ Managers
+ Sales
+ Shipping
Each user can then be made part of a group. (Users can belong to more
than one group.) When the user logs on you can check which user they
are, or which group they belong to, and display menus and forms specific
to that group. If you need to add new users you add them to the existing
groups and your code does not need to be changed.
+ Each user will have their name and password defined in the pass-
word system.
You can add further levels of protection by writing methods that extend
4D’s password capabilities. For instance you could force a minimum pass-
word length, exclude certain simple passwords, force the user to change
their password periodically, and so on.
Creating a New User
When you use the password system to create new users, you will notice
that there are two default users already created by 4D:
+ The Designer
+ The Administrator
These are two special types of users. It is important to note that users cre-
ated by the Designer cannot be deleted (but can be renamed).
Assigning a Password
You use the Password Editor to create users, assign passwords to them,
and assign them to groups. Start in the Design Environment.
+ Select Tools ¬ Passwords to display the Password Editor.
8–2 Passwords
Jumpstart 4D
You can assign a Startup Method to the user. This Project Method will
run after the user has logged in. This can be useful if you need to run code
specific to that user: for example checking whether there are any to-do’s
flagged for that user.
If you type in the name of a method that does not exist, well, obviously it
will not run. But there is also an interesting side-effect: that user will be
prevented from dropping from the Custom Menus Environment into
the User Environment. (Users can normally do this by pressing Option+f
on Mac OS or Alt f4 on Windows.) They can wreak havoc in the User
Environment, so it can be useful to prevent users from getting there.
The Last Use field tells you when that user last logged in, and Number
of Uses tells you how many times they have logged in since the creation
of that user name.
Passwords 8–3
Jumpstart 4D
Note:
+ The password is displayed as a series of symbols, not as cleartext.
+ Passwords are case-sensitive. (Remember the Caps Lock key.)
+ You have to confirm your password.
Click OK to accept the password, or Cancel if you change your mind.
(The sample database for this chapter does have a Designer password
installed. It is Jump.)
The next time you launch this database you will need a password to log in
as the Designer (and at the moment only the Designer has access to the
source code of the database). Don’t forget your password since there is no
way of recovering it, and 4D, Inc. will not recover it for you.
At this point you will need to set some Database Properties that relate to
the password system – use the File ¬ Database Properties menu item:
8–4 Passwords
Jumpstart 4D
Passwords 8–5
Jumpstart 4D
Type Manager as the Group Name, click OK. Repeat the process and cre-
ate a new group called Sales.
Figure 8-7: Your Groups Defined
8–6 Passwords
Jumpstart 4D
Clicking on a user in the Users… list will display which group (or
groups) they belong to in the scrolling area immediately below.
If there is a designer password defined, then when you next launch the
database, the standard password screen will be displayed:
Figure 8-9: 4D Password Login
+ Type your password into the Password area of the screen. Beware
that the Caps Lock key is not on.
+ Click OK to log in.
(For those with short retention spans, the designer password is Jump.)
Controlling Access
The most practical way to control access to parts of your database is by use
of the commands:
+ Current user – This returns a string which is the name of the cur-
rent user, for example Joe Soap.
+ User in group (User;Group) – This returns “true” if the user
name that you passed in the variable User belongs to the group as
passed in the variable Group. Otherwise it returns “false”.
The use of these two commands will be demonstrated in the next chapter.
8–8 Passwords
Jumpstart 4D
The designer password for this chapter’s database is Jump. As always this
is case-sensitive.
So far the application that you have created is very simple and lacks many
of the features that would make it usable and useful. You are going to add
some of these features while working through this chapter.
You will be adding the following functions:
+ Adding a startup Project Method that will set the application title
in the splash screen.
+ Setting window positions and adding titles that are more meaning-
ful.
+ Use variables to total how much you have sold in any particular
year.
+ Be able to list invoices independently of the contacts.
+ List a subset of invoices.
+ Find invoices that are past due for payment.
+ Print a list of invoices.
+ Display different menus depending on who logs in.
Setting the Application Title
Your first step is to create a method that sets the name of the application’s
splash screen. In versions of 4D prior to 4D v6, you named a project
method Startup and this was automatically run when the database was
opened. 4D v6.0 introduced the concept of Database Methods which are
methods that run when certain events happen in the database. One of
these is On Startup. Any code in this method is automatically run when
the database is launched. You can either type your code in here or call
another project method. I prefer to call another project method, but for
no particular reason other than habit.
You access Database Methods from the Explorer window in the Design
Environment.
If you click on the On Startup method name and the preview pane to the
right remains blank, then the method is empty. (In the example above, the
method has already been created, a preview of the first few lines is dis-
played when you click on the method name.)
To create a new method for the On Startup method, double-click the On
Startup name.
When you use the + symbol between two text strings, 4D concatenates
them, that is they are joined into one string. Current user returns a
string (the name of the current user) and this is added to the text string
after the + symbol. Then the current date is added to that string to com-
plete the window title. Current date returns the date (from the com-
puter’s system clock) but it is returned as a date, not as a string. The
command String formats the date as a text string so that it can be concat-
enated with the previous string. The 4 specifies the format of the date as a
string (in this case MM/DD/YYYY). 4D also now supports constants for
these formats – so the code could also be written as:
SET WINDOW TITLE (Current user+": Jumpstart My Contacts
"+String(Current date;MM DD YYYY))
If you drop from the Custom Menus Environment into the User
Environment or Design Environment you will lose the title of the
splash screen. It will revert to Custom when you return. This is
mildly annoying when you are developing a database. However
when you deploy your database your users will never leave the Cus-
tom Menus Environment so they will not have this problem.
Setting Input and List Window Positions and Titles
4D offers a lot of control over your windows. You can open windows at
any position, size, and style. You can have windows with scroll bars or
without, control their behavior and set their titles. A simple improvement
is to open your input (detail) and list screens at standard positions and
sizes, and display a title that tells the user something useful about the win-
dow. This might be what they are entering (a contact record) or how many
records are listed in a list view window.
To do this you need to create a few standard window methods. These will
use two interprocess variables that hold the size of the screen you want to
use (rather than the actual size of your PC screen) in pixels. The value of
these two variables is set in the Startup project method, which now looks
like this:
◊ScreenWidth:=875
◊ScreenHeight:=615
SET WINDOW TITLE(Current user+": Jumpstart My Contacts
"+String(Current date;4))
This will open a window, 6 pixels from the left edge of your screen, 47
pixels down from the top, that extends to the value held in ◊ScreenWidth
(875 pixels across), and down to ◊ScreenHeight (615 pixels down). The
window type is 5 (a movable dialog box). It has no title (nothing between
the quotation marks), and if you click the closebox it will call the project
method WND_Cls. Do not worry too much about the code for now; you
will see what it does shortly. These values may need to be modified accord-
ing to your platform, OS, window type and preferences. OS issues will be
covered later.
Next create a project method called WND_List. The code you need is:
Open window(6;47;◊ScreenWidth;◊ScreenHeight;5;"";"WND_Cls")
Modify SRVC_Add:
WND_Input
Repeat
ADD RECORD ([Service])
Until (ok=0)
After you have modified all these methods you will need to quit and then
launch your database again, to run the Startup method (which sets the
(This is all one line of code. Do not type return until you reach the end of
the complete line.)
This will create a title such as Contacts: 1 of 17. Records in selection
counts how many records there are in the current selection (how many
you found), while Records in table counts how many records there are in
the table.
Next you will need to make a change to the Subset button on the
CNT_lst form.
+ Using the Form Editor, display the CNT_lst form.
+ Option+Click (on Mac OS or Alt+Click on Windows) on the but-
ton. (This will display the object’s code.)
+ Edit the code to read:
Figure 9-4: bShowSubset Object Method
If you have a selection of records in the contact list, and you select some of
them and then click Subset, the object method will display only those
records you had selected. Therefore you will want the title to be recalcu-
lated to reflect this new total. (That is why the code that does this was
placed in a project method.)
You can repeat this exercise for the Services list form. (See the code for the
sample database.)
Input (Detail) Form Titles
This will usually be a simpler title.
+ Open your form method for the CNT_dtl form.
+ Modify the code to read:
If (Form event=On Load )
If ([Contact]Contact_ID=0)
9–8 Refining Your Application
Jumpstart 4D
[Contact]Contact_ID:=Sequence number([Contact])
End if
SET WINDOW TITLE(Table name(Current form table)+" Data Entry")
` <- This line added
End if
+ In the Custom Menus Environment examine what this code does
by adding a new contact record.
This code has been written to be generic so it will work with any table.
Current form table creates a pointer to the table to which the form table
belongs. Table name uses that pointer to determine the actual table name.
Therefore this code can be pasted into any other input form’s form
method and it will work in the same way. An even better way to accom-
plish this is to create a project method called (say) DTL_FormTitle, paste
the code in, and then call that project method from any detail form that
needs a title (see the form method for SRVC_dtl.)
Working with Invoices
Now it’s time to work with the invoices, independently of the contacts.
The first task is to add a new menu to the Menu Bar #1.
Figure 9-5: Menu Editor
This displays a request dialog on the screen, with the text string Enter a
year for your YTD total plus whatever the current year is as the default
value. Year of determines the year of the current date. The user can:
+ Click Cancel.
+ Click OK leaving the date as it is.
+ Type another year (last year for example), then click OK.
Whatever value was in the entry area on the dialog when the user clicked
OK is placed into the variable $YearAsString. The variable that is
returned from a request dialog is always a string. You may need to convert
it to another data type before using it in a query (in this case you will).
If (ok=1)
If they click the OK button, the OK variable is set to 1 and the code con-
tinues. If they click the Cancel button the OK variable is set to 0 and the
code terminates.
This line of code builds a string that is the first day of the year the user
entered, then converts it to a date.
9 – 10 Refining Your Application
Jumpstart 4D
$DateFrom:=Date("01/01/"+$YearAsString)
This line builds a string that is the last day of the year, then converts it to a
date.
$DateTo:=Date("12/31/"+$YearAsString)
This code queries for all invoices between the from and to dates. The *
character in the first query line tells 4D that this is a multi-line query. If
this query had three lines the first two would have the * character, and the
last line would not.
QUERY ([Invoice];[Invoice]Invoice_Date>=$DateFrom;*)
QUERY([Invoice]; & ;[Invoice]Invoice_Date<=$DateTo)
The & character in the second line tells 4D that this line is joined to the
first line by a logical AND. In plain English, these two lines tell 4D that it
should search (query) the Invoice table for all records where the
Invoice_Date is greater than or equal to the value in $DateFrom AND
where Invoice_Date is also less than or equal to the value in $DateTo.
This line sums the values in the Invoice_Total field for all the records in
the current selection (that is, all those that were found). The total is placed
in the local variable $SalesYTD.
$SalesYTD:=Sum([Invoice]Invoice_Total)
A message is built using text and the variable and then displayed using an
Alert dialog. The string "$#,###,###.00" determines the format of the
numeric value. You can place your own preferred currency symbol here.
The # symbols are placeholders for the digits, and the commas represent
the thousands separators. The double zeroes force 4D to display the result
to two decimal places. A European equivalent might be:
"DM #.###.###,00"
Using an Alert dialog is quick and easy: you do not have to specify any
coordinates or window type. The disadvantage is that you have no control
over the appearance of the dialog. If you want to use a different window
style you can open a window and then display a custom dialog in it (like
the quick find dialog).
ALERT("Your sales year to date are
"+String($SalesYTD;"$#,###,###.00"))
Listing Invoices
The next stage is to list invoices using a list form, and then print them
from that form. There are several steps to this:
+ Create a menu item called List Invoices that calls the project
method INV_List.
+ Create a project method called INV_List with the following code.
You can omit comments:
ALL RECORDS ([Invoice])
ORDER BY ([Invoice];[Invoice]Invoice_Date;<) ` This sorts them
in reverse order!
WND_List ` Open the standard size window…
MODIFY SELECTION ([Invoice];*)
+ Create a list form for the invoice table:
Figure 9-7: INV_lst Form
You should know by now how to create a form using the Form Editor.
This form has been created in a slightly different manner from the previ-
ous list forms: so feel free to examine the form.
This code could have been typed in the form method directly, instead of
being called as a project method. Test the method and see what it does.
The next step is to be able to view just a subset of the listed invoices on the
screen. For example, you have two year’s worth of invoices in your data-
base, and you only want to see those invoices for this year (and then print
them). You could handle this in two ways:
+ Have a query that finds invoices before or after a certain date, or
between certain dates, greater or less than a specified value and so
on. Coping with all these options can get quite complex, or you
could use the 4D built-in Query Editor.
+ Add a button to the list form that allows a user to select a number of
invoices (clicking, shift+clicking, etc.) then making those invoices
the only ones visible.
Invoice query
You can create a similar method to the CNT_Find project method for
invoices. The code for this project method (INV_Find) would be as fol-
lows (only the table name has been changed):
QUERY ([Invoice])
If (ok=1)
WND_List
MODIFY SELECTION ([Invoice];*)
End if
Perform a query that returns only one record and notice the window title.
This is the advantage of having the code that names the window in the
form method. Whenever the form is opened, the correct window title will
be set. This also reduces the number of lines of code that you have to type
and remember to update later.
Refining Your Application 9 – 13
Jumpstart 4D
Creating a Subset
An easy way to enable a user to create a subset of records to view is to
allow them to select some records from list view, and then have them click
a button that makes these selected records the current selection. The code
you will use will for this involves a concept in 4D called Sets.
Sets in 4D are a simple way of storing a selection of records that can be
retrieved quickly. Sets work in a similar way to Set Arithmetic/Venn Dia-
grams from your high school days. For example:
+ You can create a set that contains all the boys who take music les-
sons.
+ You then create a set of all boys older than 13.
+ Then you create a set of boys who live outside the city limits.
Having created these sets you can (almost) instantly recall them, or per-
form set arithmetic on them. In the example above, the Union of the
three sets would give you all boys who took music or were older than 13 or
lived outside the city limits. The Intersection of the three sets would give
you only those boys who took music, and were older than 13 and lived
outside city limits. Set arithmetic can only be performed on sets that are
within the same table.
+ Sets are very fast.
+ Set Arithmetic can reduce the need to perform repeated queries.
+ Sets can be local (cleared when the method ends), process (cleared
when the process ends) or interprocess (cleared when the database
quits) just like variables.
+ Records stored in sets are not stored in any sorted order – after
recalling a set you need to sort it again.
+ The Current Record Pointer is stored (but will be lost if you per-
form set arithmetic since each set will have a different current
record).
+ If you add or delete records to a table that has sets, the sets may not
be valid.
The creation and use of sets is not within the scope of this book, with the
exception of a special set which will be explained shortly.
+ Create a button on the list form, name it, and give it a meaningful
text label (such as Subset). It should be a No Action button. (This is
9 – 14 Refining Your Application
Jumpstart 4D
similar to the Subset button on the Contacts list form, but only bet-
ter.)
+ Type the following code:
If (Records in set("UserSet")>0)
USE SET("UserSet")
ORDER BY ([Invoice];[Invoice]Invoice_Date;<)
Else
ALERT("You need to select at least one record first!")
End if
The set UserSet is a special set in 4D. 4D creates an empty set named
UserSet when a user is viewing a selection of records for a table (the cur-
rent selection) in a list form. If they select any records in the list view they
are added automatically to this set by 4D. You can select one or more
records by:
+ Clicking any record.
+ Shift+Clicking adjacent records.
+ Command+Clicking (on Mac OS or Control+Clicking on Win-
dows) non-adjacent records.
4D maintains the UserSet automatically, adding newly selected records
to the set, and deleting unselected records from the set.
When the user clicks the Subset button on the list form, the code checks
to see if there are any records selected by the user. The easiest way to do
this is to count how many records there are in the UserSet. If no records
are selected, there will be zero records in the UserSet.
If there are any records selected, the method makes the current selection
for the table equal to the contents of the UserSet (which is of course
whatever records the user selected). Notice that the set name is in straight
double-quotes.
The records are then sorted (this is optional).
(If the user does not select any records then a suitable scolding is dis-
played, to reinforce the fact that the user is an “idiot”.)
If you list a selection of records, select some, then click the Subset button.
What happens?
The correct selection of records is displayed, but the title will reflect the
original record count. When the Subset button was clicked, the Form
Method ran (as long as On Clicked was set in the Form Properties for
the form) but it called a project method called INV_Title_List that only
checked to see if the form had been loaded. It did not check to see if any-
thing else had happened to the form (such as someone clicking a button
on it). Therefore the code that built the window title was not executed.
However, this is easily remedied, simply open the project method
INV_Title_List and change the first line of code to:
If ((Form event=On Load ) | ((Form event=On Clicked )))
Now the code will run if the form is loaded (opened) or the user clicks on
any active object, or any record. One slight problem with this solution is
that the code runs every time the user clicks a button (not much of a prob-
lem) but also every time they click on a record (this could happen fre-
quently). You wouldn’t want to run a lot of code in this method. An easy
way to check if code is running is to insert the BEEP command into the
code.
A better solution would be to leave the method INV_Title_List as it was,
running only when the form was loaded, and then modifying the Subset
button as follows:
If (Records in set("UserSet")>0)
USE SET("UserSet")
ORDER BY ([Invoice];[Invoice]Invoice_Date;<)
SET WINDOW TITLE("Invoices: "+String(Records in
selection([Invoice]))+" of "+String(Records in table
([Invoice])))
Else
ALERT("You need to select at least one record first!")
End if
When the user clicks the Subset button the window title will be recalcu-
lated which is more efficient.
Finding Past Due Invoices
You could use the Find Invoices menu (and associated project method)
that you created previously and then query for invoices where the due date
is less than ( before) today’s date.
To simplify this for the user though, you could create a menu item and
associated project method (INV_PastDue) containing the following code:
QUERY([Invoice];[Invoice]Due_Date<Current date)
ORDER BY([Invoice];[Invoice]Invoice_Date;<)
WND_List
MODIFY SELECTION([Invoice];*)
This will list, in the current list view form, any invoice records where the
date due is prior to today’s date (as long as your computer’s system clock is
set correctly).
Printing a Batch of Invoices
Having found a batch of invoices, it might be useful to print them, not as
a list, but as individual invoices. For example, you may wish to write a
suitably threatening letter and attach a copy of the invoice to those dead-
beats who haven’t paid us. For the user, an easy way to do this is to allow
them to find a selection of invoices (by using the query editor), which will
list the invoices on screen. (They can then use the Subset button to fur-
ther reduce their selection if required.) Once they have a selection of
records they can click a Print button to print the invoices as a batch.
+ Create a button, similar to the Subset button, and name it, etc. (It is
recommended that buttons on the same form have unique names,
although generally this is not essential unless you want to check the
value of a specific button (0 for off, 1 if clicked). Remember that
even though buttons may be on separate pages, they are still on the
same form.)
+ Create an object method for it, containing the following code:
OUTPUT FORM([Invoice];"INV_prt")
PRINT SETTINGS
FIRST RECORD([Invoice])
For ($Invoice;1;Records in selection([Invoice]))
RELATE MANY([Invoice]Invoice_ID)
PRINT RECORD([Invoice];*)
NEXT RECORD([Invoice])
End for
OUTPUT FORM([Invoice];"INV_lst")
This line sets the default form that 4D will use to print the record. It is the
same form that you used before to print the invoice from the invoice detail
form. (Since you are using the form to print, the position of the marker
lines is critical. You can examine their positions in the Form Editor.)
OUTPUT FORM([Invoice];"INV_prt")
The next line displays the page setup and printer setting dialogs specific to
your Operating System. Here you can set the paper size, orientation, num-
ber of copies, etc. These settings apply to all copies printed during this
batch.
PRINT SETTINGS
When you create a form using the Form Editor, you can use File ¬
Page Setup… to set the paper size and orientation according to the
current default printer. 4D remembers this setting for this form
when the PRINT SETTINGS command is displayed. You can over-
ride these settings if you choose.
You need to make sure that the current record pointer is pointing to the
first record before looping through the records, because the user may have
double-clicked into another record in the selection and moved the record
pointer accordingly. This command ensures that you start printing from
the first record and therefore do not miss any records.
FIRST RECORD([Invoice])
You are now going to loop through however many records there are in the
current selection. You need to define a variable for the loop counter
($Invoice) even if you don’t use it. In this case the loop starts at 1, but you
could start at any valid number. Records in selection returns the num-
ber of records in the current selection of the specified table (not how
many records there are in the table). If there were three records, this loop
would execute three times, four records, four times, etc.
For ($Invoice;1;Records in selection([Invoice]))
the list of invoices for that contact. You have set up the relations correctly,
and have buttons to add and delete invoices to the contact record.
When you open a detail form for any contact record, 4D will manage all
the relations for you automatically. In this example, that means that when
you view a specific contact record in a detail form, 4D will load the related
invoice records for only that contact and display them in the subform.
That is the purpose of the subform – to display related many records for
the currently displayed one record. This saves you all the code that is nec-
essary to do this. Most of the time this is useful – it saves you work (and
coding errors).
At times, using a subform it may affect performance. If you open a contact
record that has ten thousand invoices and you only want to see the tele-
phone number, you may have to wait a while for the invoice records to
load, even though you are not interested in them. Therefore you can turn
Automatic Relations off when needed. The how’s, why’s and wherefores
are beyond the scope of this book but you can read the 4D, Inc. documen-
tation on Automatic Relations.
When you are not displaying a record in a detail form, 4D does not man-
age the relations. Therefore you need to load the related many records for
any given one/parent record. The easiest way to do this is by using the
RELATE MANY command. This command finds all the many records
(for any related tables, there may be more than one) that are linked from
the Invoice table Invoice_ID field. In this example only the invoice items
are linked. Since you are already at the first Invoice record this command
will find all invoice items for the first invoice record. The command does
not sort the records – they are in memory in the order in which they were
created. You may want to sort them by line item number if required
immediately after the RELATE MANY command (or whatever value you
need to sort by).
RELATE MANY([Invoice]Invoice_ID)
Now that you have both the invoice and invoice item records loaded into
memory, you can print them, using the syntax:
PRINT RECORD([Invoice];*)
This command prints the current record for the invoice table. The
optional * character suppresses the page setup and print setting dialogs. If
you did not pass this optional parameter, you would have a page setup and
Refining Your Application 9 – 19
Jumpstart 4D
print settings dialog displayed for every invoice that was printed. The ear-
lier PRINT SETTINGS command already allows you to set them for the
entire batch.
Although you are telling 4D to print only the invoice record, there is a
subform on the form that displays the related invoice items. The subform
will force them to print on the invoice form.
After printing this record you will want 4D to print the next record:
NEXT RECORD([Invoice])
The final step is to set the default output form back to your list view.
OUTPUT FORM([Invoice];"INV_lst")
This method of printing batches of forms is easy, but you have limited
control over the appearance of your final invoice in some circumstances.
What happens when you have more invoice items than will fit on a single
page?
Another way of printing is to break the form into multiple parts and print
these one after another. For the example above you would print:
+ One header containing the invoice address, etc.
+ You would print the invoice items in a loop: count the number of
lines printed to pad the invoice with blank lines, and handle page
breaks in any way that you like.
+ You would print a footer with your address etc.
+ You would use the PAGE BREAK command to complete the page.
This tells the printer that the page is complete and can be printed.
After this process the result would be three separate forms. You would use
the PRINT FORM command to print each form.
Assigning Menus When a User Logs In
A Chapter 8 showed you how to create Users and Groups. One common
task is to limit access to the database by the user’s group. A simple way of
doing this is to create different menu bars for each user, each menu bar
displaying only the tasks that the user can perform. This of course
becomes complicated when you have many different user groups.
9 – 20 Refining Your Application
Jumpstart 4D
The sample database for this chapter has a new user group defined as Col-
lection. People in this group cannot create invoices, edit them, or delete
them. They can see sales year-to-date totals, and find invoices that are past
due. From the invoice list form they can print batches to invoices to mail
out (and use any other buttons that might be there).
Your new employee Eva Rice is the only member of this group. (She’s
being punished for sins in a previous life by being made responsible for
collecting overdue invoices.) You do not want her adding new contact
records, modifying them, or any tasks not related to her job function.
+ Create Eva Rice as a new user using the Password Editor.
+ Assign her a startup method with a non-existent name. (This pre-
vents her from dropping into the User Environment.)
+ Give her a password. In this example database she does not have a
password assigned. In the cold, cruel world all the users should have
a password (otherwise people could log on as other users and gain
their access privileges).
+ Add the following code to the Startup project method (which is
called from the On Startup database method.
If (User in group(Current user;"Collection"))
MENU BAR(2)
READ ONLY(*)
End if
(The second menu bar has already been created for you.)
This code checks (at startup) to see if the user is a member of the Collec-
tion group. (There could be several users in this group.) If they are, then
Menu bar number 2 is assigned. The next command sets all tables in the
database to READ ONLY. The use of the optional * parameter means that
the user cannot edit any record in any table.
(All tables are set to read-only; if instead you pass a table name it would
make only that table read only.)
An interesting feature about the READ ONLY command is that is
does not stop users from creating new records (assuming they have
some way to do this). So although a table is read-only a user could
create new records in the table. They just can’t modify them after-
wards, or modify any other records. Many users perceive this as a
bug, but it is actually the correct behavior for databases – just not
the expected behavior.
You could of course have a Case statement in your startup project method
that would assign different menu bars based on the user’s group.
Back in that harsh world you may need more access control than this sim-
ple code provides. You may want users to access specific forms but not edit
specific fields, or even see certain data. Code to handle this is ideally
placed in the Form Method for the form concerned.
You can use the SET ENTERABLE command to make fields enterable, or
not, based on a user’s group. You could also use the SET VISIBLE com-
mand to hide specific fields.
Fields or variables that are made invisible cannot be tabbed clicked into, or
clicked on. As far as the user is concerned, they don’t exist.
Summary
You now have a very basic contact manager. For each contact you can have
multiple invoices, and each invoice can have multiple items. You can cre-
ate standard items to enforce consistency. At this point, the database is
functional but there are many more refinements you could make. The
forms (especially the detail forms) could have “nicer” buttons, fields could
be arranged in a different order, and so on. But in a few hours you can cre-
ate a functional, secure database that you can add to as you need.
The previous chapters have taught you all the basic skills that you need to
create any 4D database. The following chapters will cover other issues
such as compiling your database, handling cross-platform issues, upgrad-
ing from earlier versions of 4D, and so on.
The PDF documentation that comes with 4D is an invaluable resource for
learning the specific syntax of 4D commands, and don’t forget that there
are plenty of examples on the 4D, Inc. Web site at http://www.4d.com
When examining databases don’t forget to look at the contents of data-
base, form and object methods, as well as the more obvious project meth-
ods.
Compiling a 4D Application 10 – 1
Jumpstart 4D
There is a missing right parenthesis, which should appear at the end of the
line.
While this code is incorrect, 4D can guess what you meant, and will per-
form the operation without error while in interpreted mode.
4D Compiler however will not accept incorrect code. Therefore you
should correct all syntax errors before attempting to compile (syntax is the
grammar of a programming language). As 4D Compiler compiles your
database, it will generate a list of Errors it finds and your database will not
compile until all errors are fixed.
4D Compiler also generates Warnings. These might be errors. Your data-
base can be compiled even if you have warnings.
Consider the next case:
◊SomeInterprocessVariable:=13.01
4D assumes from this assignment that you want the variable ◊SomeInter-
processVariable to be of the Real data type since you had a decimal
point in the value. In most cases 4D Compiler will guess correctly, but it
may not always guess correctly.
Therefore, the 4D language provides compiler declarations to force the
data type for your variables. Variables do not always have to be defined for
the application to compile, but if 4D Compiler cannot guess the data type
it will generate an error.
10 – 2 Compiling a 4D Application
Jumpstart 4D
you can use text fields or variables instead of string fields or variables.
Remember that text fields cannot be indexed.
Where do you declare variables?
Local variables (those whose name begins with a $ symbol, including
parameters passed to methods) must be declared in the method in which
they are used (since their scope is limited to that method).
Process and interprocess variables can be defined in either:
+ The method in which they are used. This is easiest.
+ In another method. You can create other methods, one for each pro-
gram module, or one for each compiler declaration type, and declare
these variables in that method. In interpreted mode you must ensure
that these methods are called before the variables within them are
used. An easy way to do this is to call all your compiler declaration
methods from your startup method.
You should not change the data type of process or interprocess variables
from one type to another in different methods:
C_Boolean(Date) ` In one method it is boolean…
C_Date(Date) ` Then in another method it becomes date…
One method that can work well is to define a project method named
Compiler. This then calls further project methods named
COMPILER_Date, COMPILER_Boolean, and so on.
10 – 4 Compiling a 4D Application
Jumpstart 4D
Compiling an Application
To compile a 4D application, you must have either the Designer or
Administrator password if the application is password-protected.
The easiest way to launch 4D Compiler is to drag and drop your structure
onto an alias (Mac OS) or shortcut (Windows) of the compiler program.
This opens the structure in the 4D Compiler. You can also launch 4D
Compiler and then open your structure file from the File menu.
If you had previously created a compiler project for a database, you can
double-click the project file.
Figure 10-1: Main Compiler Dialog
You can click each of these buttons in turn to set the compilation options.
Compiled Database Name
Clicking this button displays an OS-specific dialog that allows you to
specify the name and location of your compiled database. You must give
the compiled database a different name from the interpreted (your source)
database name. If the name of your database was DataMaster, you could
name the compiled database DataMaster.cmp, for example.
Compiling a 4D Application 10 – 5
Jumpstart 4D
Error file
The compiler generates an on-screen list of error messages during compi-
lation. These errors can also be saved to a text file to speed up the process
of actually fixing them in 4D. This will be covered in more detail later in
this chapter.
Figure 10-3: Naming the Error File
Range checking
Range checking monitors the execution of methods only when the com-
piled database is running and not during the compilation process.
Range checking is very useful because there are certain types of problems
that can be detected only while the database executes. Examine the follow-
ing code:
C_String(10;$String_10)
$String_10:="" ` Max. 10 Character string
C_String(20;$String_20)
10 – 6 Compiling a 4D Application
Jumpstart 4D
$String_20:="12345678901234567890"
$String_10:=$String_20 ` This line will cause problems
Since the $String_10 string can only be 10 characters long, when you
assign the 20 character string to it (in the last line of code) the string will
be truncated down to 10 characters. This may or may not be what you
intended. 4D will not warn you if you do this. If you turn range checking
on for the compiled application 4D will warn you, when the program is
running, by displaying an alert message.
Warnings
Use this option to generate more extensive diagnostic messages in the
error file. There are two cases in which warning messages are invaluable:
+ Your code is compilable (all errors have been fixed), and you want
your code to be of the highest quality.
+ Your code contains statements that the compiler cannot evaluate
completely, even though it compiles without errors.
When this option is not selected, the compiler does not generate any
warning messages.
When the Basic… option is selected, the compiler generates warning mes-
sages, which are automatically written in the error file.
When the Advanced… option is selected, the compiler also generates
more detailed warnings. You should normally use this option.
Script Manager
The Script Manager enables programs to function with alphabets and
characters other than Roman ones, for example: Japanese, Chinese, Ara-
bic, or Hebrew. You would use this option if your database is going to be
used with a version of 4D that works under the Mac OS Script Manager
or a two-byte system on Windows.
Do not select it if you do not need it.
Create Executable Application
In 4D Compiler, you have an option that allows you to merge your com-
piled database with a 4D Engine and create a stand-alone executable
Compiling a 4D Application 10 – 7
Jumpstart 4D
10 – 8 Compiling a 4D Application
Jumpstart 4D
compilation path options, since skipping a variable typing pass will reduce
the number of warnings or errors generated by the compiler.
Default button type
Buttons are also long integer process variables (a clicked button has a value
of 1, an unclicked button 0) and should be declared as such in a suitable
location: this could be the project method that calls the form that the but-
tons are on, the form method for that form, or the object method for the
button (probably the best place). A typical button variable name might be
btn_Add_Invoice. You would declare it as:
C_LONGINT (btn_Add_Invoice)
By default, the compiler will try to type those variables that are untyped to
the type that has the largest scope, therefore if you have any undefined
buttons they will be typed as Real. Real uses 8 bytes and Longint uses 4.
Therefore with this option, you can force the type of the buttons to be real
or long integer. You should set it to Longint to save memory.
This option does not have priority over the compiler directives in your
database and affects the following active objects:
+ Check boxes, 3D check boxes.
+ Picture menus, Hierarchical pop-up menus, Hierarchical lists But-
tons, Highlight buttons, Invisible buttons, 3D buttons, Picture but-
tons, Button grids, Radio buttons, Radio pictures, 3D radio
buttons.
Default numeric type
By default, the compiler will try to type those numeric variables that are
untyped to the type that has the largest scope. With this option, you can
force the type of untyped number variables to be real or long integer.
This option does not have priority over compiler directives in your data-
base.
Default alphanumeric type
By default, the compiler will try to type those alphanumeric variables that
are umtyped to the type that has the largest scope. For alphanumeric vari-
ables this is text. With this option, you can force the type of strings of
Compiling a 4D Application 10 – 11
Jumpstart 4D
characters to be text or fixed string. This option does not have priority
over the compiler directives in your database.
If you choose to set the default alphanumeric type to fixed string, an enter-
able area appears so you can set the default length of the strings.
Automatic version
If you select this option, 4D Compiler automatically gives the compiled
database a version number in the format: 1.0dx. It starts at 0 for a new
compiler project.
This number is saved in the compiler project, and the “x” is incremented
with each new compilation.
When you select this option, an enterable area allows you to enter or mod-
ify the “x” value, which the compiler will use to number the compiled
databases.
On Windows, the version number will appear in the 4D “About…” dia-
log box when you use the SET ABOUT command.
On Mac OS, the compiler creates a vers resource if it does not already
exist. This resource is used by the Get Info menu command in the Finder.
If this resource already exists in the structure, 4D Compiler modifies it.
Eliminating the Errors
One of 4D Compiler’s options is to generate an error file. If this option is
enabled 4D Compiler will generate an ASCII text file that contains all the
errors and warnings. When you enable this option you are prompted to
name this file: the default is the same as the structure file plus the suffix
.err. The file is created by default in the same folder or directory as the
application that you compiled.
The file is in plain text format and is human-readable (assuming you can
read). Here is a typical complete error code file from an application with a
few errors:
Errors: 7Warnings: 0
10 – 12 Compiling a 4D Application
Jumpstart 4D
(M) CHCK_Acct_Prt
Error in line: 1
end
The variable END could not be typed.
(M) PO_List_ThisYr
Error in line: 20
$Year:=Num(Request"PO's for year";String(Year of(Current
date(*))))
This 4D command requires at least one parameter.
Incompatible type
Error in line: 21
$BegYear:=Date("1/1/"+$Year)
Changing the type of the variable $YEAR from type Real to type
Text
Error in line: 22
$EndYear:=Date("12/31/"+$Year)
Changing the type of the variable $YEAR from type Real to type
Text
(OM) [Contact].CNT_dtl.Button1
Error in line: 29
ALERT("No details found for "+String([Contact]Master))
Incompatible type
Compiling a 4D Application 10 – 13
Jumpstart 4D
Next compiler error will open the method (in the 4D method editor)
that contains the next error, and highlight the line it believes is in error:
Figure 10-5: Typical Error
The error message is displayed in the method header. In this case, the
word end had been typed and 4D has no way of guessing what the type
should be since there is no assignment of any value. (In real life the error
probably reflects a line of code that was cut and pasted badly: it was prob-
ably part of an End if statement.)
Stop browsing error file closes the error file and removes the addi-
tional menu items.
You can also print the error file using any text editor.
Fixing errors on 4D Server
If you have multiple programmers using 4D Server to develop a database,
you cannot fix compiler errors as described above. In this case you would
print multiple copies of the error file, assign errors to individual program-
mers manually, and they would have to manually open and correct the
errors.
10 – 14 Compiling a 4D Application
Jumpstart 4D
Recompiling
A typical scenario is that you compile an application, generate a few
errors, fix them and then recompile. By doing this, you would generate
fewer errors, and repeat until the application is error and warning free.
To recompile:
+ The error file must be closed.
+ The structure file must be closed (File ¬ Close Structure if you
are in the Design Environment).
When the compiling process results in zero errors, 4D Compiler will
delete any error file in the application folder and create the compiled data-
base.
4D will not create a compiled database until all errors are fixed (but
will allow you to compile if there are only warnings).
The fact that your database has compiled does not mean that it is error
free, only that all of the code meets 4D’s syntax rules. You may well have
errors of logic or bad formulae.
Building a Compiler Project
If you are developing an application and will be compiling it more than
once, you can create a compiler project. The project saves the option set-
tings for you so that you do not have to keep setting them each time you
compile (as long as you leave the structure file and location the same).
+ Select File ¬ Save as…
4D displays an OS-specific dialog that allows you to name and locate the
project file. The file location defaults to the same folder as the application
to be compiled which is a good place for it.
Compiling a 4D Application 10 – 15
Jumpstart 4D
10 – 16 Compiling a 4D Application
Jumpstart 4D
Chapter 11 – 4D Server
client list into the database, entered your products and prices, and can use
the system in single user mode without any problems. Now everyone
needs to be able to use the system that you have developed.
The following sections will deal with how 4D Server might be imple-
mented in this scenario.
Installing 4D Server and 4D Client
You should first decide onto which computer you are going to install 4D
Server. Recent G3/G4 Macintosh computers make good servers for small
networks due to their simplicity in setting up and maintaining. In many
applications a Windows NT/2000 Server will offer better performance in
larger networks due to its faster file-handling and disk I/O. 4D Server
does not currently take advantage of multiple processors.
Make sure that energy savers/sleep mode is turned off on the server.
If the server goes to sleep all client connections will be lost. (This is
often set to a default of on in many computers.)
You start by purchasing 4D Server for Mac OS or Windows from 4D, Inc.
4D Server comes with a license for two connections: these connections
can be for either platform. You then need to purchase additional connec-
tion licenses (known as clients or seats) for the rest of your users.
4D uses a concurrent connection license: it works on how many people are
connected to the server at one time, not by how many computers are actu-
ally on the network. Looking at the example above you might determine
that:
+ The manager only uses the system once a week to run reports, on
Saturday when the sales office is closed.
+ All sales staff use the system.
+ Orders ship once a day. One shipper uses the system for an hour,
from 4:00 P.M.to 5:00 P.M., to ‘ship’ orders.
+ The customer service representative. uses the system all day, from
9:00 A.M. to 4:00 P.M..
+ The accounts clerk rarely uses the system. Data is exported from the
system into QuickBooks.
From these specifications you can determine that only six people will ever
use the system at any one time. You therefore need six connections (seats).
Two came with the server, so an additional four must be purchased.
11 – 2 4D Server
Jumpstart 4D
4D Server 11 – 3
Jumpstart 4D
Click the Add Expansion Serial Number button to enter the serial
number for your additional client connections. 4D decodes the serial
number and adds the appropriate licenses. You will now be able to make
all your simultaneous connections. (You can add further serial numbers
later if required.) Your server is now operational.
Install 4D Client
You can legally install 4D Client on every computer on your network. In
this case 4D’s client/server connection license management will only allow
any six computers to simultaneously connect (in this case). It does not
matter which six computers are connected. Your clients can be any mix-
ture of Mac OS and Windows. You may need to adjust the default mem-
ory settings for the client. (See the instructions that come with the 4D
installation CD.)
Launch 4D Client
You can now launch 4D Client and connect to the server. When 4D Cli-
ent opens, it searches the network for any and all 4D Servers that are run-
ning. Any that are found are displayed in the list and the user can select to
which database he or she would like to connect.
11 – 4 4D Server
Jumpstart 4D
If you do not see any servers you might have one of two problems:
+ The client computer is not on the network that the server is on, or
your network is faulty (Hint: fix it).
+ The wrong network protocol is selected in 4D Client. For example
you may have installed 4D Server on Windows, and the 4D Client
is on Mac OS and has defaulted to Apple Data Share Protocol
(ADSP) rather than TCP. You can change this, and should then see
the server.
+ Click the Other button. The following dialog is displayed which
will allow you to select a different network protocol (from the list of
network components that is installed).
Figure 11-3: Select Network Component Dialog
Select the TCP network component and click OK. The TCP connection
dialog is then displayed. You should now be able to select the server to
which you wish to connect. This setting is remembered the next time you
open 4D Client (so the user does not have to keep doing this).
4D Server 11 – 5
Jumpstart 4D
Local resources
The first time you connect from any client to the server you will see a dia-
log displayed that displays the message Duplicating resources
locally… This may take a few seconds if your database is large, and will
happen for each new client the first time they connect.
4D copies much of the structure of the database from the server to your
client computer, including the table and field definitions, all menu bars,
forms and so on. These are stored in files with the suffixes .RES and .REX
(these files are not obvious to your user, they are hidden away to avoid
confusion or accidental deletion). Then every time you need to display
some data in a form, 4D already has the form stored locally and does not
need to load it over the network. This reduces the network load consider-
ably and therefore improves performance.
Later you will see what happens when you update the structure on the
server.
Updating Your Applications
One day you add a few refinements to the database application that you
are still improving using your computer at home. You now want to install
this latest version on the server at your workplace:
+ All 4D Clients must quit first.
+ Quit 4D Server and back up your old database application (always
keep a backup in case the update causes problems).
+ Replace the copy of your database application on the server with
your new copy.
11 – 6 4D Server
Jumpstart 4D
+ Launch 4D Server and make sure that you open the correct version
of the new database.
+ Connect with 4D clients.
The first time each client connects 4D will detect that the version of the
database running in the server is different to the one stored on the local
client computer in the .RES and .REX files. 4D will automatically down-
load the newer versions of the resources to the client. If the new database
has the same name as the old database, 4D will overwrite the old .RES
and .REX files. If the names are different, you will end up with both the
new and the old files, but 4D will use only the latest downloaded files. In
this scenario it is possible to gradually fill up your client hard drive with
the old files, therefore you should delete these.
Multi-User Issues
You can take a copy of any database written with 4D and open it using the
matching 4D Server. You do not need to make any changes (in simple
applications) and 4D handles many of the issues that arise in multi-user
environments without any coding on your part.
However you may need to modify your code to deal with some issues.
When tow users edit the same record
What happens when two people want to edit same record? For example
sales (Person A) are taking an order from Jim Smith, and accounts depart-
ment (Person B) need to credit him with a refund.
The first person to open the record locks it automatically to others (thus
becoming the owner of the record). The first person can make any changes
they want to the record since they own it. Anyone else who attempts to
open the record will see an alert that warns them that the record is in use
by Person A, and that they can only open it as Read Only. In read only
mode, they can view the record but cannot make changes.
If Person A goes home without either saving or cancelling the changes to
the record, it will remain locked until they do. 4D automatically handles
all of this and without the need for any code from you. 4D’s behavior is
desirable.
When Person A closes the record, it is unlocked, but since the locked copy
is still in memory in the accounts department client computer (Person B)
4D Server 11 – 7
Jumpstart 4D
it is still not available for Person B to edit. Person B could either close the
record, and open it again to modify it, or you could add a button with an
object method that would keep attempting to reload it (LOAD RECORD
command in a loop) until it was saved or cancelled by the first user (and
just hope they did not go home).
When you want to lock a selection of records until you have fin-
ished a task
You might want to update all the prices in your inventory table. You
would normally do this in a loop. While this is running you do not want
anyone else modifying any of these records. When they do so, they will
lock the record – this may be before you get to it in your loop. In a loop if
the code hits a locked record, it will perform the calculations but will not
be able to save the changes (since it is locked). 4D does not warn you that
locked records have been skipped. One way to handle this is to wait until
everyone else has gone home (the non-programming approach often
works well).
The programming way is to use a semaphore. First your code checks the
LockedSet for the table you are working with, waiting until it has zero
records in it. The LockedSet contains all records for the specified table
that are currently locked (somewhat like the UserSet). When it is empty,
you set a semaphore (like a flag) and then start your code to update the
records. In any code that allows users to modify any records in this table
you test for the presence of the semaphore. If the semaphore is present,
you only allow the user to open the record in READ ONLY mode. If the
semaphore is clear then the user can open the record as READ WRITE
mode. When your updating code finishes, you clear the semaphore.
A more detailed explanation of the use of semaphores is beyond the scope
of this book.
Some commands behave differently on 4D Server
Some commands behave differently, or produce different results, when
used in 4D Server. When you are using 4D, everything can only happen
in the copy of 4D. In 4D Server some commands execute on the server,
and most execute on the client. Where the results are stored can also differ
(for example, set operations).
11 – 8 4D Server
Jumpstart 4D
4D Server 11 – 9
Jumpstart 4D
11 – 10 4D Server
Jumpstart 4D
Chapter 12 – 4D Insider
- Object names can indicate the data type or use for an object.
Reading the code becomes easier (especially for other pro-
grammers or in several years time).
- Program errors, where the wrong type of object is assigned to
another, can be avoided. Naming conventions can eliminate
naming conflicts where two or more objects can inadvertently
share the same name and cause program errors. Certain names
will be used frequently, for example, “date”. When used as a
process or interprocess variable this could cause conflicts. But
if the variable name is prefixed with a module name or noun
to which it refers, it is less likely to cause conflict, for example
“Invoice_Date”, “PO_Date”, etc.
- Naming conventions are especially important when creating
components. Your code will now be used by other program-
mers who are unaware of your naming conventions.
+ Documentation will help any developer to understand what the
code is meant to do (perhaps rather than what it actually does).
While 4D allows developers to insert comments within methods,
4D Insider allows you to add comments to a wider range of objects.
(This documentation can only be viewed with 4D Insider though.)
4D Insider can also export this documentation to a text file which
can be used to create program or user documentation.
+ If an application needs to be localized for use in other countries, the
task can be made easier by using STR# resources. For example,
instead of explicitly declaring the text label for an object, for exam-
ple Done on a button, you can instead refer to a STR# resource. All
STR# resources can then be exported to a text file, translated into
other languages, and then reimported.
+ 4D Insider can be used to create code libraries of frequently used
code. This can then be reused in other databases to save time and
resources, and to ensure consistency between applications.
+ 4D Insider can create 4D Databases from SQL 92 text files. SQL 92
files can be created by a number of CASE tools.
+ 4D Insider can be used to scale forms used in cross-platform data-
bases.
- Mac OS applications normally use 72 dpi as their screen reso-
lution, while Windows uses 96 dpi. This results in objects that
are created on the Mac OS looking approximately 25%
12 – 2 4D Insider
Jumpstart 4D
You can use the Replace features to rename objects in your database or 4D
Insider library. To rename objects, you can use one of several techniques:
+ Rename an object by substituting another name.
+ Replace a sequence of characters in the names of any number of
objects with another string of characters.
+ Add a prefix to the names of any number of selected objects. This is
useful for grouping objects together into modules.
When you rename objects in a database, the objects are renamed every-
where that they are used. This is true for all renaming operations except
for renaming a single object. In this case, 4D Insider allows you to choose
the locations in which the object should be renamed.
Renaming objects can be useful in a number of circumstances. For exam-
ple, you can change all process variables into interprocess variables, or vice
versa. To do this, find all process variables and then add the prefix symbol
for interprocess variables (◊ which is Option+Shift+v on Mac OS or ‘< >’
on Windows) to their names.
Replacing Commands
You can replace 4D commands in selected methods using the Tools ¬
Replace 4D command... . You can replace a command with an existing
project method or with a new project method. To replace a 4D command
in a selection of methods:
+ Select the objects for which you want to replace a command. To cre-
ate a continuous selection, Shift+Click the first and last objects in a
series. To create a non-adjacent selection, Control+Click (on Win-
dows) or Command+Click (on Mac OS) on the individual objects.
To select all the items in a list, choose Select All from the Edit
menu.
+ Choose Replace 4D command... from the Tools menu. The
Replace 4D command dialog box appears.
+ Select the command to be replaced by clicking its name in the list,
or by typing the first few characters of its name. The command is
selected in the command list, and the command name appears in
the text box below the list.
12 – 4 4D Insider
Jumpstart 4D
4D Insider 12 – 5
Jumpstart 4D
4D Insider 12 – 7
Jumpstart 4D
12 – 8 4D Insider
Jumpstart 4D
4D Insider 12 – 9
Jumpstart 4D
Formats/Filters None
Lists None
Menus None
Plug-ins None
Tables Fields
Subfields
Triggers
Copying an object
You can copy objects from a database or library to another database or
library. When you copy an object, Insider identifies all the dependencies
for the object. This list of dependencies includes all the objects that it uses.
Since objects in a database are interdependent, when you copy one object,
you may need to copy others in order to preserve the object’s functionality.
For example, if you copy a method to another database, you may also
want to copy the methods called by that method. At other times, you may
want to copy only some or none of the dependencies.
When you copy an object, you can choose to copy:
+ the object itself.
+ the object with some of the objects it uses.
12 – 10 4D Insider
Jumpstart 4D
Code Libraries
A library is a 4D Insider file that contains a set of structure objects. (On
Windows its file extension is .4IL.) By copying objects to a library file, you
can maintain a set of objects commonly used in your databases. This
library can easily be copied into other databases, allowing you to reuse the
objects in whichever database or library you want. 4D Insider libraries
provide a way to exchange modular 4D structure components within a
work group.
You can create as many library files as you want, organizing objects into
different library files according to their use or functionality. A library file
can be opened locally and only by 4D Insider.
STR# Resources
STR# resources are collections of text strings that are used for menus, but-
ton text, and static text on forms. Instead of hard-coding text for menus,
buttons, and forms, you can reference a STR# resource by number.
Localizing databases is much easier when you use STR# resources. Instead
of modifying each form, menu or button, you just modify the STR#
resource. STR# resources contain strings that can be used in place of static
text in menus and forms. For example, a button on a form could be
labeled 15000,1 to indicate that the text for the button should be retrieved
from item 1 of STR# resource ID 15000.
You use 4D Insider to create and edit STR# resources on either Mac OS
or in Windows. You can also use a resource editor, such as ResEdit or
Resorcerer to edit them on Mac OS.
If a form or menu does not contain any STR# resources, 4D Insider can
convert fixed strings so that they use STR# resources instead.
When you double-click a STR# resource list, the Object Contents area
displays the string resource numbers and their items. The information bar
displays the name and ID of the resource.
The following objects can use string resources for their text:
+ Menus and menu items
+ Buttons
+ Text objects in a form, such as field labels
12 – 12 4D Insider
Jumpstart 4D
You can export strings, translate them, and then import them back into
the database.
Utility Functions
Creating a new database
In addition to opening an existing database locally, 4D Insider enables you
to create a new empty database. Once you have created a new database,
you can add objects to it by copying objects from other databases or
Insider libraries.
A database must contain at least one table before it can be saved.
Displaying ID numbers of objects
The internal ID number of an object is a number used by 4D to keep
track of each design object in the structure file of a database. Insider also
uses these numbers to track objects in databases and libraries.
In 4D Insider, you can choose to display the internal ID numbers of
objects in the Main lists of browser windows.
If 4D, 4D Tools, or any other 4D program signals an error with an object,
the error window provides you with the ID number of the object. Copy-
ing all the objects, except the damaged ones, from the damaged database
to a new database, enables you to recover a structure file manually when
you have no backups.
Form scaling
4D Insider can rescale form objects. Insider also lets you rescale multiple
forms, so you can modify a group of forms. There is no Undo function
available after implementing a rescaling operation.
Form objects created on Mac OS will look smaller when viewed on Win-
dows and vice versa, even though the objects are actually the same size.
This is because the Windows screen resolution is about 25% greater than
the Macintosh resolution (96 dpi vs. 72 dpi). For example, 12-point text
on a Macintosh will appear as 9-point text on Windows.
If the font size is just large enough on Mac OS, it may be too small on
Windows. Conversely, if a font size on Windows is adequate, it may be
too large on Mac OS.
4D Insider 12 – 13
Jumpstart 4D
You can scale several forms of a database at the same time. Scaling forms
normally means that you will require two copies of all forms used on
screen: one selection of forms for use on Mac OS and one for use with
Windows. You probably want to create these before you start scaling.
The most efficient way to do this would be to do all development on one
platform and finalize forms on that platform. Then duplicate all forms
that are needed for screen uses and rename them with a platform specific
suffix or prefix. These can then be rescaled and then tweaked by hand later
as required.
Exporting
You can export objects from the Main list to a text file. When you export
an object, you can choose to export its contents, the list of objects it is
used by, the list of objects it uses, and its documentation. You can export
objects from a database or a library.
Since export files can contain only text, only the text-based contents of an
object can be exported. The following objects are text-based:
Table 12-2: Exportable Objects
Database Methods
Form Methods
Object Methods
Project Methods
Tips
Triggers
4D Components
4D Insider v6.7 allows component generation and installation in 4D v6.7
databases. This new feature allows developers to more easily supply, or
market 4D code to others. A component groups various 4D objects tables,
project methods, forms, menu bars, variables etc. together, and this is then
saved to a special file format on disk.
Unlike libraries and groups, components embed the idea of security for
the objects that they comprise of. During the development phase of the
12 – 14 4D Insider
Jumpstart 4D
4D Insider 12 – 15
Jumpstart 4D
The following table summarizes the way component objects can be man-
aged in 4D and 4D Insider, according to their attributes.
Table 12-3:
Protected Yes No No No
Private No No No No
4D Insider 12 – 17
Jumpstart 4D
12 – 18 4D Insider
Jumpstart 4D
Chapter 13 – 4D Utilities
4D Utilities 13 – 1
Jumpstart 4D
Select either the Administrator or Designer from the User list, and then
type the correct password. Click OK to open your database. The main 4D
Tools window is displayed. The dialog displays four tabs:
+ Information – information about the structure and data files.
+ Maintain – tools to maintain your database.
+ Repair – tools to repair a damaged data file.
+ Structure – tools to check and repair the structure file.
Figure 13-1: 4D Tools Window
Information tab
The path to the data file (and any additional data file segments) is dis-
played in the Data Segments field. The segment size[s] and the amount
of free disk space are listed below this field. (If there is only one segment
its size is displayed; if there is more than one, the size is displayed for the
segment that you select.)
13 – 2 4D Utilities
Jumpstart 4D
4D Utilities 13 – 3
Jumpstart 4D
Click the Check All button to check all the records and indexes in the
data file. 4D Tools will check for various types of record and index damage
and report any problems that it found. 4D Tools displays a dialog indicat-
ing the results of the check. If there are damaged records or indexes, a list
of the damaged items will be written to the journal file.
Click the Check Records… button to check only for damaged records.
4D Tools displays a dialog where you can select which tables to check.
Figure 13-3: Table Selection
Select which tables you would like to check and click the Check button
to continue checking. 4D Tools will check for various types of record
damage. If any damage is found, the following dialog will be displayed:
Figure 13-4: Details Dialog
The details of which records are damaged are written to a Journal File:
this is saved in the same folder (directory) as the application being exam-
ined with 4D Tools.
13 – 4 4D Utilities
Jumpstart 4D
Click the Check Indexes… button to check the data file indexes. This
presents a dialog where you can select which indexes to check. Usually you
would check all of them.
Figure 13-5: Selecting Indexes to Check
If an index is damaged, you may not find a record in the database even
though it is there (most types of queries use the index, not the data, for
searching). After you have selected which indexes you wish to check, click
the Check button. If there is any damage to the indexes, you will be
warned by 4D Tools to check the Journal File.
You can click the Sort… button if you wish to permanently sort the con-
tents of a specific table. You will rarely need to do this. You may wish to do
this if you have a static table (one that changes rarely) that needs to be
printed regularly in some sorted order – sorting the contents will eliminate
the need to sort the table at the time of printing.
Click the Compact… button to compact the data file. This process cre-
ates a copy of the data file with all holes in the data eliminated (so that the
records and indexes are in one continuous stream within the data file). You
can choose the name and location of the new data file using the standard
OS file save dialog that 4D Tools displays.
Compacting may take some time based on the size of the data file
and the speed of your computer.
4D Utilities 13 – 5
Jumpstart 4D
Repair tab
If 4D Tools has detected any record or index damage, you can attempt to
repair it here. Common errors that can cause the data file to be damaged
are the database crashing while data was being flushed to disk (from
RAM), or power surges or brownouts that occurred during disk activity.
Damage to the indexes is more likely than damage to the data. 4D can fix
most of these errors. If 4D cannot fix them, you may be able to recover
most, or all, of the data by using Recover by tags.
Click Repair All… to attempt to repair both damaged indexes and
records. Progress thermometers indicate the progress of the repairs, and a
final dialog indicates whether the repairs were apparently successful or
not. (Some record damage may not be detected or fixed.)
Click Repair Records… to attempt to repair records only. You can select
which tables to repair using the displayed dialog. Progress thermometers
indicate the progress, and a final dialog indicates whether the repairs were
apparently successful or not.
Click Repair Indexes… to attempt to repair indexes only. You can select
which indexes to repair using the displayed dialog. Thermometers indicate
the progress, and a final dialog indicates whether the repairs were appar-
ently successful or not.
At this point you could check for damaged records and indexes again. If
4D Tools indicates that the records are still damaged, you will have to
recover the data by tags. There are other warning signals that your data file
may be damaged:
+ Queries do not return the expected results (records appear to be
missing). You may be able to find these records in the User Envi-
ronment.
+ The same query returns different results each time it is performed.
+ 4D crashed when importing data or while flushing changes to disk
(4D will warn you if it crashed while flushing its cache).
+ 4D error messages have alerted you to damaged records.
+ Queries on indexed fields run slowly (which is unusual).
+ You frequently change field types within tables that contained data.
13 – 6 4D Utilities
Jumpstart 4D
First ensure that you have sufficient free disk space to complete the recover
by tags. A minimum would be the combined size of the structure and data
files but twice that amount would be safer.
To recover the data file, click the Recover… button. 4D Tools displays a
standard OS file save dialog that allows you to name and locate the recov-
ered data file. 4D Tools will now scavenge the data from the old data file
(as best it can) and create a new data file containing this data. New indexes
will be created from this data. A side effect of this process is that the new
data file will be compacted. This will take longer than compacting the data
file since the data has to be extracted from the damaged data file first. You
should keep the old data file until you are certain that the recovered data
file is working correctly.
Data File Segments
4D data files can comprise up to 64 2GB segments. The reason for this
approach, rather than one 128 GB segment, is that until recently most
operating systems could not support a single file larger than 2GB. You can
use the Split… button that appears on the file save dialog when you
choose to Compact or Recover a data file. Using this button, you can
create additional segments that are linked by 4D to the first data segment
(which is your original data file).
One essential point: Never let your first segment (data file) grow larger
than approximately 1.92 GB. If the first data segment reaches 2GB you
will not be able to create the additional segments, and you will not be able
to enter any more data into it either. (If this does happen, you may be able
to delete some data, or drop some indexes, and then compact the file until
it is smaller than 2GB. Then you can create the additional segments.)
Structure tab
The structure tab allows you to examine the fragmentation state of the
structure and check various structure objects for damage. Fragmentation
in the structure occurs when you frequently delete objects, such as forms.
If the structure has become highly fragmented, you can compact it in the
same way as the data file. Fragmentation in the structure file will have no
impact on the performance of the database, but compacting the structure
will make the file smaller. This has several benefits:
4D Utilities 13 – 7
Jumpstart 4D
You can enable or disable any options you wish. (You would probably
want to enable Generate a log file.)
Resource map
+ Checks the integrity of resources – this is a very low-level operation.
Passwords
+ If 4D Tools encounters a problem loading the password table, it will
try to recover the Designer password. All other users and groups
will be deleted. In the repaired database, the password table no
longer contains the Designer (if its name has been changed, the new
name will be restored).
+ Checking will be terminated if the database is badly damaged (for
example, if the password table is missing).
+ 4D Tools writes a list to the journal of the objects whose access priv-
ileges have been removed if the Activity Report option is activated.
13 – 8 4D Utilities
Jumpstart 4D
Lists
+ If a list is referenced but does not exist, it will be created.
+ If a list exists but is not referenced, a reference to it will be created.
Menu bars
+ If a menu bar is damaged, it will be replaced by a generic menu bar.
+ If a menu bar is referenced but does not exist, it will be created as an
empty menu bar.
+ If a menu bar exists but is not referenced, or if a menu exists but is
not referenced in a menu bar, it will be deleted.
Database methods
+ If a database method is referenced but does not exist, an empty data-
base method will be created.
+ If a database method exists but is not referenced, it will be recovered
if the Looking for Lost Methods option has been checked.
Project methods
+ If a method is referenced but does not exist, an empty project
method will be created.
+ It is possible to recover damaged methods if the Looking for Lost
Methods option has been checked.
Pictures
+ If a picture is referenced but does not exist, an empty picture will be
created.
+ If an image exists but is not referenced, a reference to it will be cre-
ated.
Help Items
+ If a help balloon is referenced but does not exist, it will be created.
+ If a help balloon exists but is not referenced, a reference to it will be
created.
4D Utilities 13 – 9
Jumpstart 4D
Tables, forms, …
+ If the structure of the tables/fields is faulty, 4D Tools will stop the
repair process. The database is no longer usable. (This is why you
should keep backups of your structure files, as well as your data
files.)
+ If the internal references of a table are damaged, the forms linked to
this table will be lost. Only the object and form methods can be
retrieved as lost methods.
+ If a form is damaged, it will be replaced by a generic form contain-
ing a Cancel button. Only the form method will remain attached to
the form. Other objects on the form will be lost. The methods of
these objects can be recovered as lost methods.
+ For each form, 4D Tools checks if there is a form method and/or
object methods. If a form method or object method is referenced
but does not exist, it will be created.
Lost methods
+ Retrieved lost methods are saved as project methods.
+ This option is only active if the Database Methods, Project Meth-
ods and Tables, forms, … options have been enabled.
+ It is only after selecting all these options that it is possible to estab-
lish a list of methods that are not referenced by any other object.
This list therefore becomes the list of lost methods.
The checking of Resources (I) and Resources (II) is controlled by 4D.
Generating a log file
This option should be enabled. 4D Tools will then create a journal file
that will record any errors that it found and any corrective action that it
took. This file can be viewed with any text editor or word processor.
Repairing a Structure
Click the Repair… button to repair damage to the structure file. 4D
Tools displays a dialog (similar to the one displayed when checking the
structure) which allows you to select which structure objects to repair.
Make your selection (usually all of them) then click the Repair button.
13 – 10 4D Utilities
Jumpstart 4D
Compacting a Structure
You can compact a fragmented structure file by clicking the Compact…
button. 4D Tools displays the standard OS file save dialog that allows you
to name the compacted structure file and choose its location.
Customizer Plus
Customizer Plus allows you to customize certain aspects of your finished
database. Some of these settings can be changed in the database using the
Database Properties tab. You can give Customizer Plus to your users to
change database properties without them having access to the Design
Environment. You can also use Customizer Plus to customize settings in
compiled, compiled and merged, and 4D Server based applications. You
can modify settings for both the Structure and Data files. Customizer Plus
can be used to modify some settings in all of the following applications:
+ 4D, 4D Server, and 4D Client.
+ 4D Engine, 4D Interpreted Runtime and 4D Runtime Classic
+ 4D Plug-ins located in the MAC4DX and WIN4DX folders, such
as 4D Write, 4D Draw, 4D Calc, 4D Backup, etc.
+ Applications that belong to 4D environment, such as 4D Compiler,
4D Insider, etc.
Customizer Plus can also be used to modify settings in 4D structure files:
+ Database Properties of 4D applications.
+ 4D database structure files (interpreted or compiled).
+ Compiled databases integrated with a 4D Engine.
+ 4D data files.
+ Network component files (ADSP.opt, TCP.opt, IPX.opt, etc.)
Changes made to a 4D application (such as 4D V6.7) will affect all data-
bases run by that application, while changes made to database files will
only affect those databases.
Start by launching Customizer Plus and then locating the Structure or
Data file to open from the File ¬ Open… menu. Alternatively you can
drag and drop the structure or data file icon on to the Customer Plus Icon
or alias/shortcut. The following dialog is displayed:
4D Utilities 13 – 11
Jumpstart 4D
Here you can modify the keyboard shortcuts, for Mac OS and Windows,
for the three actions defined.
Window
Figure 13-9: Window Size Setting
13 – 12 4D Utilities
Jumpstart 4D
+ Full screen with title: Opens a window equal to the size of the
screen of the computer in use, and includes a title bar.
+ Full screen without title: Same as above without a title bar.
+ Constant size: Keeps the window a constant size no matter what
type of computer is being used with the program. The size can be set
either with the pop-up menu or the coordinate boxes.
+ Constant size (centered): Same as above, but centers the win-
dow instead of using an absolute placement based on the coordinate
values.
+ Keep last position: Opens the window using its previous location
and size.
The right part of the window lets you enter the coordinates manually or
select the window coordinates from a drop-down menu, depending on the
display selected. After you select an element in the Choose screen size
pop-up menu, the screen coordinates are automatically completed, and
the pop-up menu displays the Choose screen size option again.
If your database uses the 4D toolbar, select an element with Toolbar in
order to avoid masking the top of the window with the toolbar.
WEDD
Since the WEDD resource icon was grayed out, double-clicking it will ask
you to create a new resource (parameter group). Click OK if you wish to
create this new resource.
Figure 13-10: Create New Parameters Group Dialog
4D Utilities 13 – 13
Jumpstart 4D
The WEDD resource allows you to wed (link) a data file to a structure
file, to prevent the user from inadvertently opening the wrong data file. To
do this you create a signature: this is a text string that is the same in both
WEDD resources (data and structure files). If the strings do not exactly
match the data file, they cannot be opened by the structure file. Later you
can delete the WEDD resources if you no longer need them.
If you create a WEDD resource in one file and not the other, you will not
be able to open the data file from the matching structure file. Therefore
you will have to either create matching signatures or delete the WEDD
resources. For example if you open the structure file with Customizer
Plus and create a new WEDD resource, and then enter nothing in it, you
end up with a WEDD resource containing a Null (empty) string. When
you launch the structure it will attempt to open the corresponding data
file (the file in the same folder/directory whose names are the same but
appended with .data/.dat). 4D checks to see if there is a WEDD resource
with the corresponding signature. Since there isn’t, you will get the follow-
ing error message: “The structure and data files do not correspond to each
other. The data file cannot be opened with this structure”. Do not panic!
At this point you must either:
+ Create matching resources.
+ Delete the WEDD resource.
To create matching WEDD resources, open the structure file with Cus-
tomizer Plus. Double click the WEDD resource (if grayed out click OK
to create a new one) and type a string of characters in the Signature field.
Copy these to the clipboard. Quit and save Customizer Plus. Open the
data file with Customizer Plus. Double-click the WEDD resource (if
grayed out click OK to create a new resource) and paste the signature from
the clipboard into the Signature field. Quit and Save Customizer Plus. You
will now be able to open your data file from its corresponding structure
file but not from any other structure file.
An alternative is to delete the WEDD resources. If you are on Mac OS,
this is done by holding down the Option key and double-clicking on the
WEDD resource icon. If you are using a PC, this is done by holding down
the Alt key and double-clicking on the WEDD resource icon. The icon
will turn gray and the resource has been removed. You need to remove the
WEDD resources from both data and structure files.
13 – 14 4D Utilities
Jumpstart 4D
Preferences
Figure 13-12: Preferences Dialog
Stack size
Specifies how much memory is allocated to the stack when the program is
launched. Each time you call a method from within a method, all passed
parameters, local variables, and 4D commands in the calling method are
placed on the stack. Any records that are pushed (then popped) are also
placed on the stack.
The number of nested subroutines that can be called is limited only by the
available space on the stack. If you receive Stack is full error messages dur-
ing method execution, you might consider increasing the stack size. 4D,
Inc. recommends that you increment the stack size by 4K at a time.
Beach ball
Specifies if a spinning beach ball cursor should be displayed during
lengthy operations. The check box is selected by default. This can slow
processing down.
Print one job
By default, when you send a report to a printer using the PRINT SELEC-
TION command, 4D treats each page of the report as a separate print job.
To print the entire report as one job, select Print One Job. This option is
especially useful when you send a report to a fax machine, or are creating
4D Utilities 13 – 15
Jumpstart 4D
PDF pages where you want all pages to be part of one document, rather
than having each page as a separate PDF document.
Display printing progress
Displays 4D’s print progress dialog (in addition to the OS print progress
dialog).
Display flush window
4D saves record changes to RAM, and flushes the changes to hard disk at
three predetermined times:
+ When the cache is full.
+ After the number of minutes has elapsed that you set in Database
Properties.
+ After you issue the command FLUSH BUFFERS.
When this happens, 4D’s default behavior is to display a small dialog box.
The display of the dialog box can be turned off.
Real precision (Macintosh)
These options allow you to set the number of insignificant digits (digits
that will not be taken into account when a real number is displayed on the
screen), starting from the right. By default, this value is set to 0 for the
68K-based version of 4D and to 5 for the PPC version.
Main Memory Application for Windows
On Windows you must determine how much memory your 4D applica-
tion will use. You achieve this by setting the number of blocks of memory
and the size of each block (all blocks will be the same size). On Mac OS
you select the copy of 4D and use Get Info (Command+I) to set memory
size. On Mac OS you set the minimum size that the application requires
and its preferred size.
Number of blocks
This is the maximum number of blocks you wish to allocate. If you have
decided that you wish to allocate 40 MB of RAM to your 4D application,
you could allocate it as four 10 MB blocks, or ten 4 MB blocks.
13 – 16 4D Utilities
Jumpstart 4D
This parameter group is available for structure files only. This parameter
allows you to trigger the update of the .RES file located in the 4D folder
of the client machine, when 4D Client connects to 4D Server. If you
increment this parameter, the YourDatabase.res file is updated at the next
connection. Incrementing the Update Signature forces an update between
Server and Client.
4D Utilities 13 – 17
Jumpstart 4D
Properties
Figure 13-15: Properties Dialog
Platform
Determines the platform appearance that your application will use (e.g.
Win NT 3.51., Win 95/98, etc.).
Default Font
The default font is specified for the platform chosen in the Platform drop-
down list. The following are the default fonts for each platform. The
default font and default font size are used in the Structure Editor.
Table 13-1: Default Fonts
MacOS Geneva 9
13 – 18 4D Utilities
Jumpstart 4D
Regular Size
You can specify the point size for 4D’s regular size.
Large Size
You can specify the point size for 4D’s large size.
Message font
This allows you to specify the font that will be used in message dialogs.
Size
This allows you to specify the font size that will be used in message dia-
logs.
Scheduler
The scheduler settings allow you to control how much of the CPU time
4D Server will take. These settings are most important when 4D or 4D
Server is running on a computer that is also executing other applications.
Depending on the settings, 4D may take over practically all CPU time
thus reducing the performance of other applications. By adjusting the
Number of ticks between calls to OS, the Maximum number of
ticks per call to OS and the Minimum number of ticks per call to
OS you can adjust the responsiveness of the server.
4D Utilities 13 – 19
Jumpstart 4D
13 – 20 4D Utilities
Jumpstart 4D
+ The data fork of the data file is copied into a .4DD file. This file is
called the database data file on Windows.
+ The resource fork of the data file (if not empty) is copied into a
.4DR file. This file is called the database data resource file on Win-
dows. Usually this fork will be empty unless you have created a
WEDD resource.
If you had a database called Customers (for example), transporting the
Mac OS database to Windows would create the files Customers.4DB and
Customers.RSR from the Customers file and the files Customers.4DD
(and possibly Customers.4DR) from the Customers.data file.
4D Transporter performs the transport of a Windows 4D database as fol-
lows:
+ It merges the .4DB and .RSR files of the Windows database into
one file that becomes the database structure file of the Macintosh
database.
+ It merges the .4DD (and possibly .4DR) files of the Windows data-
base into one file that becomes the database data file of the Mac OS
database.
In the Customers example above, transporting the Windows database to
Mac OS creates the Customers file from Customers.4DB and Custom-
ers.RSR and the file Customers.data from Customers.4DD (and possibly
Customers.4DR).
The two operations are symmetric: databases can be created and/or modi-
fied on one platform, then transported to the other platform multiple
times. The platform-independent technology of 4D does the rest. No
matter which platform you are using, 4D stores all your objects and
records in such a way so they can be read on both platforms. In addition,
the Windows version allows you to use the Mac OS resources present in
your database.
If you are copying a database from Mac OS to a Windows computer using
the NTFS file system, you do not need to use 4D Transporter. You can
copy the files over and immediately open them using 4D v6.7 for Win-
dows. 4D will transport the files internally. This only works with 4D v6.7
and higher and NTFS. It does not work on Fat16 or FAT32 file systems.
4D Utilities 13 – 21
Jumpstart 4D
Note:
On Mac OS, 4D Transporter is a modal application: that is while it is
open you cannot switch to other applications—you must first quit.
Preferences
Give a DOS file name
The name of a database is limited to 31 characters on both Mac OS and
Windows.
However, on Windows, you may work with a volume where filenames are
subjected to the 8.3 character DOS limit. The Give a DOS File Name
option (selected by default) tells 4D Transporter to enforce this rule and
modify filenames when transporting files from Mac OS to Windows.
Characters such as space, /, *, and so forth are replaced by underscores. If
the DOS naming convention is enforced, all characters other than conso-
nants are eliminated and, if after this operation, the name is too long, it is
truncated to 8 characters.
4D is able to work with transported databases no matter which option is
selected. Enforcing the DOS naming convention is useful only when
other Windows applications (that do not support long filenames) may
access the files.
Show preferences
This option tells 4D Transporter to display its window when you launch
the application or drag and drop files onto its icon. This is the default
13 – 22 4D Utilities
Jumpstart 4D
4D Utilities 13 – 23
Jumpstart 4D
prompt you to confirm this selection. If you made a mistake, you can
recover the original files by doing the reverse transport operation.
Make a copy first
By default, the option Make a copy first is selected. If Make a copy
first is selected, 4D Transporter creates a folder named YourApp-
Name.PC if you transport files from Mac OS to Windows, or YourApp-
Name.Mac if you transport files from PC to Mac OS. It then copies the
split or merged files into this folder.
If you drag and drop multiple files, the folder is created at the same level as
the first file. If a folder with the same name already exists, 4D Transporter
creates a folder named YourAppName.2 or YourAppName.2 and so on.
Tip
If you drag and drop your structure on to 4D Transporter, store your
transport options, and then hide the 4D Transporter window, you can
automate the transporting process.
If you transport databases in both directions or use different options often,
make several copies of 4D Transporter and configure each copy the appro-
priate way.
Move
Clicking the move button presents a standard Mac OS file open dialog
from which you can choose the database to be transported:
4D Utilities 13 – 25
Jumpstart 4D
13 – 26 4D Utilities
Jumpstart 4D
Chapter 14 – Plug-ins
Plug-ins 14 – 1
Jumpstart 4D
Windows
+ Inside a directory named Win4DX in the same directory as your
database application structure file. Plug-ins located here are only
available to the 4D application whose directory the Win4DX direc-
tory resides in. Therefore different database applications can have
different combinations of plug-ins.
+ Inside the universal 4DX folder:
- C:\Windows\4D\Win4DX
Universal 4DX Folder
Plug-ins in the universal folder are available to all 4D applications running
on that computer. You can also place any combination of plug-ins in both
folders. For example you might place 4D Internet Commands in the uni-
versal folder and 4D Write in a specific application’s folders.
Selecting 4D Plug-in Commands
When a plug-in has been installed, the new commands are added at the
bottom of the Command pane of the method editor (after your project
methods). The commands are grouped into themes within a plug-in.
(Clicking on any theme displays the list of commands for that theme.)
Plug-in themes and commands are prefixed with a plug-in specific prefix
such as CT for 4D Chart.
Figure 14-1: Command Pane Showing 4D Chart Themes
required but helps to show you that this variable (plug-in area) belongs to
4D Chart rather than say 4D Draw.
Figure 14-2: A Typical Plug-in Area
As the message points out: if you had created a picture field named
chart_Account_ in the table [Account] then the contents of this plug-in
area would automatically be saved in that field when the record was saved.
(Notice the underscore character appended to the variable/plug-in area
name – this links the field to the plug-in area.) 4D can also store the con-
tents of a plug-in area within a BLOB field. This is now the preferred
approach.
If you make your plug-in area (4D Chart/4D Draw) too small, it
may not display the contents correctly, or even display them at all.
You can adjust the size of the area by trial and error if your plug-in
area needs to be very small. One workaround is to create the con-
tents in an off-screen area, and place the results in a picture variable,
and then display the picture variable (suitably scaled) on your form.
Plug-ins 14 – 3
Jumpstart 4D
This will display the 4D Chart Wizard and set the default data table to
the [Contact] table. (The user can change the table to use from the table
drop-down menu.)
Creating a simple chart from data in the database is straightforward but
the use of many of the commands is a little more difficult. For example
changing the text size of labels is difficult to follow from the documenta-
tion. There are however many useful technical tips and technical notes on
using 4D Chart available from http://www.4D.com.
Another useful feature of 4D Charts is that they can be printed.
14 – 4 Plug-ins
Jumpstart 4D
4D Write
4D Write v6.7 provides you with sophisticated word processing and docu-
ment management functionality within your 4D applications. For exam-
ple, you can attach word processing documents to any record in your
database. 4D Write documents can also use data from 4D records. You can
write reports and letters that automatically extract information from your
database and merge it with text.
You can also use 4D Write v6.7 as a separate application by using it in an
external window. Your work within this window can be independent of
your database or use data extracted from records in your database.
Support for standard word processing functions
+ Color, user-definable margins, text alignment, line spacing, and
tabs.
+ Paragraph and character styles and style sheets.
+ Multiple column documents.
+ Find and replace characters and formats.
Support for advanced functions
+ Powerful Hypertext Links to URLs, other 4D Write documents, and
4D Methods.
+ Multiple documents open simultaneously.
+ Place and scale pictures.
Plug-ins 14 – 5
Jumpstart 4D
14 – 6 Plug-ins
Jumpstart 4D
4D Calc
4D Calc provides spreadsheet type capabilities within a database. Spread-
sheet cells can be populated with data from the database or by user data
entry. Users can create complex formulae (just like any other spreadsheet)
and the results can be pulled back into the database.
A good example of a use of 4D Calc would be in sales proposal environ-
ment. Spreadsheets could be automatically created that contained all the
relevant price data for products and services, the user could add formulae
for different quantities ordered, the spreadsheet could be printed for the
customer, and then stored in the database for future reference.
PowerView
PowerView is a plug-in that provides three capabilities:
+ It provides complete emulation of a discontinued (but widely used)
third party plug-in called AreaList Pro. (This created and managed
lists as a replacement for subforms.)
+ It provides complete emulation of 4D Calc (which it will replace).
+ It provides spreadsheet and list type management that is a cross
between AreaList Pro and 4D Calc.
PowerView is due for release in 2001. (If you are a partner, you can down-
load a developer preview.)
4D Draw
With 4D Draw, you can create network diagrams, floor plans, technical
illustrations, engineering documents, architectural blueprints. 4D Draw
documents can use data from 4D records. You can create drawings that are
based on record data and update themselves as the data changes.
You can also create hybrid solutions that allow drawings to act as user
interfaces. 4D Chart can also be used to chart data. One of 4D, Inc’s.
technical notes even demonstrates how to use it to trace bitmapped images
to create a vector-based overlay.
You can also use 4D Draw as a separate application by using it in an exter-
nal window. Your work within this window can be independent of your
database or can use data extracted from records.
Plug-ins 14 – 7
Jumpstart 4D
14 – 8 Plug-ins
Jumpstart 4D
raw TCP packets. The TCP set of commands provides developers with the
essential tools to build and control their own internet communications.
There are a number of sample databases on the 4D, Inc. Web site that
demonstrate how to build an e-mail or ftp client using 4D and 4D Inter-
net Commands.
4D ODBC
The 4D ODBC Connectivity plug-ins allow 4D to communicate with
any data source accessible by an ODBC driver, enabling you to handle the
data and structure of a SQL data source. 4D ODBC can provide access to
nearly all SQL and ODBC applications on the market. You can build any-
thing from simple queries to transaction-based client/server applications.
The main features are:
+ Access to most of the functionality of ODBC 2.0. (Core Level, Level
1, and Level 2).
+ Pass through mode support.
+ Programmable manipulation of the data source data and structure
files.
+ Cloning of 4D tables as ODBC tables and vice-versa.
+ Data exchange by value or by address.
+ Use of native types with automatic cross-conversion.
+ Ability to test available driver functions.
+ Support for Binary Large Objects (BLOBs).
+ Debugging window for tracing the communication between 4D and
4D ODBC.
4D for Oracle
The 4D for ORACLE Connectivity plug-in allows 4D to communicate
with an ORACLE Server. 4D for Oracle allows access to the data and the
structure of an ORACLE database from the 4D engine. The main features
are:
+ Direct access to the Oracle Call Interface.
+ PL SQL mode support.
+ Programmatically manipulate the data source data and structure
tables.
+ Cloning of 4D tables as ORACLE tables and vice-versa.
+ Data exchange by value or by address.
Plug-ins 14 – 9
Jumpstart 4D
14 – 10 Plug-ins
Jumpstart 4D
14 – 12 Plug-ins
Jumpstart 4D
Plug-ins 14 – 13
Jumpstart 4D
The Appearance Editor button opens a dialog box whereby you can edit
the preferences of HTML tables created by 4D Web Assistant.
Figure 14-7: Appearance Editor
4D Web Assistant is not designed for complex Web interfaces, but allows
you to quickly and easily publish 4D data to the Web. It also lets you pass
on this ability to your end users (if you choose to do so).
14 – 14 Plug-ins
Jumpstart 4D
This name conveys nothing. (Ideally the table name should give some
indication of what the loop is processing.)
Name the variable (in this case the loop counter) something more mean-
ingful (adding at least 1 second to your coding time) such as:
For ($Invoices;1;Records in selection([Invoice]))
Client
Customer
Invoice
Invoice_Item
Project
Project_Task
Project_Module
Fields
Fields should follow similar naming rules to tables. When using the
Explorer or selecting field names in the Form Editor they are listed in
alphabetical order. This can be used to group fields together, either by
module or data type:
Date_of_Invoice
Date_Shipped
Date_Received
Date_Paid
or
Invoice_Printed
Invoice_Date
Invoice_Total_Amount
Type Prefixes
Try and use local variables (prefixed with $) wherever possible since their
scope is limited to the method in which they are used. Remember that $0,
$1, $2 etc. are reserved for use as parameters.
The values of local variables cannot be displayed on forms, but can be
used with commands such as ALERT.
Variables
Alpha str_ or str002 to str255_
Boolean bln_
Integer int_
LongInteger long_
Text txt_ or text_
Date date_
Time time_
Developer Standards and Improving Your Code 15 – 5
Jumpstart 4D
Real real_
Picture pict_
BLOB blob_
Variables should not be prefixed with v for variable (an early convention).
Arrays
Alpha astr_ or astr002 to astr255_
(etc.)
Boolean abln_
Integer aint_
LongInteger along_
Text atxt_ or atext_
Date adate_
Real areal_
Picture apict_
There is no array of type Time. You would use a Longint array instead.
(Add 0 to a time to convert it to a longint.) However you may wish to use
the prefix time to indicate its use:
Time atime_
Form Objects
Button btn_
Radio Button rbtn_
Invisible Button ibtn_
Highlight Button hbtn_
Combobox cmbx_
Drop-down Menu ddm_ or drop_
Checkbox ckbx_
Tab tab_
Radio Picture rpic_
Chart chrt_
Dial dial_
Ruler rule_
Static text area stx_
Enterable text area etx_
Hierarchical list hrl_
Hierarchical Menu hrm_
Choice List clst_
Form objects can be referred to using the syntax (with wildcards):
This would set all enterable text areas to TRUE. By naming form objects
with consistent prefixes it is much easier to manage their properties such
as ENTERABLE, VISIBLE , etc.
Forms
Forms should be created in the table to which they logically belong, wher-
ever possible. For general purpose dialogs, you can create a dummy table,
or use a preferences table, to store the forms. They should be prefixed with
a module abbreviation where possible (e.g. INV) and suffixed with a three
character string indicating their use. This is because form parts behave dif-
ferently depending on how the form is displayed:
_dtl – used as detail form.
_dlg – called from a dialog.
_lst – used as a list form.
_sub – used as a subform.
_frm or _prt– printed using PRINT FORM (rather than PRINT SELECTION
or PRINT RECORD).
Methods
Methods could be prefixed with an appropriate 3-4 character string prefix
indicating their module. For instance CUST for methods relating to the
management of customer records, “INV” for invoicing and so on.
Project method names can be up to 31 characters long in 4D: this is often
enough for most purposes. In earlier versions of 4D, method names were
limited to 15 characters and frequently had to be abbreviated. This can
still be useful.
One convention for reducing the length of object names is called the
Hungarian method (named for Hungarian Charles Simonyi of Microsoft
who formalized this technique which had been in use for many years). To
create a shorter name you eliminate all non-leading vowels, double letters
etc. A variable named AR_Invoice_Delete becomes ARInvcDlt. This is
still quite readable. Another technique is to create a list of abbreviations
for common words: Print becomes prt for example, Delete becomes dlt
etc. These are then substituted for the longer words in your project
method names.
Comments
Comments can be used to explain your actions in three ways:
+ By adding blocks of comments, such as at the beginning of methods
to explain your overall logic and assumptions.
+ By adding comments to the end of a line of code to explain the pur-
pose of a specific line of code.
+ By adding comments as general documentation to just about any
database object using 4D Insider. (These comments are not viewable
from within 4D.)
Sample Header Block
`<< Project Method: Insert the name of your method here
`<< Called By: Name of method that calls this method
`<< Calls: Any further methods that this method calls
`<< Created: MM/DD/YY Your Name, Your Company
email@domain.com
`<< Modified: MM/DD/YY (date/time last modified)
`<< Purpose: Brief description of the purpose of this method
`<< Assumptions: Records loaded/in transaction?
`<<<<< Parameters >>>>>
` $1 = Pointer to table
` $2 = Text string (optional)
` $0 = Text string: Calculated window title
`<<<<< Declarations >>>>>
C_Pointer ($1)
C_Text ($2)
`<<<<< Constants >>>>>
$CR:=Char(Carriage return)
`<<<<< States >>>>>
MESSAGES OFF
Inline comments
[Table]Field:=(Int($Invoice*100))/100 `Reduces number to two
decimal places/loses remainder
An inline comment explains your logic without having to read and under-
stand the code. It may also document what you intended to do rather than
15 – 8 Developer Standards and Improving Your Code
Jumpstart 4D
what you actually coded. Comments are limited to 80 characters per com-
ment.
A parting thought on comments
It’s a good idea to assume that you may get hit by a truck tomorrow, or
even later today! It is best to start documenting early in the project (don’t
wait until the project is finished, it may be too late by then), and docu-
ment thoroughly. You never know when somebody else may have to take
over your project. Besides being hit by that truck you may choose to leave
the project.
Standardizing Your Coding
4D has database, table, form, object and project methods. In some cases,
code to execute a specific task could be placed in several different places,
and work equally as well. Consider the example of setting the window title
of a dialog.
You could set it in the project method that opens the window and calls the
DIALOG command. (You would call the command SET WINDOW
TITLE between the Open window and DIALOG commands. If however
the form is called from multiple project methods, you will need to insert
the code in each project method. If you decide to change the way you are
naming the window you will need to remember to update all the project
methods involved.
The next improvement would be to make the code that names the win-
dow into a project method. This could then be called from as many
project methods as required. This is advantageous because if you decide to
change, or improve, the way you are naming your tables, you only need
change the code in the project method that is being called.
The best way to handle this is to call your new project method from the
form method for that form. (This example is for a list form.)
Case of
: (Form event=On Load)
WND_Title (->[Client];"Clients")
End case
You pass this function two parameters: the first is a pointer to the table,
the second is the text you would like to use. This function could be
improved by using Current form table to determine the table, eliminat-
ing the need to pass the table pointer. Now, wherever this form is called
from the window title, it will always be created correctly. If you need to
modify the way the title is created, you only need to change the code in
the form’s form method and perhaps in the single project method.
Once you have found the method that suits you best, you should ensure
that all your forms use this technique, and that it is documented so that
other programmers know how you are doing this. Otherwise they may
spend hours hunting for where the title is created)
Using techniques like these has several advantages:
+ The amount of code is reduced, resulting in smaller structures, faster
compiles and so on.
+ If you need to change the way your title is created, there are fewer
places to change it, reducing maintenance time.
+ The user sees a consistent interface. Windows will always be named
by one set of rules.
+ You are less likely to create errors in the code.
+ Debugging time is reduced.
It is not always easy to understand the subtle differences between how dif-
ferent 4D objects behave. It’s important to thoroughly read the documen-
tation (lots of subtleties are explained in the manuals, but are missed by
skimming through the manuals). It is also a good idea to download the
sample databases from 4D, Inc. Seeing how different programmers
approach problems can be very instructive.
After you have created a 4D database you may wish to provide it to others
(legally that is). You may have friends or family that wish to use it, or per-
haps you have created the database with the intention of selling it. There
are several different ways to deploy a 4D database, for single-user database
applications these are:
+ 4D Runtime
+ 4D Runtime Classic
+ 4D Engine
4D Runtime
This is the cheapest way to deploy a 4D application – it is free for each
platform you purchased. When you purchase 4D for either Mac OS or
Windows you will find the installer for the 4D Runtime on the CD.
You can distribute 4D Runtime to any of your users free of charge – but
only for the platforms you have purchased. Therefore to distribute both
the Mac OS and Windows version of 4D Runtime you must have pur-
chased 4D for both platforms.
4D Runtime will not run compiled 4D applications. Nor can you use it
to create or edit databases.
4D Runtime will be installed as a separate application on your user’s hard
drive. Your application will be in separate files. If your user has different
versions of 4D installed he or she may run into problems if they open your
database with the incorrect version of 4D.
4D Runtime Classic
Occasionally you may need to deploy a copy of your database as a com-
piled, double-clickable application. This offers some distinct advantages
over 4D runtime:
+ Compiled applications cannot be edited. This offers both security
for you and protection for your client.
+ Compiled applications usually run significantly faster than inter-
preted applications.
Deploying Your 4D Database 16 – 1
Jumpstart 4D
with the engine of your choice (and especially before burning thousands
of CD’s).
Splash screen
You can change the contents of the 4D splash screen by editing the PICT
resource # 5002 in a 4D application using a resource editor such as
ResEdit or Resorcerer. This eliminates manually changing it for every
menu bar.
Installers
There is a potential problem if you have a 4D application on a Windows
CD and let users copy it onto their systems. Windows applications resi-
dent on a CD take on the CD properties of read-only – you can run the
application and it appears to be working but data is not saved. There are
no user warning messages. You can avoid this problem by embedding the
4D application in a zip file or by using an installer creation package.
If you are building a cross-platform installer, it will need to be tested on
both platforms. Check that all components, including subfolders such as
the Mac4DX/WIN4DX folder are created in the correct locations, and
that the names are correct.
4D, Inc. will be releasing an installer in 2001 that is based on 4D itself.
Since it was written in 4D it will be inherently cross-platform.
Deploying Web-Based Applications
If you are going to deploy, or use, an application that has Web functional-
ity (such as a Web server) but is based on a single user product (such as 4th
Dimension, not 4D Server) you will probably need to purchase a Web
extension license from 4D, Inc. You should contact customer service to
establish your requirements and costs.
Deploying 4D Server-Based Applications
There are no engine or runtime type products for 4D Server but there is a
product called 4D Server Application. This can run compiled databases
only and is cheaper than 4D Server Standard Edition.
If you anticipate selling a lot of copies of a server based product you
should contact OEM sales at OemSales@4d.com.
Chapter 17 – 4D Resources
4D’s maturity means that there are many online resources available:
+ The 4D, Inc. Web site
+ Various independent Web resources
+ Mailing lists
+ Books and magazines
+ User Groups
Most of the resources are online, with a limited selection of books avail-
able.
4D, Inc. (USA)
One of the best places for 4D programmers to start is the 4D, Inc. Web
site in the USA. This had a major overhaul with the release of 4D v6.5,
and is currently undergoing another revision. There are a wide range of
resources here for the beginner, vertical market developer, academic user,
Web developer, and more.
+ Product downloads (from the products page you can download the
latest versions of 4D v6.5 and 4D v6.7 products).
+ Tutorials and sample databases from beginner to expert.
+ Technical Notes. (Technical notes older than six months are avail-
able to all users: notes less than six months old are restricted to part-
ners.)
+ Demonstration versions of 4D.
+ PDF Documentation for all products.
+ Developer referrals.
+ Product searches.
+ Links to user groups around the US.
The starting URL for the 4D Web site is:
http://www.4d.com.
Mailing Lists
There are two major independent mailing lists for 4D in English. These
lists are neither run nor moderated by 4D, Inc. and are uncensored
4D Resources 17 – 1
Jumpstart 4D
Jumpstart 4D list
This list is aimed at beginners or programmers new to 4D. More details
can be found at the Jumpstart Web site:
www.jumpstart-4d.com
Eastern Europe
4D ExYu mailing list maintained by Milan Adamov (covers all Slavic lan-
guages spoken in the former Yugoslavia - Serbian, Croatian, Bosnian
[those three came from Serbo-Croatian], Slovenian and Macedonian):
List-Subscribe <mailto:listserver@4d.co.yu?body=SUBSCRIBE%204DExYu>
List-Unsubscribe <mailto:listserver@4d.co.yu?body=UNSUB-
SCRIBE%204DExYu>
List-Digest <mailto:listserver@4d.co.yu?body=SUB-
SCRIBE%20DIGEST%204DExYu>
List-Help <mailto:listserver@4d.co.yu?body=HELP>
Web Resources
Here are a few Web based resources for 4D developers.
4D Mentor
This is the home Web site of Walt Nelson, a long time 4D developer and
ex-ACI employee. Walt offers a number of his previous technical notes for
download, and also offers a number of his books for free electronic down-
load.
http://www.4dmentor.com
17 – 2 4D Resources
Jumpstart 4D
Monkeywerks
Monkeywerks is an archive of all 4D NUG messages (over 130,000) that
is hosted by Pacific Data Management Inc., of San Jose, California Com-
pany founder and owner John Beaulieu is an ex-ACI Inc. employee and
also hosts the 4D mailing lists (the list is administered by Karen Sabog).
http://www.pdm-inc.com/mky.htm
Inner Dimension
Plug-in directory of nearly all 4D plug-ins ever written (current and past).
http://www.inner-dimension.com/Pages/BluePage.html
Dimensions Magazine
http://www.dimensionsmag.com/
Mac OS X -4D
This Web site provides information on running 4D on Mac OS X, and
also provides links to Mac OS X resources.
http://www.macosx-4D.com/
4D Resources 17 – 3
Jumpstart 4D
Books on 4D
Inside 4D v6 (Out-of-print)
This is a beginners book by Steve Hussey and Geoff Perlman that includes
a CD-ROM with sample databases. The book is now out of print (it only
covers 4D v6.0) but a PDF version of book still available on request.
Email Steve Hussey, the author, at shush@harborside.com.
Jumpstart 4D v6.7
You can read about updates and the latest news at the Web site:
http://www.jumpstart-4d.com
4D v6.5 Companion
Also by David Adams, it also includes a CD with sample code. Available
from Automated Solutions Group at http://www.asgsoft.com
The 4D Web Companion
The newest book by David Adams, The 4D Web Companion covers 4D’s
Web technology. This book is for all levels of 4D Web developers, and can
be ordered through the 4D, Inc. Web site.
User Groups
There are many active user groups around the country – there are links
from the 4D, Inc. Web site:
http://www.4d.com/community/usergroups.html
17 – 4 4D Resources
Jumpstart 4D
Cross-Platform Issues 18 – 1
Jumpstart 4D
+ How file paths are specified (Mac OS uses : as the delimiter while
Windows uses \.)
+ Font handling and font names.
+ Use of high ASCII characters (those above ASCII 127).
+ Screen resolutions and dpi (Mac OS 72 dpi, Windows 96 dpi).
+ Keyboard shortcuts (Command key versus Control key and Option
key versus Alt key).
+ Graphic User Interface (GUI) components such as button appear-
ance and behavior.
+ Lack of Resources on Windows – the Mac OS also allows resources
such as graphics, text, or sound to be installed into external resource
files.
+ OS technology differences – AppleEvents do not execute under
Windows and DDE does not work on Mac OS.
+ Installed technologies – QuickTime is almost certain to be installed
on a Mac OS system and is less likely to be installed on Windows
(although QuickTime for Windows is available).
+ Different graphic file formats such as PICT (Mac OS) and BMP
(Windows).
It can be time-consuming to build a single application that is fully cross-
platform both in functionality and appearance, but you may increase your
potential market share if you do.
Compatibility between Windows and Mac OS Versions of 4D
The following is a non-exhaustive list of compatibility features:
+ A database created or modified on Mac OS or Windows can be
opened on either platform with no changes.
+ All the tools such as the method editor, forms editor, choice lists,
menu editor, passwords, and so on, work exactly the same way on
both platforms, although their appearance differs slightly due to cos-
metic difference in the display of windows, close boxes, scroll bars
and so on.
+ The Form Editor includes a mapping mechanism for an optimal
match between Mac OS and Windows fonts.
+ An internal byte-swapping and ASCII code-filtering mechanism
handles diacritical characters, such as à, é, ñ, ø, and so on. This is
transparent to the developer and the user.
18 – 2 Cross-Platform Issues
Jumpstart 4D
+ Picture fields, variables, and pictures copied into forms are handled
transparently by the program; you can, for instance, copy and paste
a .BMP file on a Windows machine and reuse it as a PICT file on
Mac OS, and vice versa.
+ 4D Server, running on Mac OS or Windows, will simultaneously
serve Mac OS and Windows clients. This includes the automatic
smart-downloading of methods, forms, and 4D plug-ins to 4D Cli-
ents running on either platform.
+ A database property will allow you to designate whether or not con-
trols such as buttons and choice lists should look the same on both
platforms, or whether they should have the look and feel of the plat-
form of the workstation. (Mac OS style buttons on a Mac, Win-
dows-style buttons on Windows.) After you set the Customizer
option, 4D Server will handle this transparently.
Differences Between the Mac OS and Windows Versions of 4D
There will be some small differences related to the operating system. On
Windows, for instance, you can edit Balloon Help but cannot show it.
On Windows, you can maximize and minimize windows; on Mac OS you
cannot.
Differences at the language level
Everything you do on Mac OS will work the same way on Windows
(unless the OS does not permit it). For instance a SAVE RECORD com-
mand saves a record exactly the same way on both Mac OS and Windows.
Depending on the command, the operating system may require some
small differences. For instance, after a call to Open document on Mac
OS, the Document system variable will contain the path to the docu-
ment selected, such as “Disk:Folder:Doc”; after the same call on a Win-
dows workstation, the Document variable will contain a path such as
“C:\Folder\Doc.txt”.
Check your applications for any instances where you have hard-coded
document pathnames; it may be a good idea to create code that checks the
Platform variable and branches your code according to the type of com-
puter in use.
Compiler Generation of Platform-Independent Databases
4D Compiler will generate Fat Binary databases for 68K, PPC, and Intel.
Cross-Platform Issues 18 – 3
Jumpstart 4D
From the File ¬ Database Properties… menu item you can select the
target platform interface. Your options are:
+ Automatic – changes the interface to suit the platform: i.e. executed
on a computer running Windows 95/98 it will use the Windows 95/
98 look and feel.
+ Mac OS 7.
18 – 4 Cross-Platform Issues
Jumpstart 4D
+ Windows NT 3.5.1.
+ Windows 95/98.
+ Platinum.
+ Mac Theme
You can try different interfaces to see their appearance on screen.
Forms
When creating or editing a form, you can define the form’s look and feel
by using the Form Properties dialog available from the Form menu:
Figure 18-2: Setting the Form Properties
Using the Platform Interface drop-down menu, you can select the
desired look and feel. Inherit from database or Automatic are the
best choices for cross-platform use. You can also override each form’s
appearance on a case-by-case basis.
Objects
Double-clicking each object allows you to change its look and feel. Inher-
ited from Form is set by default. It is best left at that setting:
Cross-Platform Issues 18 – 5
Jumpstart 4D
Note the Mac OS shortcuts defined in the menu editor: Command N for
example. On Windows this would appear as Control N. 4D handles the
mapping of Mac OS shortcuts to Windows automatically.
It should be noted though that some menu items are expected to have a
different name under Windows – Mac OS users, for example expect to
Quit a program. Windows users expect to Exit it. 4D does not handle
these issues automatically – you may need to create different menus for
Mac OS and Windows.
Forms and form objects
There are differences in appearance between various objects on Mac OS,
Windows NT, and Windows 95/98. Buttons for example look different–
and Windows has the concept of “focus”. In Windows, users frequently
18 – 6 Cross-Platform Issues
Jumpstart 4D
tab to buttons and other objects and the dotted line indicates which object
has focus – that is, it is ready to receive the next action. 4D handles this
automatically.
Keyboard shortcuts
The following modifier key equivalents exist for Windows and Mac:
Table 18-1: Mac OS and Windows Modifier Key Equivalents
Mac OS Windows
Cross-Platform Issues 18 – 7
Jumpstart 4D
Style Sheets
Figure 18-5: Object with Style Sheet
You can create Style Sheets for use by objects that display text (text labels,
button labels, etc.). Style sheets can be created and edited from either the
Database Properties dialog, or using the Object Properties text tab (or
the Properties Palette if you prefer).
A style sheet defines which fonts are used on which platform.
Figure 18-6: Creating a Style Sheet
+ Two fonts of the same size will usually appear at different sizes on
Mac OS and Windows.
Until recently most Mac OS systems used 72 dpi as the display resolution,
while most Windows systems used 96 dpi. This means that a 12 point
font on Mac OS appears to be approximately at 10 points on Windows.
This scaling may make the font too small to be read.
Using the style sheet editor, you can map the fonts that are used on one
platform to another font of a different size and style on the other platform.
Editing or creating a style sheet from the forms editor
Figure 18-7: Font Attributes Tab in Object Properties
Double-click any object that can have style sheets attached (any object
that displays text).
Clicking the Edit button next to the Style Sheet drop-down menu
allows you to create and edit the style sheets.
Cross-Platform Issues 18 – 9
Jumpstart 4D
Here you can create a new style sheet “Field Label” by clicking the New
button. Then from the platform menu select the OS of choice and define
the fonts you wish to use for that platform. In this case for Mac OS you
can use Helvetica 9 point. Styles can be applied as desired. You repeat the
process for each OS in turn. So in this example you have selected Helvet-
ica 9 for Mac OS and MS Sans Serif for both Windows platforms.
You need to be aware that different fonts, especially on different plat-
forms, have different character widths and kerning or letter spacing.
When creating these field labels you need to ensure that there is sufficient
space for the label to appear, whichever platform it is on.
18 – 10 Cross-Platform Issues
Jumpstart 4D
Here the “Size” label does not have space to grow if required but the
“Description” label does. Here they are also positioned well to the left of
the fields.
It is a good idea to use fonts that are commonly installed in respect to each
platform. (There are commands to list what fonts are installed on a system
that is hosting 4D/4D Client. You could use these commands to check
that the necessary fonts are installed.)
Useful Cross-Platform Commands and Functions
PLATFORM PROPERTIES (platform{; system; machine})
The PLATFORM PROPERTIES command returns information about
the type of platform you are running, the version of the operating system,
and the processor installed on your machine.
PLATFORM PROPERTIES returns environment information in the
parameters platform, system, and machine.
platform indicates whether you are running a 68K or PowerPC-based
Macintosh, or a Windows version of 4D. This parameter returns one the
following predefined constants:
Table 18-2: Platform Properties
You can also use constants for these values. For example Windows for the
value 3 (see the later code example).
The information returned in system and machine depends on the ver-
sion of 4D you are running.
This is probably the most important command for use within a 4D cross-
platform application. This enables you to determine the platform on
which you are executing. Code to determine this is best located in your
startup method: Create a method called Startup and call it from the
Database Methods On Startup.
Cross-Platform Issues 18 – 11
Jumpstart 4D
18 – 12 Cross-Platform Issues
Jumpstart 4D
Again this code would normally be called from the Startup database
method.
MAP FILE TYPES (MacOS; Windows; Context)
You use this command to make your calls to System Documents plat-
form-independent.
MAP FILE TYPES allows you to associate a Windows file extension with
a Mac OS file type.
You only need to call this routine once to establish a mapping for a whole
working session with a database. This code is best executed therefore in
the On startup database method. You call this command for each file
type that you need to map.
Once the call has been made, all the System Documents commands, such
as Open document, when running on Windows, will automatically sub-
stitute the Windows file extension for the Mac OS file type you actually
pass as parameter to the routine.
In the parameter MacOS you pass a 4-character Mac OS file type. If you
do not pass a 4-character string, the command does nothing and generates
an error.
In the parameter Windows you pass a 1 to 3 character Windows file
extension (e.g. DOC). If you do not pass a one to three character string,
the command does nothing and generates an error.
Cross-Platform Issues 18 – 13
Jumpstart 4D
In the parameter Context you pass the string that will be displayed in the
List Files of Types drop-down list of the Windows open file dialog box.
The context string is limited to 32 characters and additional characters are
ignored.
Once you have mapped a Windows file extension to a Mac OS file type,
you cannot delete this mapping or change its settings. While developing
and debugging a 4D application, reopening the database allows you to
restart with a fresh mapping configuration.
4D Windows File Locations
Table 18-3: 4D Folder Contents on Windows
File Notes
File Notes
18 – 14 Cross-Platform Issues
Jumpstart 4D
Mac OS Windows
File
File Type File Extensions
Cross-Platform Issues 18 – 15
Jumpstart 4D
18 – 16 Cross-Platform Issues
Jumpstart 4D
Index
Symbols
#D 4 – 15
#H 4 – 15
& 9 – 11
.4DB 13 – 20, 13 – 21, 13 – 25
.4DC 13 – 25
.4DD 13 – 21
.4DR 13 – 21
.err 10 – 12
.RES 11 – 6, 11 – 7, 13 – 8, 13 – 17
.REX 11 – 6
.REX files 11 – 7
.RSR 13 – 20, 13 – 21
@ 4 – 7, 5 – 13
Numerics
2GB 13 – 7
4D Chart 4 – 10, 14 – 1
4D Client 11 – 1
4D Compiler 12 – 16, 16 – 2
4D Engine 10 – 7, 16 – 1, 16 – 2
4D Explorer 3 – 38, 3 – 39
4D Insider 10 – 8
4D Networked User Group 17 – 2
4D Query Editor 5 – 4
4D Runtime 16 – 1
4D Runtime Classic 16 – 1, 16 – 2
4D Server 11 – 1
4D Server Standard Edition 16 – 3
4D theme 4 – 11
4D Tools 13 – 1
4D Web Assistant 3 – 8, 14 – 10, 14 – 12
79,1 3 – 35
A
Accept 3 – 42, 5 – 11, 5 – 12
Index 19 – 1
Jumpstart 4D
Accept button 3 – 42
Ad Hoc Reports 4 – 12
Add Expansion Serial Number 11 – 4
Add Formula 4 – 10
Add Item 3 – 41, 5 – 3
Add Line 4 – 6
ADD RECORD 3 – 42
Administrator 10 – 5, 13 – 1
ADSP 11 – 3, 11 – 5
Advanced… 3 – 28, 10 – 7
ALERT 12 – 5, 15 – 5
Alert dialog 9 – 12
alias 13 – 1
ALL RECORDS 3 – 40
All Tables 4 – 6
All tables 4 – 4
Allow 4D Open Connections 8 – 5
Alpha 3 – 4, 3 – 11
Alphanumeric 3 – 4
And 4 – 4
Appearance Editor 14 – 13
AppleEvents 14 – 1, 18 – 2
Apply 6 – 4
Apply Formula… 4 – 1, 4 – 11, 4 – 12, 4 – 18
Apply Once 4 – 18
APPLY TO SELECTION 4 – 12
ASCII 4 – 16, 10 – 12, 18 – 2
Auto assign related value in subform 7 – 7
Automatic Form Creation 3 – 16
Automatic Relations 9 – 19
Automatic Resizing 4 – 17
Automatic Width 4 – 14
Available Actions 3 – 25
Available Fields 3 – 18, 3 – 20, 4 – 4, 4 – 6, 4 – 10
B
Balloon Help 18 – 3
Basic… 10 – 7
Basic4D 14 – 1
Begins with 4 – 7
Binary Large Object 3 – 6
bitmaps 3 – 5
BLOB 3 – 6, 14 – 9, 14 – 10
BMP 18 – 2
19 – 2 Index
Jumpstart 4D
Boolean 3 – 5, 4 – 5
Border Line Style 7 – 9, 7 – 31
Browse… 6 – 7
Buttons tab 3 – 25, 3 – 29
C
calculations 3 – 4
Can’t Modify 7 – 22
Cancel 3 – 42, 5 – 12
Cancel button 3 – 42
Canned Reports 4 – 12
CAPS LOCK 13 – 2
Caps Lock 8 – 4
CASE 12 – 2
Case 5 – 17, 9 – 22
Case statement 6 – 10, 6 – 11
case-sensitive 3 – 42, 13 – 2
Char function 4 – 8
check 13 – 1
Check All 13 – 4
Check Indexes… 13 – 5
Check Records… 13 – 4
Check… 13 – 8
Choice List 4 – 5
Client/server 11 – 1
Clipboard 4 – 10
CNT_Find 5 – 4, 9 – 13
CNT_QR 5 – 4
CNT_Sort 5 – 4
command 3 – 40
Command pane 14 – 2
Command+Spacebar 3 – 16
Commands by Alphabetical Order 4 – 12
Commands by Theme 4 – 12
Compact 13 – 1
Compact… 13 – 5, 13 – 11
Comparison Area 4 – 5
Comparison Operators 4 – 7
Compiler 10 – 4
Compiler Declarations 10 – 2
Compiler Project 10 – 2
Compiling Options 10 – 5
compound query 4 – 5
concatenate 4 – 17, 9 – 3
Index 19 – 3
Jumpstart 4D
Conjunction Buttons 4 – 5
Constant size 13 – 13
Constant size (centered) 13 – 13
Coordinates 5 – 19
Create a Blank Database 3 – 8
Create and Replace 12 – 5
Create Database Folder 3 – 8
Create Multiple Pages 3 – 24
Create Table 6 – 6
Criteria Area 4 – 4
Current date 7 – 21
Current form table 9 – 9
Current Menu Bar 3 – 34
Current Menu Item 5 – 3
Current Selection 4 – 2, 4 – 4, 4 – 11, 4 – 18, 4 – 19
current selection 4 – 11
Current user 8 – 8
Custom Menus Environment 1 – 2, 3 – 16, 3 – 32, 3 – 33, 3 – 40, 3 – 44, 4 –
1, 4 – 12, 5 – 1, 7 – 12, 7 – 17, 7 – 19, 9 – 3, 9 – 4, 10 – 1
Customizer Plus 2 – 1, 13 – 1, 13 – 11, 13 – 14
D
damaged record 13 – 6
Data Control 7 – 14
Data Control tab 7 – 29
Data Segments 13 – 2
Database Methods 3 – 39, 9 – 1, 13 – 10
Database Properties 3 – 15, 4 – 1, 13 – 11, 13 – 16
DataWave 14 – 11
Date 3 – 5, 10 – 4
DDE 18 – 2
Default Value 7 – 14
Del Line 4 – 6
Delete Selection 3 – 30
Design Environment 1 – 2, 3 – 15, 3 – 33, 3 – 43, 4 – 1, 5 – 2, 5 – 3, 5 – 15,
6 – 2, 6 – 8, 7 – 4, 7 – 9, 7 – 18, 9 – 3, 10 – 1, 12 – 8, 13 – 11
Designer 8 – 3, 8 – 4, 10 – 5, 13 – 1
Developer referrals 17 – 1
DIALOG 5 – 17, 15 – 9
Disk File 4 – 16
Display Format 7 – 29
Display User List in Password Dialog Box 8 – 5
Done 3 – 30, 6 – 3
Duplicating resources locally… 11 – 6
19 – 4 Index
Jumpstart 4D
E
Edit
Clear 4 – 2, 5 – 2
Edit Documentation 12 – 8
Edit menu 3 – 32
Edit String… 7 – 14
Enter
Apply Formula… 4 – 11
Enter in List 3 – 32
Enter key 3 – 41
ENTERABLE 15 – 7
Enterable 5 – 10, 7 – 22, 7 – 30
Enterable property 5 – 9
Entry Order 6 – 2, 6 – 11
Errors 10 – 2
Events Tab 5 – 16
Except 4 – 4
EXECUTE 12 – 7
Explorer 3 – 17, 3 – 26, 7 – 11, 15 – 5
F
false 3 – 5
Fat16 13 – 21
FAT32 13 – 21
Field 3 – 1
Field Properties 7 – 22
Fields List 4 – 4, 4 – 5
File
Close Structure 10 – 15
Database Properties 8 – 4
Database Properties… 11 – 3, 18 – 4
Headers & Footers… 4 – 14
Import Data… 6 – 5
menu 4 – 14
Open Database… 13 – 1
Open… 4 – 16, 13 – 11
Page Setup… 9 – 18
Print… 4 – 16
Save as… 4 – 15, 10 – 15
FLUSH BUFFERS 13 – 16
Font 4 – 17, 5 – 19
Form
Index 19 – 5
Jumpstart 4D
Display 5 – 18
Display ¬ Markers 7 – 9, 7 – 30
Display ¬ Object Properties 5 – 8
Display ¬ Properties List 5 – 8
Entry Order 6 – 11
Form Method… 7 – 20
Form Properties… 5 – 16
Properties… 5 – 17
Form Editor 3 – 16, 3 – 26, 7 – 8, 7 – 9, 7 – 10, 7 – 11, 7 – 12, 7 – 13, 7 – 27,
9 – 18, 15 – 5
Form Events 5 – 16
Form Method 3 – 39, 5 – 15, 7 – 19, 7 – 20
Form Methods & Triggers 5 – 15, 7 – 4
Form Properties 5 – 17, 7 – 20, 9 – 16
Form title 3 – 24
Form Type 3 – 28
Form Wizard 3 – 1, 3 – 16, 3 – 20, 5 – 17
format 3 – 5
Forms 3 – 17
Formula Editor 4 – 7, 4 – 10, 4 – 11
Full screen with title 13 – 13
Full screen without title 13 – 13
functions 3 – 40
G
Generate a log file 13 – 8
Get text from clipboard 3 – 40
Graph 4 – 16
Graphical User Interface 3 – 21
Group Selection 12 – 5
Group With Dependencies 12 – 6
Grow Horizontally 7 – 17
Grow Vertically 7 – 17
H
HIDE TOOLBAR 4 – 2
Horizontal Distribution 5 – 19
I
I 3 – 27
If...End 6 – 11
import 5 – 1
19 – 6 Index
Jumpstart 4D
Import Editor 6 – 1, 6 – 6
Import Table 6 – 6
Import Wizard 6 – 1
Indexed 3 – 13, 3 – 19, 6 – 4, 13 – 6
Initialize Local Variables 10 – 9
Input Form 3 – 27, 3 – 31
Insert Line 4 – 6
Integer 3 – 4, 3 – 5
interpreted 10 – 1
Interprocess 5 – 10
interprocess variable 9 – 4
Intersection 9 – 14
IPX/SPX 11 – 3
is equal to 4 – 7
J
Journal File 13 – 4, 13 – 5
justification 4 – 17
K
Keep last position 13 – 13
key field 7 – 2
Keys… 5 – 11
Keywords pane 3 – 37
L
Label Height 4 – 17
Label Size 4 – 17
Label Wizard 4 – 1, 4 – 16, 4 – 18
Last Check 13 – 3
Layout page 4 – 18
Layout Tab 4 – 17
Line 5 – 3
List Form 3 – 28
List of Fields 4 – 17
List of Menu Bars 3 – 34
List of tables 6 – 5
LOAD RECORD 11 – 8
LockedSet 11 – 8
Longint 3 – 4, 3 – 5
Looking for Lost Methods 13 – 9
lost methods 13 – 10
Index 19 – 7
Jumpstart 4D
M
Mac OS creator code 13 – 23
Master table 4 – 4
Maximum number of ticks per call to OS 13 – 19
Menu Bar 3 – 34, 5 – 2
Menu Bar Editor 3 – 33
Menu Editor 3 – 41, 3 – 43
Menu Items 3 – 35
Menus 5 – 1
Show Custom Menus 5 – 2
Method Name 5 – 5
Method to apply 4 – 18
Methods tab 7 – 4
Minimum number of ticks per call to OS 13 – 19
MODIFY SELECTION 5 – 4, 9 – 6
Modify… 4 – 10
modules 12 – 4
Monkeywerks 17 – 3
N
network components 11 – 5
New Form Wizard 3 – 18, 7 – 9
Next compiler error 10 – 14
Next Page 3 – 25
No Action 7 – 24
Normal 10 – 9
NTFS 13 – 21
number 3 – 4
Number of ticks between calls to OS 13 – 19
O
Object
Clear Object Method 7 – 30
Object Method 3 – 39, 6 – 1, 6 – 2, 6 – 8, 6 – 11, 7 – 26, 7 – 27, 7 – 30
Object Properties 5 – 9, 5 – 18, 5 – 19, 6 – 9, 6 – 10, 7 – 9, 7 – 14, 7 – 15, 7
– 18, 7 – 25, 7 – 30
ODBC 14 – 9
OK 5 – 4, 15 – 3
OK variable 3 – 42, 5 – 11, 5 – 12
On Clicked 9 – 16
On Data Change 6 – 9, 6 – 10, 7 – 27, 7 – 30
19 – 8 Index
Jumpstart 4D
ON ERR Call 15 – 3
On Load 5 – 16, 5 – 17, 6 – 9
On Startup 9 – 1, 9 – 2
On Startup Database Method 9 – 21
On web authentication 14 – 12
On web connection 14 – 12
One Field per Line 3 – 24
Open 6 – 6
Optimized 10 – 9
Option 13 – 23
Option+Shift+v 9 – 4
Options tab 3 – 29
Or 4 – 4
ORACLE 14 – 9
Order by... 4 – 1
Order By… 3 – 30, 4 – 9, 4 – 18
Order by… 3 – 30, 4 – 9, 4 – 10, 5 – 4
Output Form 3 – 27, 3 – 31
P
PAGE BREAK 9 – 20
Page Size 4 – 17
Pareto’s Rule 3 – 1
Pascal 3 – 40
Password Editor 8 – 2, 9 – 21
Password Groups
Creating 8 – 5
Passwords 8 – 1
Assigning 8 – 1
New group 8 – 6
New User 8 – 6
PICT 3 – 5, 18 – 2
Picture 3 – 5
PL SQL 14 – 9
Preview 3 – 39
preview pane 3 – 27
Preview Window 3 – 39
Previous Page 3 – 25
PRINT FORM 9 – 20
Print Preview 4 – 14
PRINT SELECTION 13 – 15
PRINT SETTINGS 9 – 18, 9 – 20
Print… 4 – 14
Printer 4 – 16
Index 19 – 9
Jumpstart 4D
Private 12 – 15
Process 5 – 10
Project Method 3 – 39, 4 – 8, 6 – 10, 8 – 3, 9 – 1, 13 – 10
Property List 5 – 9, 5 – 18, 5 – 19, 6 – 9, 7 – 9, 7 – 14, 7 – 15, 7 – 18
Protected 12 – 15
Public 12 – 15
Q
Queries 13 – 6
Queries Menu 4 – 3
QUERY 3 – 30, 5 – 4
Query by Example… 4 – 6, 4 – 7
Query in selection 4 – 5
Query… Editor 3 – 30, 4 – 4, 4 – 5, 4 – 6
Quick Report Editor 3 – 30, 4 – 1, 4 – 12, 4 – 15, 4 – 18, 5 – 4, 5 – 5
QuickTime 18 – 2
R
Raised 7 – 9
Range checking 10 – 6
READ ONLY 9 – 21, 11 – 7, 11 – 8
Real 3 – 4, 10 – 2
Real number 10 – 3
Record number/Record Count 3 – 24
Records in selection 9 – 8
Records in table 9 – 8
Recover 13 – 1
recover 13 – 1
Recover by tags 13 – 6
Recover… 13 – 7
RELATE MANY 9 – 19
Related Table 4 – 6
Related table 4 – 4
Relationship Properties 7 – 6, 7 – 7
repair 13 – 1
Repair All… 13 – 6
Repair Indexes… 13 – 6
Repair Records… 13 – 6
Repair… 13 – 10
Reparse 12 – 17
Repeat 3 – 42
Repeated Values 4 – 13, 4 – 14
Replace 6 – 7, 12 – 4, 12 – 5
19 – 10 Index
Jumpstart 4D
Replace 4D command... 12 – 4
REPORT 5 – 4
Report
Labels 4 – 16
Resizing Options 7 – 17
resource 3 – 35
Resources 18 – 2
4D Zine 17 – 3
Books on 4D 17 – 4
Dimensions Magazine 17 – 3
HPO Soft 17 – 3
Inner Dimension 17 – 3
Monkeywerks 17 – 3
User Groups 17 – 4
Resources (I) 13 – 10
Resources (II) 13 – 10
Return 5 – 5
S
Save button 4 – 6
scope 10 – 4
Script Manager 10 – 7
Selected Actions 3 – 25
Selected Fields 3 – 20
semaphore 11 – 8
Sequence number 7 – 21
SET ABOUT 10 – 12
Set Arithmetic 9 – 14
SET ENTERABLE 9 – 22
SET VISIBLE 9 – 22
Sets 9 – 14
Shortcut 3 – 35, 13 – 1
Show All 3 – 30
Show Preferences 13 – 23
Show Subset 3 – 30, 3 – 44
Show Toolbar 4 – 2
size 4 – 17
Sort… 13 – 5
Sorted 4 – 13
Splash Screen 5 – 1
splash screen 5 – 1
Split… 13 – 7
SQL 14 – 9
SQL 92 12 – 2
Index 19 – 11
Jumpstart 4D
Stack is full 13 – 15
stand-alone executable application 10 – 7
Standard Code 4 – 18
Startup Environment 4 – 2
Stop browsing error file 10 – 14
STR# 12 – 12
String 9 – 3
string and array handling 3 – 40
Structure Editor 13 – 18
style 4 – 17
Styles Tab 3 – 21
Subfields 3 – 4, 4 – 5
subform 7 – 8, 7 – 11
Subset 9 – 17
subtable 3 – 5, 4 – 5
Sum 7 – 28
Sunken 3 – 21
system variable 3 – 42
T
Tab 15 – 4
Table 3 – 1
Table Methods 3 – 39
Table Properties 6 – 3
Tables
Field Type Summary 3 – 6
First List of Fields 3 – 2
Revised Fields 3 – 3
Tables, forms, … 13 – 10
target width 3 – 29
TCP 11 – 5
TCP/IP 11 – 3
Technical Notes 17 – 1
Template used 3 – 28
Text 3 – 4
text field 3 – 4
Time 3 – 5, 15 – 6
tokenizes 3 – 41
Tool Palette 5 – 19, 7 – 13, 7 – 16, 7 – 25
Toolbar group area 4 – 2
Tools
Menu Bar Editor 5 – 2, 5 – 3
Passwords 8 – 2
Triggers 3 – 39
19 – 12 Index
Jumpstart 4D
true 3 – 5
Tutorials 17 – 1
U
Ungroup 12 – 6
Union 9 – 14
Until 3 – 42
Use Dynamic Field Names 3 – 24
Use menu 10 – 13
Use new memory allocation scheme (Macintosh only) 13 – 20
Used Space Thermometer 13 – 3
User 4 – 1
User Environment 3 – 10, 3 – 15, 3 – 32, 3 – 43, 4 – 1, 4 – 2, 4 – 3, 4 – 12, 4
– 18, 5 – 1, 6 – 5, 9 – 3, 9 – 7, 9 – 21, 10 – 1, 13 – 6
User in group 8 – 8
User list 13 – 2
User List in Alphabetical Order 8 – 5
Users 9 – 20
UserSet 11 – 8
V
Variable 9 – 1
Variable Name 5 – 9
vers 10 – 12
VISIBLE 15 – 7
W
Warnings 10 – 2
WEDD 13 – 13, 13 – 14
whole numbers 3 – 5
wildcard character 4 – 7
Z
Zero 10 – 10
Index 19 – 13
Jumpstart 4D
19 – 14 Index
“ Tanyhis4Dis abeginner,
must-read book for Steve Hussey takes those new
Jumpstart 4D
especially
if you come from a FileMaker Pro ®
to 4D on an enlightening and
highly readable journey to a
Press ™
Learning to program within one of the world's most renowned • The most comprehensive
development environments just got easier. Jumpstart 4D, the newest beginner's guide to 4D
book by longtime 4D developer Steve Hussey gives those who are new available
to 4D the strong foundation they need to successfully develop and
strengthen their 4D development skills. Hussey's expertise in 4D shines • Easy to read, step-by-step
through his insightful explanations of the basics of 4D development. format
Step-by-step, Hussey takes readers through all of the features that
4D has to offer, from creating a new database to adding related tables
to refining an end application. Whether you're new to database
programming or just new to 4D, Jumpstart 4D is the perfect guide for
exploring and realizing the possibilities of one of the richest database
• Written for people new to 4D
and programming
• Teaches you all you need to
Jumpstart 4D
applications around. know to start developing
your own databases in
"I really enjoyed Jumpstart 4D. It gave me a great minutes
start in understanding and using the basics of 4D • Loaded with time-saving tips
Steve Husseys
development. This is an excellent book for 4D users and useful hints to make
who are just starting out." ~ Robert Reed database programming a
University of Texas, Austin
snap
•••••
• Build a powerful working
"Jumpstart 4D delivers what you need to get going
Steve Hussey
application using 4D in a few
in a simple, no-nonsense way." ~ Nicholas Daum
RDBMS Consultant hours
••••• • Covers the entire process of
"After working through the book you'll have a very creating a 4D database appli-
respectable knowledge of 4D as well as a really cation including developing,
compiling, and deploying
clever invoicing system that you created yourself."
~ Kim Kohen
and much, much more...
Steve Hussey is a prolific author on the subject of 4D; in addition ISBN 0-9712895-1-4
to many books on 4D, he has written numerous articles for 90000
Dimensions: The Journal of 4D and 4D WebSTAR, and
technical notes for 4D, Inc. He is a popular speaker at
the 4D Summit conferences, and regularly trains people
in 4D across the United States and Canada. In March 2001, Steve
Press ™
PRESS.4D.COM
became the editor and publisher of Dimensions. He lives on a small
island off the coast of Washington state.
9 780971 289512 Press ™