You are on page 1of 312

“ 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 ™

solid understanding of the


background. ”
~ Charlie Tiggs
Tiggs Consulting basics of 4D:

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 ISBN: 0-9712895-1-4


by Steve Hussey SHELVING CATEGORY: PROGRAMMING 4 D P R E S S . 4 D . C O M
Jumpstart 4D™ © 2002 by Steve Hussey. The 4D WebSTAR and the 4D Press Logo are registered trademarks of 4D, Inc. 4D is a registered trademark of 4D SA. Brands and
products referenced herein are the trademarks or registered trademarks of their respective holders. Printed in the U.S.A. BK0300C00ESB001
“ 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 ™

solid understanding of the


background. ”
~ Charlie Tiggs
Tiggs Consulting basics of 4D:

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 ISBN: 0-9712895-1-4


by Steve Hussey SHELVING CATEGORY: PROGRAMMING 4 D P R E S S . 4 D . C O M
Jumpstart 4D™ © 2002 by Steve Hussey. The 4D WebSTAR and the 4D Press Logo are registered trademarks of 4D, Inc. 4D is a registered trademark of 4D SA. Brands and
products referenced herein are the trademarks or registered trademarks of their respective holders. Printed in the U.S.A. BK0300C00ESB001
Previous books published by Alto Stratus LLC
4D First and Last
4D Step-by-Step
Programmer’s Glossary
Database and Computer Security Guide
4D Advanced Guide, 1st Edition
4D Advanced Guide, 2nd Edition
4D Advanced Guide, 3rd Edition
The Inner Dimension (CD Book)
Inside 4th Dimension v6 (with Geoff Perlman)
4D A-Z (CD Reference)

Publications Published by Alto Stratus LLC


Dimensions: The Journal of 4D & WebSTAR
http://www.dimensionsmag.com
© Steve Hussey 1993 – 2002, Alto Stratus LLC
Printed in the United States of America.
All rights reserved. This product and related documentation are protected
by copyright and distributed under licenses restricting its use, copying,
distribution, and decompilation. No part of this product or related docu-
mentation may be reproduced in any form by any means without prior
written authorization of Steve Hussey or an authorized officer of Alto Stra-
tus LLC.
RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by
the United States Government is subject to the restrictions set forth in
DFARS 252.227-7013(c)(1)(ii) and FAR 52.227-19.
Trademarks and Acknowledgements
4th Dimension, 4D, 4D Insider, 4D Compiler etc. are all the trademarks
of 4D, Inc., and 4D SA.
References to Mac OS refer to the Macintosh operating system, a regis-
tered trademark of Apple Computer Inc.
Windows refers to Windows 98/NT/2000, and is a registered trademark
of Microsoft.
All other trademarks are acknowledged as the property of their respective
owners.
Colophon
Distributed by 4D Press™

This book was outlined with In Control 4, written using FrameMaker 6,


illustrated with Adobe Photoshop 5.5 and 4D v6.7. was used to create all
sample databases.
Index entries were generated with custom 4D software written by Steve
Hussey. All content created on a Apple Macintosh PowerBook G3 Series
computer (500 MHZ) using Mac OS 9.1.
No computers were hurt during the creation of this book.
This book is not in the public domain.
Dedication

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

Trademarks and Acknowledgements 1–3


Colophon 1–3
Using Jumpstart 4D 1–1
About the CD-ROM 1–1
New to 4D? 1–1
Opening and Editing the Sample Databases 1–2
Inadvertently Launching 4D Runtime 1–2
Absolute Beginners: Start Here 2–1
Can You Use Your Computer? 2–1
Installing 4D 2–1
What is a Database? 2–2
What Can Relational Databases Be Used For? 2–3
How Difficult is It to Learn 4D? 2–3
Creating a Single Table Database 3–1
Defining the Problem 3–1
Launching 4D 3–6
Opening an Existing 4D Database 3–7
Creating a New Database 3–7
Creating Tables and Fields 3–9
Creating Fields 3 – 11
Using the Form Wizard to Create Forms 3 – 16
Fields Tab 3 – 20
Styles Tab 3 – 20
Options Tab 3 – 23
Buttons Tab 3 – 25
Creating a List Form 3 – 28
Entering Data 3 – 31
Entering and Reviewing Sample Data 3 – 43
Summary 3 – 45
The User Environment 4–1
What is the User Environment? 4–1
Entering Records in the User Environment 4–2
The Current Selection 4–2
Queries Menu 4–4
Charts 4 – 10
Apply by Formula 4 – 11
Quick Report Editor 4 – 12
Jumpstart 4D

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

Eliminating the Errors 10 – 12


Recompiling 10 – 15
Building a Compiler Project 10 – 15
4D Server 11 – 1
The Scenario 11 – 1
Installing 4D Server and 4D Client 11 – 2
Updating Your Applications 11 – 6
Multi-User Issues 11 – 7
Developing a Database Using 4D Server 11 – 9
4D Insider 12 – 1
Using 4D Insider to Improve an Application 12 – 1
Replacing Commands 12 – 4
Groups 12 – 5
Unused Objects 12 – 6
Documentation 12 – 7
Copying Objects from One Database to Another 12 – 8
Code Libraries 12 – 12
STR# Resources 12 – 12
Utility Functions 12 – 13
4D Components 12 – 14
Using Insider with 4D Server 12 – 16
4D Utilities 13 – 1
4D Tools 13 – 1
Customizer Plus 13 – 11
4D Transporter 13 – 20
Plug-ins 14 – 1
Plug-ins Extend 4D’s Functionality 14 – 1
Installing 4D Plug-ins 14 – 1
Selecting 4D Plug-in Commands 14 – 2
Creating a Plug-in Area 14 – 2
4D, Inc. Plug-ins 14 – 4
Third-Party Plug-ins 14 – 10
Developing Your Own Plug-ins 14 – 10
Web Assistant 14 – 10
Developer Standards and Improving Your Code 15 – 1
Writing Better Code 15 – 1
Developer Standards 15 – 3
Naming Conventions 15 – 4
Type Prefixes 15 – 5
Comments 15 – 8
Standardizing Your Coding 15 – 9
Jumpstart 4D

Deploying Your 4D Database 16 – 1


4D Runtime 16 – 1
4D Runtime Classic 16 – 1
4D Engine 16 – 2
A Few Thoughts Before Deployment 16 – 2
Deploying Web-Based Applications 16 – 3
Deploying 4D Server-Based Applications 16 – 3
4D Resources 17 – 1
4D, Inc. (USA) 17 – 1
Mailing Lists 17 – 1
Web Resources 17 – 2
Books on 4D 17 – 4
User Groups 17 – 4
Cross-Platform Issues 18 – 1
Developers Should Understand the Operating Systems 18 – 1
Compatibility between Windows and Mac OS Versions of 4D 18 – 2
Differences Between the Mac OS and Windows Versions of 4D 18 – 3
Compiler Generation of Platform-Independent Databases 18 – 3
Database Properties 18 – 4
User Interface Differences 18 – 6
Style Sheets 18 – 8
Useful Cross-Platform Commands and Functions 18 – 11
4D Windows File Locations 18 – 14
Index 19 – 1
Jumpstart 4D

Chapter 1 – Using Jumpstart 4D

About the CD-ROM


If you have the Jumpstart 4D book, it may a include CD-ROM that con-
tains the book as a PDF and the sample databases. This CD contains:
+ A PDF version of this book. This is licensed only for your personal
use.
+ Sample databases for the relevant chapters.
+ Sample data files.
New to 4D?
One way to learn is to skim through the book and get a feel for 4D. Don’t
worry about trying to understand everything. Then come back to the
beginning and work through the exercises.
Alternatively you can just start at the beginning and work your way
through the exercises.
The sample databases on the CD are complete – you do not need to type
in any code, however creating your own code will probably help you to
understand it better. If you mess something up, who cares? Throw the
database away and go back to the sample databases from the CD.
4D User versus 4D Programmer?
If you are using 4D rather than programming in 4D, you may want to
read the sections on 4D Chart, Label Editor, Query Editors, Order by...
Editor and Quick Reports and skip the other chapters.
Moving up from FileMaker Pro?
Again, you might want to skim through the book to get a feel for 4D.
Then pretend you know nothing about databases and start learning 4D
from scratch.
4D works in a very different way from FileMaker Pro: you really need to
treat 4D as a very different tool. If you want to convert a FileMaker Pro
application to 4D, you should finish the book before attempting a conver-

Using Jumpstart 4D 1–1


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

When you double-click a 4D database it may be opened by 4D Runtime


instead of 4D. This may happen because 4D Runtime was installed after
the 4th Dimension program, and has the same signature as 4D.
If you use Option+f (Mac OS) Alt+F4 (Windows) and the database
immediately quits you know that the database has been opened by 4D
Runtime. (The 4D Runtime can only execute databases: It will not allow
you to edit them.) There are three possible cures for this:
+ Delete 4D Runtime if you do not need it.
+ Stuff or zip 4D Runtime. (You can unstuff or unzip it later, if
needed.)
+ Reinstall 4th Dimension.
- The OS launches the latest version of an application by look-
ing at its last modification date.
4D Runtime will be covered in “Chapter 16 – Deploying Your 4D Data-
base”.

Using Jumpstart 4D 1–3


Jumpstart 4D

1–4 Using Jumpstart 4D


Jumpstart 4D

Chapter 2 – Absolute Beginners: Start Here

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

2–2 Absolute Beginners: Start Here


Jumpstart 4D

other by common values (known as a key). The data is not duplicated


between different files, but loaded into memory only when needed by the
relational key.
What Can Relational Databases Be Used For?
Relational databases can be used to build many different types of applica-
tions:
+ Accounting applications such as billing, invoicing, accounts receiv-
able and payable, checking registers, inventory management, and
more.
+ Sales management applications such as contact, leads and mail man-
agement.
+ Multimedia databases that can store video clips, audio files, MP3s,
QuickTime movies, and more.
+ Internet applications such as e-mail and ftp clients.
+ Managing collectibles such as postage stamps, baseball, and trading
cards.
+ Document repositories that store documents such as letters and
manuals.
How Difficult is It to Learn 4D?
4D is simple to learn, if you have some programming experience. It is dif-
ferent from many other databases though, and may take some getting used
to. Its programming language is very similar to Pascal (including its han-
dling of strings and arrays).
If you are new to programming though, it may appear difficult at first, but
a few hours of experimenting should enable you to build a simple contacts
database. Six months of learning and you should be able to complete
moderately complex applications.
There are many resources available to help you along the way (see chapter
17 “4D resources”), especially on the 4D, Inc. (formerly ACI US Inc.)
Web site at http://www.4d.com/. Make good use of them! There are
also further resources and links from the Jumpstart 4D Web site at http://
www.jumpstart-4d.com
Good luck!

Absolute Beginners: Start Here 2–3


Jumpstart 4D

2–4 Absolute Beginners: Start Here


Jumpstart 4D

Chapter 3 – Creating a Single Table Database

In this chapter you will learn how to:


+ Define the solution to a problem.
+ Launch 4D.
+ Create a new 4D Database.
+ Define Tables and Fields.
+ Use the Form Wizard to create forms for input/output.
+ Enter data.
Defining the Problem
Before you start coding, you should have a clear idea of the scope of the
problem you wish to solve. Developing should be 80% planning and 20%
coding (Pareto’s Rule). The problem to be solved using this book will be:
+ To develop a 4D database to store contact information.
+ To allow invoices to be issued to these contacts for various products
and services.
+ To print invoices, and copies of the invoices when required.
+ To find invoices due for payment on any given date.
+ To generate various reports and charts as required.
Your mythical customer is vague about what they mean by “contacts”.
Their product line is likely to change. They have no idea how many cus-
tomers they have, how many invoices they might issue, how many line
items would be ordered on a typical invoice, or what reports they might
want. (In short, they are a typical customer.)
In this chapter you will cover the first part of the problem: the contact
table. How do you decide what will go into the contact table? And what
exactly is a table anyway?
In database terms, a table is a related collection of data. In a spreadsheet it
would be the data that appears in a single spreadsheet. For example, all the
data that would belong to the contact, such as their name, address, and fax
number. 4D can have up to 255 tables in a database. (In FileMaker Pro
each table would be a separate database file.) Your finished application
would have one table for the contact specific data, another for the invoice
Creating a Single Table Database 3–1
Jumpstart 4D

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

3–2 Creating a Single Table Database


Jumpstart 4D

Table 3-1: First List of Fields

Field

Fax Number

This raises a few questions:


+ The name field: Do you allow for companies and/or individuals?
How do you know which is which? If the contact is an individual
can you search on the first or last name, or do you need to know the
whole name?
+ Will one line do for the address? What happens if you have a more
complicated address to store? (Most addresses in the USA consist of
2 to 3 lines, plus the city, state, and zip.)
+ What happens if you have a contact overseas, or north of the border
in Canada? Are their addresses formatted differently? (Hint: Yes.)
+ Can you find one format that handles all these different cases?
After considering these points, you may wish to refine your field list fur-
ther:
Table 3-2: Revised Fields

Fields

Company Name

First Name

Last Name

Address Line 1

Address Line 2

City

State

Zip Code

Country

Telephone

Fax

Creating a Single Table Database 3–3


Jumpstart 4D

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

Alphanumeric 0 Chars (Uses 2) 80 Chars Yes Empty

Text 0 Chars 32,000 Chars No Empty

Integer -32,768 32,767 Yes 0

Longint -2,147,483,648 +2,147,483,647 Yes 0

Real (15 digits) -1.7e-308 +1.7e+308 Yes 0

Date 01/01/100 12/31/32767 Yes 00/00/00

Time 00:00:00 596,000:00:00 Yes 00:00:00

Boolean N/A N/A Yes False

Picture Empty 32 KB No Empty

BLOB Empty 2 GB No Empty

Subtable N/A N/A Depends on Depends on


field type field type

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

3–6 Creating a Single Table Database


Jumpstart 4D

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 have two choices:


Creating a Single Table Database 3–7
Jumpstart 4D

Create a new database (with optional enclosing folder/directory).


Open an existing database.
 With 4D v6.7 you can also install the 4D Web Assistant when cre-
ating a new database.
If you choose to open an existing database, the text area below that radio
button lists recent databases used with this version of 4D.
Select Create a Blank Database, then click OK to continue.
Figure 3-2: Naming the Sample Database

At this point you can:


+ Navigate to a specific folder/directory using the navigation services
provided by your OS.
+ Name your new database.
Click Save to save the database.
Since the Create Database Folder option was selected, 4D created the
enclosing folder as well:
Figure 3-3: Enclosing Folder

3–8 Creating a Single Table Database


Jumpstart 4D

Figure 3-4: Folder Contents

Sample DB is the structure file


Sample DB.data is the data file
4D creates the first table in the database automatically, since every 4D
database must have at least one table (even if it is unused).
Figure 3-5: Structure View in a New Database

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 a Single Table Database 3–9


Jumpstart 4D

Figure 3-6: Table Properties Dialog

+ Change the name Table 1 to Contact.


+ Click the Apply button.
+ Click Done.
The table has been renamed. You need not worry about the other tabs for
the moment.
Figure 3-7: The Renamed Table

You can enlarge the window to any convenient size.


Now that the table has been created, you can add fields to it.
+ Every field belongs to a specific table.
+ Fields cannot be deleted, only reused. They can be made invisible, so
that they do not appear in 4D’s User Environment editors.
+ In some 4D editors, the fields are listed in creation order; in others,
they are listed alphabetically by name.
+ Think (at least a little) before creating fields, especially subtables/
subfields, since they cannot have their type changed. Remember:
Think twice, code once!
3 – 10 Creating a Single Table Database
Jumpstart 4D

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.

Creating a Single Table Database 3 – 11


Jumpstart 4D

Why define fields such as telephone numbers as alpha instead of numbers?


Using an alphanumeric field will allow you to enter telephone numbers
such as 1-800-4D First.
Also, in the case of US zip codes, there are zip codes with leading zeroes. If
you define the field as a number, the leading zero will be dropped. The
extra character allows for the dash in 9-digit zip codes.
Notice that the spaces in the field names have been replaced with under-
scores “_”. The reason for this is purely practical – when double-clicking
on field names in the method editor, if the field name has no spaces the
entire name will be selected for copying, pasting, and deletion. If there are
spaces in the name you will only select the part of the name you double-
clicked on (and may not notice when copying or cutting and pasting).
Double-click on the first empty cell below the table title.
Figure 3-8: Field Properties Dialog

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.

3 – 12 Creating a Single Table Database


Jumpstart 4D

Figure 3-9: Field Defined

You can also click the Indexed attribute.


 Indexing a field makes it much quicker to search for: effectively an
index is like a duplicate entry for the field, held in an optimized for-
mat. As such, each index will add to the size of the data file. There-
fore you probably won’t want to index every field (and some field
types cannot be indexed). Index the fields that the user will search
on most frequently.
You can turn indexes on and off as you require, and you can even manage
this using 4D code.

Table 3-5: Indexable Field Types

Field Type Indexable

Alpha Yes

Text No

Date Yes

Time Yes

Real Yes

Integer Yes

Long Integer Yes

Creating a Single Table Database 3 – 13


Jumpstart 4D

Table 3-5: Indexable Field Types

Field Type Indexable

BLOB No

Picture No

Subtable/subfield Subfields only

Click the Apply button to apply your properties to the field.


Repeat the process until you have defined all fields. If you make a mistake
you can always double-click on the field in the table and edit the field’s
properties. The table should look something like this:
Figure 3-10: Completed Table

You can click and drag the lower border of the table to expand its size.
Figure 3-11: Table Without All Fields Showing

3 – 14 Creating a Single Table Database


Jumpstart 4D

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…

Creating a Single Table Database 3 – 15


Jumpstart 4D

Figure 3-13: Database Properties

+ Select Never from the Automatic Form Creation drop-down


menu.
If you let 4D create the forms for you, they will bear little resemblance to
what you want. You are better off creating your own using the Form Wiz-
ard.
Using the Form Wizard to Create Forms
Before you can enter any data via the keyboard into 4D, you will need an
input (detail) and an output (list) form for the table. Some tables may not
need data entry via the keyboard and therefore will not need forms.
4D’s normal mode of operation uses the list form to display lists of records
in a window. Double-clicking any row in the list (which represents a
record) opens an input form for that record with the data displayed in the
form. Unlike FileMaker Pro, you cannot enter data in a list form in the
Custom Menus Environment (where 4D uses menus to manage data).
We will discuss this in more detail later on.
For your contact records you will need an input form and a list form.
These will be created in the Form Editor. If you press Command+Space-
bar (on Mac OS or Control+Spacebar on Windows) while in the Design
Environment the Explorer is displayed.

3 – 16 Creating a Single Table Database


Jumpstart 4D

Figure 3-14: 4D Explorer

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.

Creating a Single Table Database 3 – 17


Jumpstart 4D

Figure 3-15: New Form Wizard

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).

3 – 18 Creating a Single Table Database


Jumpstart 4D

Figure 3-16: Fields in Suitable Order

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.

Creating a Single Table Database 3 – 19


Jumpstart 4D

Figure 3-17: New Form Wizard: Fields Tab

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.

3 – 20 Creating a Single Table Database


Jumpstart 4D

Figure 3-18: 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.

Creating a Single Table Database 3 – 21


Jumpstart 4D

Figure 3-20: Appearance

+ Foreground and background colors can be set.


Style Sheets
4D’s style sheets work in a similar way to desktop publishing and word
processing style sheets. You can create a named style sheet and define a
font, size, style and justification. The difference is that 4D uses style
sheets to manage the cross-platform representation.
 Mac OS and Windows use differently named fonts. It is very
unusual to find a Mac and a Windows computer that have fonts
installed with the same names. The OS will normally substitute
fonts for those that are not installed. This can cause your forms to
look different from what you had intended. Additionally, most ear-
lier Mac OS screens default to 72 dpi, while Windows defaults to 96
dpi. To have fonts that look the same on both platforms, your Win-
dows fonts should be 96/72 (125%) the size of your Mac fonts. A
10pt font on Mac OS looks similar to a 12 point on Windows.
Example: 4D allows you to create a style sheet named (say)
Fld_Enterable. This would use one font, size, style etc. on Mac OS and a
different font, size etc. on Windows. This way you can control the appear-
ance of your forms.
Even if you do not intend to use your application cross-platform, you
should consider using style sheets. If you later decide that your fields
should be displayed in a different font, you can just edit the style sheet
definition and all objects that use that style sheet will be automatically
updated.

3 – 22 Creating a Single Table Database


Jumpstart 4D

Figure 3-21: Style Sheet Editor

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

Creating a Single Table Database 3 – 23


Jumpstart 4D

Here you can set options such as:


+ Form size
+ Label location
+ Display options
If you select one of the standard PC screen sizes, 4D will create a form of
suitable size, or you can enter your own size (in pixels).
By selecting the various screen options, 4D will add these to the form.
+ Record number/Record Count will insert a variable that displays a
record count such as Record 1 of 5.
+ Form title will display the form name when the window is opened.
+ You can select a background picture from the drop-down menu.
+ If you have a menu bar defined already, you can associate it with the
form so that it is automatically displayed when that form is opened.
+ One Field per Line displays only one field on each line.
+ Create Multiple Pages if necessary will create more pages for each
form if there are too many fields to place on the first page (Page1).
+ Use Dynamic Field Names will use a special text marker for the
labels so that the actual field names will be displayed on the form. If
you later change the name of a field, 4D will automatically update
the labels.
Pages on a Form
4D’s forms can have multiple pages. Every form has by default two pages
when it is created:
+ Page 0 (zero) – the master page.
+ Page 1.
Page 0 is a special page: Any object that is placed on this page will appear
on all subsequent pages. This is a useful page to locate Save/Cancel but-
tons, headers, etc.
You can have buttons on any page that allow you to move to the next
page, or you can use a tab object to allow the user to click on whichever
page they want to go to.

3 – 24 Creating a Single Table Database


Jumpstart 4D

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

From this tab you can select:


+ The button family you like.
+ What buttons will appear on the form.
+ Where the buttons will appear on the form.
After selecting a button family from the drop-down menu, you can click
the right arrow next to the first displayed button to examine the appear-
ance of the remainder of the buttons.
You can move, or drag and drop the button Available Actions to the list
of Selected Actions. You can then change their order. The order of the
Selected Action buttons is the order the buttons will appear on page 1 of
your form. New forms have a default selection of buttons in the Selected
Actions list. You can delete buttons you will not need (in this case Next
Page and Previous Page).
Now you can click OK to complete your form.

Creating a Single Table Database 3 – 25


Jumpstart 4D

Figure 3-24: Completing the Form

+ 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

+ The table name is in bold.


+ The (single) form is listed below it (to show that this form belongs
to this table).
3 – 26 Creating a Single Table Database
Jumpstart 4D

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

Double-click the form to open it in the Form Editor:


Figure 3-27: Your Detail/Input Form

Creating a Single Table Database 3 – 27


Jumpstart 4D

Later you can edit this form as desired.


Creating a List Form
Now that you have a form for data entry, you will need a form for data
viewing. You need to repeat the process, except this time you will create a
list form.
+ Use Command+Spacebar (On Mac OS or Control+Spacebar on
Windows) to bring the explorer to the front.
+ Select the Contact table.
+ Click New.
+ Enter a name for the form. For this example the f orm name will be
“Contact_lst”.
Figure 3-28: Naming the List Form

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.

3 – 28 Creating a Single Table Database


Jumpstart 4D

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.

Creating a Single Table Database 3 – 29


Jumpstart 4D

Figure 3-30: 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

Creating a Single Table Database 3 – 31


Jumpstart 4D

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.

3 – 32 Creating a Single Table Database


Jumpstart 4D

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):

Creating a Single Table Database 3 – 33


Jumpstart 4D

Figure 3-33: Menu Bar Editor

List of Menu Bars lists all currently defined menu bars.


Current Menu Bar lists all menu items for the Menu Bar that is selected
on the left.
To create your first menu bar click the Add button beneath the List of
Menu Bars list. This will create the first menu bar and number it 1:
Figure 3-34: First Menu Bar

3 – 34 Creating a Single Table Database


Jumpstart 4D

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).

Creating a Single Table Database 3 – 35


Jumpstart 4D

Figure 3-36: Quit Menu Defined

You can now create the Quit project method:


+ Select the word Quit.
+ Copy (Command+C on Mac OS or Control+C on Windows)
+ Type Command+M (on Mac OS or Control+M on Windows)
The following dialog appears:
Figure 3-37: Project Method Dialog

+ Leave the Method Type selected as Listing. (Flowchart methods


cannot be compiled).
+ The Paste command (Command+V on Mac OS or Control+V on
Windows) – this will paste the name of the method into the Method
Name. (This is useful to ensure that you do not misspell longer
method names.)

3 – 36 Creating a Single Table Database


Jumpstart 4D

Figure 3-38: Correct Project Method

+ Click OK.
The Quit project method opens:
Figure 3-39: Quit Project Method

The method window is divided into three areas:


+ The method editing area (the top part of the window).
+ Keywords pane – You can select keywords from here by either:
- Double-clicking any keyword.
- Dragging and dropping any keyword from the Keywords
pane to the editing area.
+ The list of tables and fields (center pane). You can use the same
methods to select the field names.
+ Commands pane – All of 4D’s commands (and any installed plug-
ins) can be selected from here by clicking on the theme (the bold
name) and holding the mouse button down. All commands for that

Creating a Single Table Database 3 – 37


Jumpstart 4D

theme are then displayed. To select a command scroll to the desired


command and release the mouse button.
The window can be resized by dragging the thumb tab in the lower right-
hand corner of the window.
The panes can be resized (on a window-by-window basis) by clicking and
dragging on either the horizontal or vertical dividing lines between the
panes.
The window title is the project method name and the window has the
standard OS controls for closing, resizing, and minimizing the window.
Figure 3-40: Selecting a command:

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:

3 – 38 Creating a Single Table Database


Jumpstart 4D

Figure 3-41: 4D Explorer: Methods Tab

You can use the 4D Explorer to list your methods.


+ Clicking on a method name displays it in the Preview Window (if
Preview is selected).
+ Double-clicking a method name opens it in the method editor. (You
can also select it and click Edit).
+ Command+Click (on Mac OS or Control+Click on Windows) a
method name to edit it.
- If you change the name of a method that is called from
another method you will also have to change the name there.
Methods in 4D fall into several categories:
+ Database Methods – These run when certain database events hap-
pen (such as starting up).
+ Form Methods – These execute when certain events happen to
forms (such as when a form is opened).
+ Table Methods (aka Triggers) – These execute when certain events
happen to a table (such as when saving a new record).
+ Project Methods – These only execute when you call them.
+ Object Methods – Execute when certain events happen to the
object they are attached to (such as when a button is clicked).
All of these method types can call project methods.
What is a method?
In 4D, a method is a sequence of code that performs a particular task. In
other languages this might be called a program, class, subroutine, or func-
Creating a Single Table Database 3 – 39
Jumpstart 4D

tion. 4D’s programming language was based originally on Pascal, and if


you have used Pascal or BASIC you’ll find 4D’s language easy to use. 4D
v6.7 has about 600 commands and functions in its language, about 1200
if you include 4D’s plug-ins (which add further commands and functions
to 4D when installed).
 For geeks: 4D’s string and array handling is Pascal-based too,
rather than C or C++ like.
In a 4D method you type (or drag and drop) a sequence of instructions
into the method editor. You can also cut/copy and paste between methods.
 A single method can hold up to approximately 32 KB of text (that’s
a lot). It is easier to edit methods though, if they are short and to the
point. A good rule of thumb is: If the method is too long to fit on
your screen, then it’s too long! Long methods are hard to read and
even harder to debug.
 There is no theoretical limit to the number of methods in a data-
base.
When the method is executed, the steps are executed one after another
until the method is finished. Since a method can call further methods, and
so on, you can execute a lot of functions.
The Quit method you just wrote is a very simple example of a method.
When called from the Quit menu item it executes the single command
QUIT 4D. Notice that the command is all in uppercase; this is because it
is a command (rather than a function). When executed it will quit 4D.
Later you will notice that some commands are in uppercase, for example
ALL RECORDS, while others are in lowercase, for example Get text
from clipboard. Commands in lowercase are known as functions,
because they return a result. In this example executing the command Get
text from clipboard “returns” whatever text was on the clipboard,
therefore you need somewhere to put the resulting text. You would assign
it to a field or variable, for example:
[Table]Clipboard_Contents := Get text from clipboard

Creating more project methods


So far the only method you have created is the Quit method. This gives
you a way to quit your application when you are in the Custom Menus
3 – 40 Creating a Single Table Database
Jumpstart 4D

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

Creating a Single Table Database 3 – 41


Jumpstart 4D

line immediately. This improves performance. If you type the com-


mand incorrectly, 4D will display the correct syntax and parameters
for the command in the method header.
When you are finished, your code should look like this:
Figure 3-42: Add Contact Record Method

+ 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

+ Switch to the Custom Menus Environment (Command+I on Mac


OS or Control+I on Windows).
+ Select Add Contact from the Contact menu.
+ 4D will display the detail form you created earlier.
+ Enter some sample data.
+ Click the disk icon (with the green background) to save the record.
+ Add further records as desired.
+ After you have saved your last record, you will have an empty screen.
Click the disk icon with the red background to close the screen (the
empty record will not be saved).
Now that you have entered some sample data you may wish to review it.
+ Select List Contacts from the Contact menu.
- If you have more than one record in the database you will see a
list of records in the list form you designed.
- If you have only one record defined, you will see the record in
a detail (input) form. You can modify this behavior so that 4D
always lists records in the list form no matter how many there
are. To do this, change the line of code:
MODIFY SELECTION([Contact])

to
MODIFY SELECTION([Contact];*)

in the CNT_List method.


You can add, edit, and delete records as you wish. To delete a record you
can click the delete icon in the detail form. You can also delete a selection
of records in the list view.
If you have a lot of records to delete you can:
+ List Contacts.
+ Click, Shift+Click or Command+Click (on Mac OS or Con-
trol+Click on Windows) any combination of records.
+ Click the Show Subset button to make the selected records the
current selection.
+ Click Delete Selection to delete the current selection.
 Command+Z (on Mac OS or Control+Z on Windows) cannot
undo a deleted record in 4D. It can undo changes you have made to
a field.
3 – 44 Creating a Single Table Database
Jumpstart 4D

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...

Creating a Single Table Database 3 – 45


Jumpstart 4D

3 – 46 Creating a Single Table Database


Jumpstart 4D

Chapter 4 – The User Environment

In this chapter you will learn how to:


+ Enter data using 4D’s forms.
+ Use 4D’s Editors.
+ Use the Quick Report Editor.
+ Create labels with the Label Wizard.
+ Query (search) data.
+ Sort data using Order by...
+ Update a selection of records using Apply Formula…
All of these tasks occur in the User Environment.
What is the User Environment?
The User Environment is a convenient place to:
+ Enter, review, and edit data.
+ Find records.
+ Sort records.
+ Print labels.
+ Create and print charts.
+ Report data.
+ Fix data.
4D provides a number of tools to help you do this in the form of its User
Environment editors. The User Environment is not really suitable for an
end user to use, but it is useful for entering test data before a complete
Custom Menus Environment has been built, for testing and debugging,
or fixing corrupted or incomplete data without the need to write code.
Most of the 4D tools available from the User Environment can be
accessed via code so that you can provide the same functionality from the
Custom Menus Environment.
To experiment with the User Environment launch the Chapter 3 sample
database. Note that the database opens in the Design Environment. You
can change easily this behavior if you need to:
+ File ¬ Database Properties

The User Environment 4–1


Jumpstart 4D

+ Click User Environment in the Startup Environment group.


The next time you open the database it will open in the User Environ-
ment and display the default list form for the first table in the database.
You may also want to uncheck the Show Toolbar option in the Toolbar
group area. (This will turn off 4D’s toolbar that runs across the screen,
below the menu bar. You can also hide the toolbar in code using the HIDE
TOOLBAR command.)

Entering Records in the User Environment


+ Press Command+U (on Mac OS or Control+U on Windows) to
switch to the User Environment.
Now you can enter some new records in the User Environment rather
than using your menus. Any existing records you have entered will be dis-
played in the list form.
+ Select Enter ¬ New Record from the 4D menu, or press Com-
mand+N (on Mac OS or Control+N on Windows) to enter a new
record using the detail form.
+ To delete a record select it (by clicking on the row) and either:
- Press the Delete key.
- Select Edit ¬ Clear.
+ To enter records in the list view (which can be quicker if you have a
lot of records to enter) press Command+, (on Mac OS or Control+,
on Windows), or select Enter ¬ Enter in List. Each Command+N
(on Mac OS or Control+N on Windows) adds a new line to the list
and places the cursor in the first field for data entry.
Enter a few records.
The Current Selection
One concept that is essential to understanding 4D is the Current Selec-
tion. You have now entered a few records into one of the 4D tables (the
Contact table). At various times you will be working with some or all of
these records. 4D refers to the selection of records that you are working
with as the Current Selection.
Consider a Contact table that has 100 records in it, the names of all your
customers:

4–2 The User Environment


Jumpstart 4D

+ 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.

The User Environment 4–3


Jumpstart 4D

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.

4–4 The User Environment


Jumpstart 4D

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

+ You can search only on fields in the current table.


+ Query by Example… performs both indexed and sequential que-
ries.
You can use Comparison Operators. For example, to use the is equal to
operator, enter the value to be queried for in the appropriate field. If you
need a different operator, precede the value with one of the following
signs:
Table 4-1: Comparison Operators

Comparison Operator

is not equal to #

is greater than >

is greater than or equal to >=

is less than <

is less than or 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

+ Searching on the results of arithmetic computations.


Figure 4-1: Query by Formula… Editor

For example you could find:


+ All clients whose last name starts with Smith.
+ All clients born before January 1st, 1979.
+ All invoices whose total exceeds $1000 and are past due.
The example shows querying for all (US) 5-digit zip codes. Note that the
query is performed on the entire table, not the current selection of records.
Formula Length
You can only write a formula that is one logical line long. That is, you can-
not press the Enter key on the keyboard (Return on Mac OS) and write a
second line. The editing area, however, will wrap to the next line if the
statement is too long. If you need to use a formula that is more than one
line, write it as a Project Method and use the project method in the for-
mula.
Using the Char Function
If you are searching for a character using the Char function, you must use
ASCII codes. For a detailed discussion of the Char function, and a list of
Mac OS and Windows ASCII codes, refer to the 4D Language Reference
documentation.
4–8 The User Environment
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

The Order by… editor contains the following areas:


Available Fields
This area displays a list of fields in the current table. Indexed fields are
shown in bold. You can sort on fields from subtables and related tables
(provided the relation is automatic). To use a field from a related table or
subtable, expand a foreign key field by clicking on the plus sign (on Win-
dows) or disclosure triangle (on MacOS) to display the fields from the
related table.
 Only tables and fields that are visible appear in the Order By… edi-
tor. (When you define Fields and Tables you can define that they
are Invisible to hide them from the user.)
The User Environment 4–9
Jumpstart 4D

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

The User Environment 4 – 11


Jumpstart 4D

commands in alphabetical order by selecting Commands by Alpha-


betical Order from the Commands by Theme drop-down menu.
As with the other 4D editors you can save and load formulas for future
use.
What use is the Apply Formula… editor? It is a quick and dirty way of
cleaning up data while you are developing a database. Your users should
not be given access to the User Environment and therefore will be unable
to access or use it.
You could emulate this functionality in the Custom Menus Environment
by using the command APPLY TO SELECTION.
Quick Report Editor
Now that you have created a current Selection of records in one table you
may want to print out the data that you found. You can use the Quick
Report Editor for this.
In 4D you will normally have two types of reports:
+ Canned Reports are programmed reports which usually find, sort
and print a report that has a fixed format. These are reports that are
run fairly often, an example might be a report of today’s shipped
orders.
+ Ad Hoc Reports. These reports are only occasionally needed, the
user can create them when needed using the Quick Report Editor.
Let’s say that want to create a one-time list of your contacts to impress
your bank manager. To create one you:
+ Select Report ¬ Quick… (or Command+R on Mac OS or Con-
trol+R on Windows). This displays the Quick Report Editor.

4 – 12 The User Environment


Jumpstart 4D

Figure 4-4: Quick Report Editor

+ 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 User Environment 4 – 13


Jumpstart 4D

+ Automatic Width – 4D calculates the width of the longest value in


that column and sets the column width automatically to prevent val-
ues from being cropped. This can be slow on a long report.
+ Select Print… or Print Preview from the File menu.
Print Preview prints a miniature view of the report:
Figure 4-6: Print Preview

+ 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.

4 – 14 The User Environment


Jumpstart 4D

Figure 4-7: Header & Footer Definition

+ #D is the 4D shorthand for current date, #H for the current time.


These variables can be selected from the drop-down menu to the
right of the Left/Center/Right fields.
+ A footer can be set in the same way.
Saving the Report
Select File ¬ Save as… to save the report for future use. You can name
the file anything you like (You use the .qr suffix so that you know that the
file is a Quick Report Editor definition when at the Desktop/Finder).
Figure 4-8: Saving a Quick Report

The User Environment 4 – 15


Jumpstart 4D

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

4 – 16 The User Environment


Jumpstart 4D

+ 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.

The User Environment 4 – 17


Jumpstart 4D

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.

4 – 18 The User Environment


Jumpstart 4D

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 4 – 19


Jumpstart 4D

4 – 20 The User Environment


Jumpstart 4D

Chapter 5 – Improving the Custom Menus


Environment

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

Figure 5-1: 4D Splash Screen

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

5–2 Improving the Custom Menus Environment


Jumpstart 4D

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).

Improving the Custom Menus Environment 5–5


Jumpstart 4D

WND_Cls
Create a project method named WND_Cls and enter the following code:
CANCEL

Close the method.


WND_Cntr
Create a project method named WND_Cntr and enter the following
code:
`$1 = Window width
`$2 = Window height
`$3 = Window type
`$4 = Window title
`$5 = Close method

The lines above, preceded by a ` character, are comments. Anything fol-


lowing the ` character is ignored by 4D. The lines are there for your bene-
fit. Each comment can be up to 80 characters. In this case, the comments
list the parameters that will be passed to this method when it is called. The
first parameter will be the width (in pixels) of the window, the second
parameter the height of the window, and so on.
The following are compiler declarations (more on these in the Compiler
chapter):
C_REAL($1;$2;$3;$sw;$sh;$ww;$wh)
C_STRING(255;$4)
C_STRING(15;$5)

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

$ww:=Int($1/2) ` Center of window, horiz.


$wh:=Int($2/2)` Center of window, vert.

5–6 Improving the Custom Menus Environment


Jumpstart 4D

Open window($sw-$ww;$sh-$wh;$sw+$ww;$sh+$wh;$3;$4;$5)

Variables $1 through $5 are known as parameters. They reflect values


passed to this method in the order they were passed. The first value is $1,
the second is $2, and so on. If there is a result to be returned, it is placed
in $0.
Parameters are a very powerful concept. You can create a project method
that accepts parameters (this is now called a function) and pass it different
values at different times. The method stays the same, only the parameters
are changed (perhaps to protect the innocent?). In the example above, you
can execute the same method and pass it different heights and widths to
open windows of different sizes. You can pass many parameters to a
method, although you need to pass the same number of parameters each
time. (You can write code to work around this limitation.)
 A method can also return a value to the method that called it. This
uses a special local variable called $0. Only one value can be
returned this way.
Next create a new form in the Contact table, name it
Contact_QuickFind. This will be used to display a variable to enter your
search criterion.
Figure 5-4: Contact_QuickFind Dialog

This form consists of three parts:


+ The variable text_SearchValue
+ Four radio buttons (which the user uses to indicate which field they
wish to search on).
Improving the Custom Menus Environment 5–7
Jumpstart 4D

+ Two buttons: Cancel and Query.


After creating the blank form you can drag and drop the different objects
from the tools palette onto your form.
Figure 5-5: Tools Palette

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.

5–8 Improving the Custom Menus Environment


Jumpstart 4D

Figure 5-6: Property List

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:

Improving the Custom Menus Environment 5–9


Jumpstart 4D

Figure 5-7: Object Properties

+ The variable has been named text_SearchValue. It must be set as


Enterable (so the user can enter a value).
Next, create the radio buttons. You can drag and drop the first one, set its
properties, then duplicate it as many times as you need. Each button must
have a unique name, but should start with the same first letter. (4D does
not force you to use unique names. You can use buttons with the same
name in different forms.)
 Form object names must be process or interprocess. They must not
start with the $ character.
The radio buttons should be named:
+ rbtn_Last
+ rbtn_Company
+ rbtn_City
+ rbtn_State
Next create two buttons: one to execute the query, the other to cancel the
operation if the user changes his or her mind (believe me they do). They
can be dragged and dropped from the tools palette.

5 – 10 Improving the Custom Menus Environment


Jumpstart 4D

Figure 5-8: OK Button Properties

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

Improving the Custom Menus Environment 5 – 11


Jumpstart 4D

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

Display whichever records have been found:


MODIFY SELECTION([Contact])
End if

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.

Improving the Custom Menus Environment 5 – 13


Jumpstart 4D

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

The second method has an extra advantage (or perhaps disadvantage). It


resets the search value back to the empty string each time the query is per-
formed. Otherwise whatever value you typed in for the previous query will
reappear in the search variable the next time it is called. (Sometimes this is
useful.)
Modifying the Code
C_TEXT(text_SearchValue)
text_SearchValue:="" ` Optional
WND_Cntr (400;200;5;"Find Contacts";"WND_Cls")
DIALOG([Contact];"Contact_QuickFind")
CLOSE WINDOW
If (ok=1)
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)
: (rbtn_State=1)
QUERY([Contact];[Contact]State=text_SearchValue)

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

Improving the Custom Menus Environment 5 – 15


Jumpstart 4D

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

+ Click the Events tab.


+ Make sure that the On Load event is checked. The others do not
matter at this time.
Now when you run the Quick Find menu item, the first radio button will
default to being selected. The user can click any other button if needed.
Trying to anticipate which defaults will suit your users is all part of the fun
of designing an effective and efficient user interface.
Form Events
Form Events can be confusing at times, but for most purposes they are
simple if you understand the basics. There is one essential point to under-
stand: they are Form Events, not record events, as many people believe.
Code written in a Form Method runs when certain events happen to the
form: loading the form, unloading it, closing it, and so on. A typical
example is that you want to set up certain conditions on the form before
the user sees it, this might include:

5 – 16 Improving the Custom Menus Environment


Jumpstart 4D

+ Coloring some field backgrounds to indicate that data in them is


mandatory.
+ Enabling and disabling buttons.
+ Setting the window title (when displaying selections of records).
+ Making some object invisible to some users (for security).
+ Setting default radio buttons or check boxes.
+ Loading data from fields into variables (and back again when the
form is closed).
To set up a form with a form method that handles form events there are
two things you need to do:
+ Have form method code that tests for each event (that you are con-
cerned with) and which does something when that event occurs.
+ Enable the matching form events in the Form Properties. If you
don’t enable the matching events your code will not run! In the
Form Properties you are telling 4D to recognize that these events
are occurring for this form (they are set on a form-by-form basis).
The code tells 4D what to do when these events occur.
Case of
: (Form event=On Load )
rbtn_Last:=1
End case

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:

Improving the Custom Menus Environment 5 – 17


Jumpstart 4D

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

+ Double-click on any button. This opens either the Property List or


Object Properties depending on how you set your preferences from
the Form ¬ Display menu.
You can now set the size and font:

5 – 18 Improving the Custom Menus Environment


Jumpstart 4D

Figure 5-14: Button Settings in the Properties List

+ Button width has been set to 72 pts.


+ Text has been set to Helvetica 10 pt. (Creating a button style sheet
would be a good idea).
Figure 5-15: Button Settings in the Object Properties Dialog

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

Improving the Custom Menus Environment 5 – 19


Jumpstart 4D

4D will space the buttons evenly apart.


You can now use the arrow keys to move the buttons to your desired posi-
tion.

5 – 20 Improving the Custom Menus Environment


Jumpstart 4D

Chapter 6 – Adding a Non-Related Table

In this chapter you will learn how to:


+ Create a second table.
+ Import data from a text file into this table using 4D’s Import Edi-
tor.
+ Create an Object Method on a form in another table that uses this
data.
A common requirement in a database is to be able to ‘look up’ data from
another table. A typical example would be zip (postal) codes.
 For the benefit of international readers the US Postal Service uses zip
codes to assist in the delivery of mail. A zip code is a 5-digit number,
each number has a corresponding town, county, and state. One zip
code may in fact cover several towns in a rural area, or just part of a
town in an urban area. For example 97467 covers Reedsport, Win-
chester Bay, and Gardiner in Oregon, yet 95825 covers only a few
blocks of urban Sacramento.
Once issued, a zip code never changes, but new zip codes are added regu-
larly. An extra 4 digits may be added to specify the delivery route within
the zip code but users are usually not interested in that data unless they
wish to verify addresses. Databases of zip codes can be downloaded from
the Web. There are currently about 45,000 valid zip codes (including
codes that cover US Forces bases in the USA and overseas). The data file
included with the sample database in Chapter 6 includes most of the cur-
rent zip codes for the US.
In a contact database it would be useful if there was the ability to look up
part of the contact address (city and state) from the zip code. This saves
the user time during data entry, and reduces the possibility of typing
errors. To do this you need to:
+ Add a second table that can store the zip code data.
+ Import the data from the text file using the Import Wizard (you
wouldn’t want to type in 45,000 zip codes).

Adding a Non-Related Table 6–1


Jumpstart 4D

+ 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:

6–2 Adding a Non-Related Table


Jumpstart 4D

Figure 6-1: New Table Dialog

+ Enter the table name Zipcode.


+ Click OK. The Table Properties dialog is displayed.
Figure 6-2: Table Properties Dialog

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:

Adding a Non-Related Table 6–3


Jumpstart 4D

Figure 6-4: Zipcode Field

This field needs to be indexed since it will be queried on frequently.


Indexed fields query much faster than non-indexed fields. The Unique
property forces 4D to allow only unique record values for this field. If you
try to enter a duplicate value (in this case a zip code) 4D will alert you and
prevent you from entering it. Indexed must be selected for this option to
be enabled.
+ Click Apply to define this field and set these attributes.
+ Set up the City field in the same way.
Figure 6-5: City Field

+ Click Apply.
Set up the State field:

6–4 Adding a Non-Related Table


Jumpstart 4D

Figure 6-6: 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…

Adding a Non-Related Table 6–5


Jumpstart 4D

Figure 6-8: Import Editor

+ Use the file navigation dialog to navigate to the location of your


copy of the text file that contains the zipcode data. The dialog is OS-
specific. Select the data file to import and click Open.
4D will display the Import Editor wizard.
Figure 6-9: Import Wizard

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.

6–6 Adding a Non-Related Table


Jumpstart 4D

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.

Adding a Non-Related Table 6–7


Jumpstart 4D

 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

: (Records in selection([Zipcode])=1) ` What you want...


[Contact]City:=[Zipcode]City ` Copy the city from the
zipcode table to Contact table
[Contact]State:=[Zipcode]State ` Copy the state from the
zipcode table to Contact table

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.

Adding a Non-Related Table 6–9


Jumpstart 4D

Figure 6-12: Object Properties Dialog

On Data Change is set using the Object Properties.


Case statements
A Case statement is a series of tests, only one of which will execute. It
takes the form:
Case of
:(Some Test in here) ` Note the colon to the left of the first
parenthesis
` What happens if the test above it was successful
:(Some Other Test)
` Yet more code that executes only if the test immediately above
it succeeds
Else
` What happens if all the above tests fail
End case ` The end of the test, each case of must have a
matching End case

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)

Adding a Non-Related Table 6 – 11


Jumpstart 4D

To change the entry order:


+ Click in the Address_Line_2 field and drag to the Zipcode field.
+ Click in the Zipcode field and drag to the country field.
+ Click in the Country field and drag to the Telephone field.
+ Click in the Telephone field and drag to the Fax field.
+ When you have finished setting the desired entry order, you will
need to select Form ¬ Entry Order again to turn this mode off.
Now as the user tabs through the fields, he or she will tab from the
Address_Line_2 field to the Zipcode field. Then they can enter the zip
code and tab out (into the country field) to activate the query. The city
and state fields will be filled in if a matching zipcode is found.
The user can always click into the fields in any order, whatever entry order
is set.
Summary
Even though 4D is a relational database you do not need to relate all, or
even any, of the tables. Tables can be used to store data that can be queried
from other tables as needed, without using 4D’s relational links. This
might seem to defeat the purpose of having a relational database, but in
some cases, this is an efficient way of managing data.
Typical tables that would be handled this way include zip and postal
codes, and product description tables. (You will see an example of this
later.)

6 – 12 Adding a Non-Related Table


Jumpstart 4D

Chapter 7 – Adding Related Tables

In this chapter you will learn how to:


+ Add more tables.
+ Create relations between these tables.
+ Add a tab object and a second page to the Contact table detail form.
+ Add a subform to the Contact table’s second page.
+ Create more methods.
So far you have built an application that manages your contacts. Now you
need to add additional functionality to allow invoices for your services to
be issued to these contacts. To do this, you will need at least two extra
tables:
+ Invoice table.
+ Invoice_Item table.
There is a one to many relationship between the Contact table and the
Invoice table: this means that for any single Contact record there could be
zero, one, or many Invoice records. The Contact table is known as the
parent of the Invoice table, and the Invoice table is known as the child (or
many table) of the Contact table. The Invoice table is a related many table
to the Contact table.
The Invoice_Item table is the many table to the Invoice table. There is a
one to many relationship between the Invoice table and the Invoice_Item
table: this means that for any single Invoice record there could be zero,
one, or many Invoice_Item records. The Invoice table is known as the
parent of the Invoice_Item table, and the Invoice_Item table is known as
the child of the Invoice table.
The relationship would look like this (the arrowhead points from the
many table to the one table):

Adding Related Tables 7–1


Jumpstart 4D

Figure 7-1: Table Relationships


Contact

Contact ID

Invoice

Contact ID
Invoice ID
Invoice Item

Invoice ID

This arrangement allows you to have:


+ Zero to many contact records.
+ Zero to many invoices for each contact.
+ Zero to many line items for each invoice.
This is a very flexible arrangement.
Each table needs a field which is common to the tables that it is related to.
This acts as a common link between them. This field is known as a key
field. A table might have more than one key field, each one linking to a
different table. Starting from the top of the relationship, the Contact
table, you will need a Contact ID that is unique to a contact record. This
is known as the primary key in the relationship. This ID must be unique
and should not be related to the data in any way, since the data could
change.
 A key must be based on data that is unique: zip codes and names are
out. Telephone numbers can change, so can names and even (if
unlikely) social security numbers (think about what happens when
you go into the Witness Protection Program). Therefore the only
safe key value is an arbitrary value. This is usually easiest to imple-
ment as a sequential number. This number has no meaning; it is
used only as a key to link the data. It should never change. (If it
needs to be changed, then you need to update all records linked to
the record that you are changing.)
The Invoice table then has a matching field for the Contact_ID known as
the foreign key. The Invoice table also has a primary key – the
Invoice_ID. This is used to manage the relation to the Invoice Item table,
which has a corresponding foreign key.
7–2 Adding Related Tables
Jumpstart 4D

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

Figure 7-3: Contact Table

Adding Related Tables 7–3


Jumpstart 4D

(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

+ Click on the Methods tab.


+ Expand the Form Methods & Triggers title.
+ Expand the Contact table title.
+ Double-click the Contact_dtl form name.
+ Leave Listing selected and click OK.
+ Type the following code:
If (Form event=On Load)
If ([Contact]Contact_ID=0)
[Contact]Contact_ID:=Sequence number([Contact])
End if
End if

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

Field Name Type Indexed

Contact_ID Longint Yes

Invoice_ID Longint Yes

Invoice_Date Date Yes

Due_Date Date Yes

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 -

Table 7-2: Invoice_Item Field Definitions

Field Name Type Indexed

Invoice_ID Longint Yes

Item_Number Longint Yes

Service_Code A20 No

Adding Related Tables 7–5


Jumpstart 4D

Table 7-2: Invoice_Item Field Definitions

Field Name Type Indexed

Service_Description A80 No

Hourly_Rate Real No

Number_of_Hours Real No

Extended_Price Real No

Your new tables should look like this:


Figure 7-5: Tables Viewed in Structure

Now you can create the relationships.


+ Click in the Contact_ID field in the Invoice table, hold the mouse
key down, and drag into the Contact_ID field in the Contact table.
Release the mouse button.
 The order in which you click and drag has significance in 4D! The
field you drag from is the foreign key – the key in the many table.
The field you drag to is the primary key – the one table.
The Relationship Properties dialog appears.

7–6 Adding Related Tables


Jumpstart 4D

Figure 7-6: Relationship Properties Dialog

+ Set the properties as shown.


+ Click Apply.
+ Click Done.
Repeat the process clicking and dragging from the Invoice_ID field in the
Invoice_Item table to the Invoice_ID field in the Invoice table. Set the
Relationship Properties as before. At any time you can double-click on a
relationship line between any two key fields. The Relationship Properties
dialog will be displayed and you can set the properties as you wish.
Auto assign related value in subform is an interesting and useful prop-
erty. If this property is selected it will copy the value from the [Con-
tact]Contact_ID field to the [Invoice]Contact_ID field, when the Invoice
record is created in a subform that is displayed on a Contact table form. It
saves you the trouble of having to add it in using code.

Adding Related Tables 7–7


Jumpstart 4D

Figure 7-7: Finalized Relationships

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

7–8 Adding Related Tables


Jumpstart 4D

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

You should make fields an appropriate width to display the maximum


value you expect that field to contain, including symbols and separators as
appropriate (the $ symbol for example).
To examine how each object’s properties are set double-click on objects in
the Form Editor in the supplied database.
The Invoice Detail Form
The next step is to create the detail form for the Invoice table. This form
will be used to display information from the Invoice table (such as the
billing address), and the invoice items from the Invoice_Item table (using
the subform). First create a input (detail) form with the fields from the
Invoice table:
Figure 7-10: Basic Invoice Input Form

+ Leave a blank area for the subform.


+ Position your fields as you wish.
+ Set the entry order.
+ Create the field labels.

7 – 10 Adding Related Tables


Jumpstart 4D

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:

Adding Related Tables 7 – 11


Jumpstart 4D

Figure 7-12: Subform in Position

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

7 – 12 Adding Related Tables


Jumpstart 4D

Modifying the Contact Form


You need to place the Invoice subform on the Contact input (detail)
form. The best way of doing this is to create a second page and place it
there. Then the contact’s data is on the first page, and the list (subform) of
invoices for that Contact is on the next page. You could add additional
pages to the Contact form later if needed.
4D forms support multiple pages:
+ Page 0 is the master page. Anything on this page appears on every
subsequent page.
+ Page 1 is the first normal page.
+ Pages 2 - n are optional, additional pages, and are added as required.
The easiest way to manage access to pages is by using the tab object.
+ Open the Contact detail form in the Form Editor.
+ Go to page 0. (The page selector is in the lower right-hand corner of
the form window. Select Page 0.)
Figure 7-14: Selecting Page 0

+ 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

+ Click the right-facing triangle in the upper right corner to display


more tabs for the Object Properties.
+ Click the Data Control tab.
Figure 7-17: Data Control Tab

+ Click Edit String… under Default Value:


+ Type the two values as shown:

7 – 14 Adding Related Tables


Jumpstart 4D

Figure 7-18: Default Tab Values

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.

Adding Related Tables 7 – 15


Jumpstart 4D

+ 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

+ Click OK to create a second page.


+ Drag and drop the Invoice subform onto this page, as you did
before.
Figure 7-22: Contact Second Page with Invoice Subform

7 – 16 Adding Related Tables


Jumpstart 4D

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.)

Adding Related Tables 7 – 17


Jumpstart 4D

The next step therefore is to add a couple of buttons to manage adding


(and deleting) records in the subform. In the subform you will add some
code to the form method to create some of the data automatically.
You will need to be in the Design Environment, viewing Page 2 of the
Contact Input form. First you need to create a button next to the sub-
form.
+ Drag and drop a button object onto the form next to the subform.
Figure 7-24: Button Object

+ Size the button, then set its properties as follows:


Figure 7-25: Button Properties

+ The button name is unimportant at this time.


+ The button action is essential.
+ The text can be anything you choose: “Add Invoice” for example, or
“+”.
+ Close the Object Properties dialog (or Property List palette).
Next you need to create a button to delete selected records from the sub-
form.
+ Click once on the button you just created to select it.
7 – 18 Adding Related Tables
Jumpstart 4D

+ Press Command+D (on Mac OS or Control+D on Windows). This


duplicates the object.
+ Double-click the object and modify its properties as follows:
Figure 7-26: Delete Button Properties

+ Buttons that work with automatic actions (such as adding/deleting


subrecords) must have different names from each other. (If two
automatic action buttons have the same name, even on different
pages of the same form, they can confuse each other, and you too.)
+ When you click this button it will delete the record in the subform
that is currently selected by you (you have the cursor in one of its
fields).
List the contacts in the Custom Menus Environment and double-click
any record. Click the Invoices tab.
+ If you have an invoice showing, click on it and click the Dlt button.
If not, click in the subform and click the Add button.
Again you have created an empty record.
+ Double-click this record and note what happens.
Since you have no buttons on this form, 4D will display a set of standard
buttons to the side. You can use these to manage the record (but thank-
fully you’ll be adding some nice buttons of your own shortly).
When you create a record in a subform it would be useful if you could
complete some of the fields automatically. This is an ideal use for Form
Methods.

Adding Related Tables 7 – 19


Jumpstart 4D

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 Sequence number command acts like a record counter, each


time a new record is added and saved, it is incremented by one (for
that table). This is a simple way to manage invoice numbers.
+ You do not need to create a value for the Contact_ID field in the
Invoice table: the table relations you defined previously manage this
automatically, as long as the Invoice record is created in a subform.
+ Current date returns the date as determined by the computer’s sys-
tem clock.
+ The Due_Date is calculated from the Invoice date.
+ The remainder of the fields are copied over.
A common question is: “Why are the address fields from the Contact table
copied over to the Invoice table?” Consider the following scenario: Com-
pany ABC is based in Portland, Oregon. They buy goods from you several
times. They move to Seattle (for the climate) and buy again. They request
copies of their old Portland invoices for an audit.
If you had not copied the address over to the invoice file, when you
reprinted the invoices they would show the current address from the Con-
tact table, not the address to which the goods had actually shipped. You
copy this type of data over as a snapshot of the data as it was at that time.
Your invoice subform will look something like this, after you have added
an invoice or two to the Contact (remember to click in the subform before
clicking the Add button):
Figure 7-27: Invoice Subform

+ Note how the Invoice numbers increment.


+ The Invoice Date is set to the date the record was created.

Adding Related Tables 7 – 21


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

Double-click the first button to display the Object Properties dialog or


the Property List. Set the properties as follows (from top to bottom but-
ton):
Figure 7-29: Cancel Button

Figure 7-30: Save Button

Adding Related Tables 7 – 23


Jumpstart 4D

Figure 7-31: Print Button

+ Note that the Print button has a No Action set.


+ Once the Object Properties dialog or the Property List is open,
you can click on objects in turn to display their properties. You do
not need to keep double-clicking on each object.
Figure 7-32: Your Three Buttons

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.

7 – 24 Adding Related Tables


Jumpstart 4D

+ A final refinement is to add text labels for the automatically calcu-


lated subtotal and tax fields.
A quick way of adding multiple text labels is to create the first using the
text tool from the Tool Palette. Double-click it, and edit its properties
using either the Object Properties dialog or the Tool Palette. Then
duplicate it (Command+D on Mac OS or Control+D on Windows).
Drag the duplicate into the correct position. Then type Command+D (on
Mac OS or Control+D on Windows) again. A third duplicate will appear,
offset from the second by the relative difference between the first and sec-
ond buttons. That is, if the second duplicate was positioned 20 pixels
down from the first by duplication, the third duplicate will be 20 pixels
down from the second, and so on.
You can then tweak the text labels into position, or use the alignment tools
on the Tool Palette. (Hint: Use the left alignment tool to align the text
labels along their left edges.) The alignment tool icons are only enabled if
more than one object is selected (since you need at least two objects to
align).
If you select more than one object, and then click an alignment icon, the
objects are aligned according to the following rules:
+ Left alignment aligns all objects to the leftmost edge of the leftmost
object of the selected objects.
+ Right alignment aligns all objects to the rightmost edge of the right-
most object of the selected objects.
+ Top alignment aligns all objects to the uppermost edge of the high-
est object of the selected objects.
+ Bottom alignment aligns all objects to the lowermost edge of the
lowest object of the selected objects.
+ Center alignment aligns all objects to the center of the object nearest
the center of the selected objects.
When you are finished your form should look something like this:

Adding Related Tables 7 – 25


Jumpstart 4D

Figure 7-33: Completed Invoice Form

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

Making the Line Items Work


As you add line items to the invoice it would be useful to have some of the
fields auto-complete, and the totals automatically update. Most of this will
take place in the Invoice_Item subform fields. These tasks will be handled
by Object Methods.

7 – 26 Adding Related Tables


Jumpstart 4D

+ Open the Invoice_Item subform in the Form Editor.


+ Make the Item_Number field non-enterable.
+ Create an Object Method for the Item_Number field.
(Option+Click (on Mac OS or Alt+Click on Windows), then select
Listing Method.)
+ Type the following code into the method window:
If ([Invoice_Item]Item_Number=0)
Item_Number:=Records in selection([Invoice_Item])
End if

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

+ Make the Extended_Price field non-enterable.


This works as follows: whenever you type a value into either of the two
fields (Number_of_Hours or Hourly_Rate) the object method will exe-
cute when you click or tab out of the field. This way you can change either
of the values at any time, and the extended price will be recalculated.
Now, wouldn’t it be useful if the totals were calculated as well?
An easy way to manage this is to recalculate them as the extended price is
calculated. Therefore you could perform this calculation after updating
the extended price:
+ Open the method in the Method Editor (Command+P on Mac OS
or Control+P on Windows).
+ Add the following lines of code:
[Invoice]Invoice_Subtotal:=Sum([Invoice_Item]Extended_Price)
[Invoice]Invoice_Sales_Tax:=[Invoice]Invoice_Subtotal*0.0725
[Invoice]Invoice_Total:=[Invoice]Invoice_Subtotal+[Invoice]Inv
oice_Sales_Tax
[Invoice]Amount_Due:=[Invoice]Invoice_Total-[Invoice]Paid

After each extended price is calculated, the subtotal is calculated as the


sum of all Extended_Price values in the current selection of the
Invoice_Item table. Since 4D is managing the current selection, the cur-
rent selection comprises all line items belonging to this invoice. Sales tax is
calculated as 7.25 percent of the subtotal.
The total is calculated as the subtotal plus the sales tax amount. Finally,
the amount due is calculated from the amount paid and the invoice total.
If you also make tax-exempt sales, you might want to put the value for the
sales tax rate into a variable on the invoice form, or into a field on the
invoice form. Then you could change the rate to 0% for tax-exempt sales.
A typical invoice might look like this:

7 – 28 Adding Related Tables


Jumpstart 4D

Figure 7-35: Typical Invoice

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

+ The $ symbol will precede every value.


+ Commas will separate thousands.
Adding Related Tables 7 – 29
Jumpstart 4D

+ There will always be two places displayed after the decimal.


+ Negative values will be displayed in parentheses.
You can experiment with these formats. Once a format is selected it is cop-
ied to the field below the drop-down. Here you can edit the values.
+ Deselect the [Invoice]Paid field. (Shift+Click on it.)
+ Switch to the Field tab in the Object Properties dialog.
+ Deselect Enterable (this applies to all the remaining fields).
Next you can create an object method that will deduct the amount paid
from the total to calculate the remaining amount due, if any.
+ Create an Object Method for the [Invoice]Paid field. Type the fol-
lowing code:
[Invoice]Amount_Due:=[Invoice]Invoice_Total-[Invoice]Paid

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.

7 – 30 Adding Related Tables


Jumpstart 4D

+ 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

Adding Related Tables 7 – 31


Jumpstart 4D

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

Field Name Type Indexed

Service_Code Alpha 20 Yes

Service_Description Alpha 80 No

Hourly_Rate Real No

+ Create an input form for the table:


Figure 7-38: SRVC_DTL Form

Create a list form for the table:


Figure 7-39: SRVC_lst Form

You can examine the list form in detail in the sample database.

7 – 32 Adding Related Tables


Jumpstart 4D

+ Create an additional menu to Add and List Service items:


Figure 7-40: Service Menu

Create two new Project Methods:


SRVC_Add Project Method
Repeat
ADD RECORD([Service])
Until (ok=0)

SRVC_List Project Method


ALL RECORDS([Service])
ORDER BY([Service];[Service]Service_Description;>)
MODIFY SELECTION([Service])

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

Adding Related Tables 7 – 33


Jumpstart 4D

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.

7 – 34 Adding Related Tables


Jumpstart 4D

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

Figure 8-1: Password Editor

+ Double-click the Designer icon/name.


Figure 8-2: Editing The User

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

+ Click the Edit… button to create a password for the Designer.


+ Enter your password:
Figure 8-3: Entering a Password

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

Figure 8-4: Database Properties: Access Control

+ Deselect Allow 4D Open Connections (unless you specifically need


them).
If Display User List in Password Dialog Box is selected, 4D will dis-
play all the names of the users in a dialog when the database is first
opened. A user can select their name from the list, then type in their pass-
word. This makes it easier for the user, but also easier for the hacker. With
the names already provided in the list, the hacker has to guess only half the
login information. If this option is not selected the user will have to type
both their user name and password, and of course get both correct. Some
users may not like all that extra effort.
User List in Alphabetical Order sorts the users names into alphabeti-
cal order (rather than creation order) when they are displayed on the login
dialog.
Creating Groups
Before you create any groups you will need to create a few new users. Cre-
ate the following users:

Passwords 8–5
Jumpstart 4D

Figure 8-5: Users

You can select Passwords ¬ New User, or Command+N (on Mac OS


or Control+N on Windows) to create each user. (These users do not have
any password assigned.)
Now you can create two new groups:
Select Passwords ¬ New group.
Figure 8-6: New Group Dialog

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

(The highlighted names have no significance at this point.)


To assign a user to a group, drag and drop his or her name from the
Users... list onto the name of the group in the Groups… list. This
makes that user a member of that group.
The scrollable area below the Groups… list, lists the members of the cur-
rently selected group. In this case Joe Soap has been made a member of the
Manager group, and Mary and José have been made members of the Sales
group.
Figure 8-8: Assigning a User to a Group

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

+ Select your user name.


Passwords 8–7
Jumpstart 4D

+ 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

Chapter 9 – Refining Your Application

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.

Refining Your Application 9–1


Jumpstart 4D

Figure 9-1: Explorer Dialog: Methods Tab

+ On Mac OS click the disclosure triangle to the left of Database


Methods.
+ On Windows click the + symbol to expand the Database Methods
heading.
Figure 9-2: Explorer Window: Database Methods Listed

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.

+ Leave Listing selected (as always) and click OK.


9–2 Refining Your Application
Jumpstart 4D

+ Type the following code: Startup


+ Next create a new project method:
- Command+M (on Mac OS or Control+M on Windows).
+ Type Startup as the method name.
+ Type the following line of code:
SET WINDOW TITLE("Jumpstart My Contacts") `Insert your title
between the quotes
+ Close the Startup project method window, then close the database
method window.
That is all there is to it.
When the database is opened, 4D will execute any code in the On Star-
tup database method. This comprises a single call to the project method
named Startup. For now this method executes a single line of code which
sets the application’s splash screen title to Jumpstart My Contacts (or
whatever you chose to name it). If you are feeling adventurous, you could
add the users login name, date and other text to the title. Examine the
effect of the following code:
SET WINDOW TITLE (Current user+": Jumpstart My Contacts
"+String(Current date;4))

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

Refining Your Application 9–3


Jumpstart 4D

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))

The diamond symbol preceding the variable name indicates to 4D that


this is an interprocess variable. (Later if you decide to add multiple pro-
cesses to the database these variables will work in any process. This is not
necessary for this simple, single-process application, but allows for future
expansion.)
+ On Mac OS, the diamond symbol is Option+Shift+v
+ On Windows, use <> (less than symbol and greater than symbols).
Your code will now assume that your screen is 875 pixels wide by 615
high. You can change these values to suit your PC’s actual screen resolu-
tion. (iMac and iBook screens are 800 by 600 for example.) If you reduce
the width of your windows, you may have to move some of the objects to
fit.
Next create a project method called WND_Input. Type the following
code:
Open window(6;47;◊ScreenWidth;◊ScreenHeight;5;"";"WND_Cls")

9–4 Refining Your Application


Jumpstart 4D

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")

This is the same as the WND_Input method.


Now you need to modify the two project methods that add and list your
Contact records.
Open the CNT_Add project method, and insert the following line:
WND_Input

You code should now look like this:


WND_Input
Repeat
ADD RECORD ([Contact])
Until (ok=0)

Open the CNT_List method and modify the code to read:


ALL RECORDS ([Contact])
ORDER
BY([Contact];[Contact]Company_Name;>;[Contact]Last_Name;>;[Con
tact]First_Name;>)
WND_List `This line inserted here!
MODIFY SELECTION ([Contact])

Open the CNT_Find method and modify the code to read:


QUERY ([Contact])
If (ok=1)
WND_List
MODIFY SELECTION ([Contact];*) ` Note the added * character
End if
Refining Your Application 9–5
Jumpstart 4D

The optional * character added to the MODIFY SELECTION command


has the following effect: if absent and the query only returns one record,
the record will be displayed using the default input form. If present (as
here) the single record will be displayed in the default list form.
Modify CNT_FindQuick as follows:
WND_Cntr (400;200;5;"Find Contacts";"WND_Cls")
DIALOG([Contact];"Contact_QuickFind")
CLOSE WINDOW
If (ok=1)
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)
: (rbtn_State=1)
QUERY ([Contact];[Contact]State=text_SearchValue)
End case
WND_List
MODIFY SELECTION ([Contact];*)
End if

Modify SRVC_Add:
WND_Input
Repeat
ADD RECORD ([Service])
Until (ok=0)

Finally modify SRVC_List:


ALL RECORDS ([Service])
ORDER BY ([Service];[Service]Service_Description;>)
WND_List
MODIFY SELECTION ([Service];*)

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

9–6 Refining Your Application


Jumpstart 4D

value of the two interprocess variables). Another way is to execute the


Startup method from the User Environment: press Command+E (on
Mac OS or Control+E on Windows), then select the Startup method
from the displayed list of project methods.
This is one good reason for placing startup code in a project method – you
can execute it from the User Environment. It is also a good reason for
keeping users out of the User Environment.
The next task is to set the window title to something meaningful. This will
differ between input (detail) forms and list forms.
List form titles
You are going to set the title in the form method for the Contact_lst
form. By doing this here it does not matter where the form is called from:
your title will always be set correctly. One way of creating or editing the
form method is to use the Explorer. Click the Methods tab, then expand
Form Methods & Triggers.
Figure 9-3: Explorer Dialog: Methods Tab

+ Double-click Contact_lst, leave Listing selected and click OK.


+ Type the following code:
If (Form event=On Load)
CNT_Title_List
End if
+ Create a project method called CNT_Title_List. Type the following
code:

Refining Your Application 9–7


Jumpstart 4D

SET WINDOW TITLE("Contacts: "+String(Records in


selection([Contact]))+" of "+String(Records in table
([Contact])))

(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

+ Click on Contact and then click Add Menu.


+ Name the Menu Invoice.
Refining Your Application 9–9
Jumpstart 4D

+ Click Add Item and name it Sales YTD.


+ Type INV_SalesYTD in the Method Name field.
+ Press Return, this assigns that method name to the menu item).
+ Create a project method with this name (Hint: Use copy and paste.)
+ Type the following code:
$YearAsString:=Request("Enter a year for your YTD
total";(String (Year of (Current date))))
If (ok=1)
$DateFrom:=Date("01/01/"+$YearAsString)
$DateTo:=Date("12/31/"+$YearAsString)
QUERY ([Invoice];[Invoice]Invoice_Date>=$DateFrom;*)
QUERY ([Invoice]; & ;[Invoice]Invoice_Date<=$DateTo)
$SalesYTD:=Sum([Invoice]Invoice_Total)
ALERT("Your sales year to date are
"+String($SalesYTD;"$#,###,###.00"))
End if

Looking at the code line by line:


$YearAsString:=Request("Enter a year for your YTD
total";(String (Year of (Current date))))

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"))

Refining Your Application 9 – 11


Jumpstart 4D

 Local variables (those whose name is preceded by a $ symbol) can-


not be displayed on a dialog, but can be passed to an alert dialog.
You must use process or interprocess variables on any other type of
dialog. In that case, change the name of the variable from $Sale-
sYTD to SalesYTD.
The code above displays an Alert dialog like this (depending on the value
of invoices in your database):
Figure 9-6: Alert Dialog with Results

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.

9 – 12 Refining Your Application


Jumpstart 4D

+ Create a Form Method with the following code:


INV_Title_List
+ Create the Project Method INV_Title_List with the following code:
If (Form event=On Load)
SET WINDOW TITLE("Invoices: "+String(Records in
selection([Invoice]))+" of "+String(Records in table
([Invoice]))) ` This line typed as one long line
End if

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?

Refining Your Application 9 – 15


Jumpstart 4D

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.

9 – 16 Refining Your Application


Jumpstart 4D

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")

Here’s what the code does, line by line:


Refining Your Application 9 – 17
Jumpstart 4D

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 next command is very important. To explain why it is necessary, you


first need to understand an important concept in 4D – Automatic Rela-
tions.
Say you have two tables in a database: Contact and Invoice. The Invoice
table is related as the many table (child) of the Contact table (parent). You
create a detail form for the Contact table that uses a subform to display
9 – 18 Refining Your Application
Jumpstart 4D

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 End for function ends the loop.


End for

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

Refining Your Application 9 – 21


Jumpstart 4D

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.

9 – 22 Refining Your Application


Jumpstart 4D

Chapter 10 – Compiling a 4D Application

4D databases are developed in what is known as interpreted mode. This is


what you have been doing so far, you just didn’t know it. This allows the
flexibility of creating code and testing it on-the-fly. That is, you can make
changes to the database, switch to the User Environment or the Custom
Menus Environment, and test your code immediately. If the changes are
not satisfactory, you can switch back into the Design Environment and
change your code.
Most programming languages like C and C++ are not used in this way. In
these languages you write your code using a text editor. This creates what
is known as the source code. When you have finished, you use a compiler
to take the code and compile it (along with forms and other program
resources) into a usable program. You are often not aware of any errors in
your code until the compiler finds them. Most of the program editors used
to create the source code do not detect errors.
4D applications can be compiled at any time in the development process
(although you must quit 4D/4D Server before compiling). It is a good
practice to treat all your databases as though they will be compiled at some
time in the future. If you wait until the database is finished, you may have
accumulated hundreds of unnoticed errors.
Compiling serves several purposes:
+ Compiled applications will normally run faster than interpreted
applications.
+ Compiled applications cannot be edited. This prevents others from
seeing or modifying your code. The compiled code is also known as
the object code.
- The compiled application is a copy of your interpreted data-
base. The interpreted code (also known as the source code) is
kept so you can still work on the original.
+ Compiling checks various aspects of your code and alerts you to
some programming errors (however it cannot correct faulty logic ).
- 4D’s programming language has a syntax (like other written
languages such as English or French) that must be followed for

Compiling a 4D Application 10 – 1
Jumpstart 4D

the program to work correctly. The compiler will check the


syntax of all your methods and alert you to any errors.
In this chapter you will learn how to:
+ Add Compiler Declarations to your database.
+ Compile your database.
+ Fix any errors.
+ Create a Compiler Project.
Preparing a Database for Compilation
A simple database may need no preparation for compiling. In interpreted
mode, 4D is often able to second guess what you intended, rather than
what you typed. Consider the following piece of code:
$Result:=Int($SomeValue

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

When 4D is running in the interpreted mode it is very forgiving of data


type mismatches, and where you have not specifically declared the data
type it will make a best guess. Usually 4D errs on the side of caution and
allocates the widest data type (known as scope). This allows for the largest
range of values. Look at the following code snippet:
$SomeNum:=13

4D will treat this internally as a Real number (uses 8 bytes of RAM),


since this is the most flexible data type for numbers. You may have
intended that this value be an integer (uses 2 bytes of RAM) or long inte-
ger (uses 4 bytes of RAM). To force 4D to treat it as either of these, you
must use a compiler declaration.
Compiler declarations
There is a matching compiler declaration for each field type (a field’s data
type is assigned when you created it in the structure editor):
C_Boolean
C_String
C_Date
C_Time
C_Picture
C_Blob
C_Real
C_Integer
C_Longint

You can declare multiple variables with a single compiler declaration:


C_Boolean($Male;$Mineral;$IsNew) ` 4D is not case sensitive
C_String(20;$Name;City)
C_String(255;$PathName)
+ Note that string variables can be up to 255 characters in length,
whereas string fields are limited to 80 characters.
+ String variables of different lengths must be declared separately.
If you attempt to assign a string to another string of shorter length, you
may not get the results you expect. Making sure that string lengths match
either the fields that they are loaded from, or the string variables that they
are assigned to, can be a daunting task in a complex application. Therefore
Compiling a 4D Application 10 – 3
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…

 It is also not recommended to use process variable names that have


the same names as 4D functions, for example Date as above.
If you frequently need to use a variable with a similar name, consider
using a prefix to differentiate between them:
C_Boolean(bln_Date) ` In one method
C_Date(date_Date) ` Then in another method

and even better:


C_Boolean(bln_InvoiceHasDate) ` In one method
C_Date(date_InvoiceDate) ` Then in another method

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

Figure 10-2: Naming Your Compiled Database

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

application. This is an application that can be launched by double-click-


ing it, it does not require the presence of 4D on the users computer.
Before using this option, you must install 4D Engine on your hard disk.
This is a separately licensed program from 4D, Inc.
This is covered in more detail in Chapter 16 “Deploying Your 4D Data-
base”.
Symbol Table
You can use this option to generate a text file that contains the symbol
table of your database. This file contains information about all the objects
in the database that is being compiled. It includes information about pro-
cess variables, interprocess variables, local variables, their data types, and
the name of the method from which the data type was determined.
The symbol table also includes a list of your methods and functions, the
data types of their parameters, and for functions, the data type of the value
returned.
This data can be useful to more experienced programmers: 4D Insider
(covered in a later chapter) displays this data in a much more useful for-
mat, and has other capabilities.
PowerPC
When you compile with this option set, your compiled database is fully
optimized for Power Macintosh. 4D Compiler generates native PPC code
which can be executed by a PPC-compatible (PPC native or FAT) 4D, 4D
Client, or 4D Engine. The whole 4D environment will operate at Power
Macintosh speed.
Windows
If you are compiling for a PC with a 386 or 486 processor, choose the
386/486 option. If the target machine is a Pentium, choose the Pentium
optimized option.
If your compiled database will be used with 4D Server and a mixture of
PC clients, you must choose the most powerful compiler option. (If you
have both Pentium and 486 clients, choose Pentium.)

10 – 8 Compiling a 4D Application
Jumpstart 4D

 A database compiled with the Pentium option will work on a 386/


486 based machine.
The More… Button
Clicking the More… button takes you to a second page where further
options can be set.
Optimization
+ The Normal generator allows you to compile quickly and generates
non-optimized code. This is useful for quickly identifying errors in
your code.
+ The Optimized generator produces better optimized and more
compact code. This process of generating the code takes more time,
but database execution is slightly faster.
In practice, on modern computers, there is little difference in speed
between the two options.
Initialize local variables
This option gives you three choices. The default setting is set to “zero” and
is the option you should choose if you have not already taken steps to
make sure you have initialized all the local variables. The other two set-
tings are available if you want to optimize the database performance.
When a method executes, space for the local variables is reserved in mem-
ory. These local variables are cleared at the end of the method.
While a method executes, the behavior of the compiled code depends on
one of these three settings. If you set the Initialize Local Variables option
to:
+ Zero: Instructs 4D Compiler to create the local variables and ini-
tialize each variable to a null value (empty strings of characters, 0 for
numbers).
+ No: Instructs 4D Compiler to create the variables and not initialize
them. If your code initializes the variables correctly, this option opti-
mizes database execution. The method runs faster, because the com-
piler does not initialize the variables.
+ to a random value: Instructs 4D Compiler to create the variables
and initialize them to a random value. These intentionally induced
Compiling a 4D Application 10 – 9
Jumpstart 4D

“bugs” should cause unexpected or erratic behavior as the database


executes, allowing you to identify the local variables that you may
have forgotten to initialize. Use this setting during the development
stages of the database. You might use this when debugging – never
use it on the final compilation. For the final compilation of a data-
base, use the Zero or No setting.
Typing file
If you select this option, 4D will display an OS-specific dialog to specify
the name and location of the typing file. This file contains the compiler
directives that declare all the variables. To use these declarations in your
database, you can copy the compiler directives into one or more project
methods.
Compilation path
If you watch the compilation process you will notice that there are three
initial passes through the database as 4D attempts to deduce the variable
type for any variables which do not have compiler declarations.
By setting the compilation path you can eliminate these passes, assuming
that you have already typed all of the corresponding variable types using
compiler declarations. There are three possible settings:
+ Type the variables: 4D Compiler deduces the types of all vari-
ables that have not been explicitly declared. For beginners this is the
best option to set.
+ Process and interprocess have been typed: This option is
appropriate if all process and interprocess variables have been typed.
This can be done either by the developer or by pasting the contents
of the typing file into a method. If this option is selected, 4D Com-
piler accelerates compilation by skipping the typing phases. Compi-
lation consists of copying the database, the compilation pass, and
generating the files.
+ All variables have been typed: Use this option if all of your
process, interprocess, and local variables have been typed. With this
option, compilation is much faster, but has no effect on the code
generated.
Changing the compilation path options in 4D Compiler enables you to
save time during compilation. However, be careful when changing the
10 – 10 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

*** General errors ***

The type of END is unknown

10 – 12 Compiling a 4D Application
Jumpstart 4D

This variable is used in the method (M) CHCK_Acct_Prt

(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

When you open a 4D application in interpreted mode if there is an error


file that is not in use by another application in the same folder, 4D will
open the error file and add two new menu items to the Use menu:

Compiling a 4D Application 10 – 13
Jumpstart 4D

Figure 10-4: Modified Use Menu

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

Figure 10-6: Saving a Compiler Project

Double-clicking the project file in the finder/desktop will launch 4D


Compiler and set the previously selected options for this database, as long
as the database name and location have not changed.

10 – 16 Compiling a 4D Application
Jumpstart 4D

Chapter 11 – 4D Server

4D Server is the client/server version of 4D. (Database purists argue that


4D Server is not a true client/server database, but for most users it behaves
like one.)
4D Server stores your application (database) and data file on one com-
puter (the server) and allows many people to access the application and
data over a network from their computers (both the users and their com-
puters are known as clients).
4D Server runs on both Macintosh and Windows computers, and so does
4D Client. You can mix and match combinations – you can have a mix-
ture of Mac/Windows clients with 4D Server running on either platform.
Since 4D Server is also a Web server you can also connect with a Web
browser if the database is set up to be Web served.
4D Server allows multiple clients to connect to the single database simul-
taneously. 4D Server automatically handles many multi-user issues, such
as two people trying to change the same record. Other issues you may
wish to handle programatically (more on this topic later).
4D Server consists of two parts:
+ 4D Server
+ 4D Client
In this chapter you will learn:
+ How to install applications on the server for client/server use.
+ How to update your application.
+ How to cope with issues that arise in multi-user applications.
+ How to develop a database using 4D Server.
The Scenario
Imagine that you run a small, mail-order nursery that has decided to com-
puterize its sales operations. You have a staff of ten: an office manager, five
people in sales, two in shipping, one in customer service (returns, credits)
and an accounts clerk. You have developed the database program yourself,
at home, using 4D. It’s all tested and ready to use. You have imported your
4D Server 11 – 1
Jumpstart 4D

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

Install 4D Server on your server computer


Delete unnecessary software from the server computer, run disk utilities to
check the integrity of your hard drive and defragment it if possible. You
should make sure that the server is 100% operational and you have no
disk errors of any kind before starting installation. Do not run other soft-
ware such as mail servers on the 4D server computer unless you want poor
performance.
Install 4D server on your server computer using the current installer. (See
your 4D Documentation for how to do this.) You may also need to install
network components where necessary: ADSP for Mac only networks,
TCP/IP for mixed Mac and Windows networks and IPX/SPX on Win-
dows only (if you use IPX rather than TCP/IP.)
On Mac OS set the memory allocation in the Finder. A good starting
point might be the preferred memory size plus twice the database applica-
tion size in MB.
Copy your database application and data file onto the server computer
then launch 4D Server and open your database when prompted.
 On Windows you use the File ¬ Database Properties… menu
in 4D Server to set the application RAM (to the same values as you
would a Mac OS server). On Windows memory is set in blocks: say
the memory requirement was 35 MB, you might round that to 9-10
blocks of 4 MB, or 5 blocks of 8 MB.
Now you can add the additional client connections. Select File ¬
Update License… to display the license number entry dialog.

4D Server 11 – 3
Jumpstart 4D

Figure 11-1: License Number Entry Dialog

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

Figure 11-2: Mac OS ADSP Default Server Connection Dialog

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

Figure 11-4: Mac OS TCP Connection Dialog

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

As each command is explained in the 4D PDF documentation, there are


notes when a difference exists between the behavior on 4D and 4D Server.
The 4D Server documents also contain notes about the operations of trig-
gers, sets, and other operations that are specific to 4D Server.
Developing a Database Using 4D Server
You can also use 4D Server to develop applications using more than one
programmer. It is especially useful when developing cross-platform appli-
cations since you could have some programmers use Macintosh clients
and others use Windows (or even Virtual PC running Windows on a
Mac).
Objects are locked in the same way as records. If one user opens a form he
she own it, and it is locked to other users until closed by the person who
opened it. (This is one reason for calling project methods from forms and
form objects: since they are separate objects they can still be edited even
though their parent form is locked.)
If you are going to compile a database that is being developed on 4D
Server, you must quit 4D Server first (after quitting all 4D Clients) to
ensure that all changes that have been made by the client have been
flushed to disk by the server.

4D Server 11 – 9
Jumpstart 4D

11 – 10 4D Server
Jumpstart 4D

Chapter 12 – 4D Insider

4D Insider is a developer (rather than a user) tool that works with 4D


databases.
+ 4D Insider allows you to cross-reference objects in your databases.
You can select any database object, a table, form, method, variable,
or menu bar and view the object’s relationship to other objects in the
database. i.e. which other project methods call a particular project
method.
+ You can also view the contents of the objects. For example in the
case of forms, you can see all the objects on the form. In the case of a
method, you can view its code.
+ You can rename many types of objects (but not tables and fields, for
example).
+ You can also create and edit STR# resources which are used to local-
ize text labels for menus, buttons and static text into other lan-
guages.
+ You can use 4D Insider to copy objects from one database, or 4D
Insider library, to another database.
- A library is a special file that you can create using 4D Insider
to store objects commonly used in your databases.
- You can reuse objects in other databases. You can also modify
the objects in one database and then update all databases that
use these objects.
+ With 4D Insider v6.7 (and higher) you can create components that
can be used in other databases. Components are similar to libraries,
but can be protected so that other programmers cannot see or mod-
ify their content.
Using 4D Insider to Improve an Application
While developing a professional software application, there are several
steps you can take to make future maintenance and updating easier (and
therefore save time and money as well).
+ You can implement and enforce object naming conventions. This
offers many advantages:
4D Insider 12 – 1
Jumpstart 4D

- 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

smaller on Windows. A 12pt font looks like 9pt and so on. 4D


v6.7 supports cross-platform style sheets that allow the use of
different fonts, at different sizes, dependent on the platform
used but other objects such as buttons will still appear at the
wrong sizes.
Using 4D Insider to enforce naming conventions
There is no definitive way to name an object. A naming convention that
suits one developer may not suit another. What is important is to create a
standard, and document it so that all developers understand it, and ensure
that it is used consistently. There will often be infractions, or perhaps a
change in the standard. 4D Insider can help here by allowing you to
rename objects as needed.
Table and field names cannot be modified using 4D Insider. However,
when they are changed in the structure the names are updated in all other
objects. The exception to this are any objects, such as project methods,
that are open when the table or field name is changed. These will be
updated the next time the object is opened. If you retokenize the open
method (Command+Enter on Mac OS or Control+Enter on Windows)
the table or field names will be flagged as unrecognized (marked with bul-
lets), and the changes will not be recognized when the method is open
again. It is best therefore to close all objects before modifying structure
names.
Renaming database objects
Insider allows you to rename the following types of objects:
Formats and Filters
Forms
Groups
Lists
Named Selections
Picture Library graphics
Project Methods
Semaphores
Sets
Style sheets
Tables
4D Insider 12 – 3
Jumpstart 4D

Tips and Balloon Help


Variables

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

+ Select an existing method by clicking its name in the list, or by typ-


ing the first few characters of its name. Alternatively, you can create
a new project method by typing its name in the text box below the
project method list.The project method name appears in the text
box below the project method list.
+ If you are using an existing project method, click Replace. If you
are creating a new project method, click Create and Replace.
This is a very useful way to create wrappers around code. For example,
you may decide to replace 4D’s ALERT dialog with a custom dialog of
your own. You can create your own project method App_Alert and
replace every call to 4D’s ALERT command with a call to App_Alert.
Groups
4D Insider helps to support the development of modular code by allowing
you to organize design objects into libraries and groups. Using groups, you
can reorganize objects according to their function.This reorganization can
help simplify structures viewed within 4D Insider. Note that the groups
cannot be viewed within 4D or 4D Server.
Groups organize objects within a structure or library based on object func-
tionality. When you group objects together, they are moved into a folder
whose name is the same as that of the group. For each database or library,
you can create as many groups as you want. Within groups, you can create
as many levels of subgroups as you want. Insider considers a group to be a
type of object. Unlike libraries, the purpose of a group is not to duplicate
objects in your database, but rather to reorganize objects into folders
according to their functions.You can use groups to:
+ Clarify the organization of a database.
+ Make it easier to move objects associated with a particular aspect of
your database’s functionality.
Creating a Group from a Selection
To create a group containing the objects in a selection:
+ Select the objects in the main list.
+ Choose Tools ¬ Group Selection. A dialog box appears, allowing
you to enter the name of the group.
+ Type the name of the group and click OK.

4D Insider 12 – 5
Jumpstart 4D

Creating a group with dependencies


You can group objects with their dependencies — that is, with the objects
they use. In this case, the group created by 4D Insider contains the
selected objects and the objects that they use.
+ Select the objects in the Main list.
+ Choose Group With Dependencies from the Tools menu. A dia-
log box appears, enabling you to enter the name of the group.
+ Type the name of the group and click OK. The group, containing
the selected objects and the objects they use, is added to the Main
list.
Performing operations on objects in groups
4D Insider treats objects contained in groups as it does all other objects.
You can perform any operation on grouped objects. When you perform a
search, some of the objects meeting the criteria of the search may be
located inside a group. In this case, the list produced by the search will
contain the name of the group, but not those of the matching objects
inside the group. If you open the group, only the items in the group that
match the search criteria will be displayed.
Ungrouping/deleting a group
You can delete a group at any time. When you ungroup an existing group,
the Group object is removed from your list and the objects that it con-
tained are returned to the normal database or library object list. To delete a
group:
+ Select the group that you want to remove.
+ Choose the Ungroup command in the Tools menu.
Unused Objects
Unused objects are objects that are not used by anything in the database.
For example, an unused method is one that is not executed at start-up or
called by another method. Unused objects appear in red on a color moni-
tor, in grey on a grey-scale monitor, and in bold on a black and white
monitor.
There are three cases in which Insider does not recognize an object in a
method or object method:
12 – 6 4D Insider
Jumpstart 4D

+ An object is not recognized if its value depends on method execu-


tion. For example, the following statement builds a form name:
INPUT FORM ("MyForm"+"_Input")
+ An object is not recognized if it is a parameter to a user-defined
method, rather than to a 4D command or function.
+ Methods called within EXECUTE statements.
Prefixing Unused Objects
You can prefix any unused objects with “x_”. 4D Insider cannot delete any
kind of object, but you can later open the database with 4D or 4D Server
and delete these prefixed objects (which will be displayed adjacent to each
other because of the prefix).
Documentation
4D Insider allows you to document most of the objects contained in a
structure or library. This documentation is saved in the structure of the
database. The types of objects that you can document include:
Fields
Forms
Groups
Menu bars
Menus
Methods (database, form, object, project, and trigger)
Plug-ins/plug-in commands
Tables

This documentation can either be entered and edited within 4D Insider


or from the Explorer within 4D. It does not affect 4D method comments.
General
You can create documentation containing a general description of a struc-
ture or library. The window that appears is identical to that used for the
documentation of objects, except that it does not contain the Delimiter
Object check box or the date of the last modification. The text can be
styled.

4D Insider 12 – 7
Jumpstart 4D

Viewing the date of the last modification


The date that appears in the documentation window refers to the date on
which the object was last modified in the Design Environment of 4D or
4D Server. For example, for a project method, the date indicates when the
lines of code were last modified. Bear in mind that the date is not updated
when you modify the documentation of an object. It is only updated
when you modify the object’s contents.
If your database has been converted from one version of 4D to a later one,
the date of the last modification of the objects corresponds to the date on
which the structure was converted (if the objects have not been modified
since that date).
Printing documentation
You can print and export documentation in the form of text files. This can
be used to create programmer or user documentation.
Plug-in Commands Comments
When creating documentation for a plug-in command (e.g., for plug-ins
such as 4D Write, 4D Calc, etc.), the information that you type will auto-
matically be placed into the comments portion of the plug-in command.
If a plug-in command contains information in the comments area, you
can view it by selecting the plug-in command and choosing Edit Docu-
mentation from within Insider.

Copying Objects from One Database to Another


4D Insider enables you to copy objects from one database or library to
another. Copying objects with 4D Insider provides an easy way to reuse
objects that you have already created in other databases. 4D Insider does
not limit you to copying individual objects. You can copy an object and its
dependencies (the objects that it uses). By copying an object with its
dependencies, you can copy an entire segment of a database’s functional-
ity. (Note that the 4D Insider documentation refers to this process as mov-
ing, however, strictly speaking it is a copy since the original object is left in
the source database.)

12 – 8 4D Insider
Jumpstart 4D

Objects that can be copied


You can copy all objects except for language elements (variables, arrays,
sets, semaphores, and so on). Language elements cannot be moved
because, although they are referenced in methods and object methods,
they are not physically created until 4D is running. Similarly, commands
are part of 4D itself and cannot be copied from one structure to another.
The following objects can be copied:
Database methods
Formats/Filters
Forms
Groups
Lists
Menu bars
Menus
Picture library graphics
Plug-ins
Project methods
STR# resources
Style sheets
Tables
Tips

Objects copied together


Some objects cannot be copied by themselves. For example, when you
copy a form, 4D Insider automatically copies the form methods and
object methods attached to the elements in the form. The following table
lists the copyable objects and any objects automatically copied at the same
time.
Table 12-1: Objects Copied Together

Copyable Objects Objects Copied with the Object

Database methods None

Forms Form methods

Object Object Methods

4D Insider 12 – 9
Jumpstart 4D

Table 12-1: Objects Copied Together

Copyable Objects Objects Copied with the Object

Formats/Filters None

Groups Objects in the group

Lists None

Menus None

Menu bars None

Picture library graphics None

Plug-ins None

Project methods None

STR# resources None

Style Sheets None

Tables Fields

Subfields

Triggers

Tips (linked to any field)

Tips (not linked to any field) None

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

+ the object with all of the objects it uses.


You can control how the object is copied at the time of the copy. If you
choose to perform a copy in which you copy the object with all of the
objects it uses, Insider will perform the copy immediately. Otherwise, it
will display a window containing a series of questions about the copy.
There are two types of questions:
+ those concerning the copy – if an object with the same name already
exists.
+ those linked to a dependency – if the object uses other objects.
Performing a copy
To move objects from a source database to a target database:
+ Launch 4D Insider.
+ Open the source database or library.
+ Open the destination database or library.
+ Select the objects to be moved from the Main list of the source data-
base or library.
Questions generated
If you perform a standard copy without using a modifier key, the window
displayed at the time of the move contains only the most important ques-
tions. For example, if an object already exists in the destination database,
but with different contents, Insider allows you to choose whether to
replace the object or ignore it.
By using a modifier key, you can request that 4D Insider do one of the fol-
lowing:
+ Copy all objects used by the selected objects: If you hold down the
Alt (on Windows) or the Option (on Mac OS) key at the time of the
move, the objects are automatically copied with their dependencies.
In this case, 4D Insider will not ask you about referenced objects or
about the objects that you requested to be automatically copied.
+ Show all questions: If you hold down the Control key (on Mac OS)
at the time of the copy, or move the objects using the Right mouse
button (on Windows), the window displays a detailed list of ques-
tions about the move. This gives you the opportunity to control
what is copied and how replacements are handled.
4D Insider 12 – 11
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

component, each object is attributed an access type, Public, Protected or


Private. This attribute determines whether the object will be visible, or
modifiable in 4D and in 4D Insider once the component is installed
within another 4D database.
Using these features, you can develop a 4D module that offers certain fea-
tures, such as calculating various financial functions. You can then supply
this component to others and they can install it into their databases. If you
have written your component correctly they will be able to install it with-
out any conflicts.
Those objects that are protected cannot be modified by the new user, and
those objects that are private cannot even be seen by the user. This protects
you by not allowing them to see how you developed the code and also pre-
vents them from modifying it.
All objects however remain visible and moveable during development
phase of a component, regardless of their attributes.
There are three different security levels:
+ Public objects are viewable and can be modified by the user; how-
ever, they cannot be renamed or deleted. This object attribute may
be useful for providing user customized objects. In 4D editors, pub-
lic objects appear as all other objects.
+ Protected objects are viewable but can neither be modified nor
deleted by the user. A protected method can be called but its content
can neither be viewed nor modified (the preview area in Explorer
will remain blank). In 4D editors, the icon for protected objects is
depicted by a red slash.
+ Private objects are neither viewable nor, consequently, modifiable
for component users using 4D or 4D Insider.
Tables and fields cannot be classified as private. When uninstalling a com-
ponent, tables are not deleted from the database (since tables cannot be
deleted in 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:

Name Contents Contents Renamable


Type
viewable viewable modifiable or deletable

Public Yes Yes Yes No

Protected Yes No No No

Private No No No No

Avoiding name conflicts


During a new component installation, if different objects with the same
name are detected in both the component and the database, the installa-
tion is aborted. Therefore it is important to use original object names.
Using customized prefixes for naming objects can be useful. 4D, Inc.
advise component developers to use the following naming conventions:
+ Prefix each object name with a unique 5-character ID (for example
asllc), add an underscore (_), insert 3 or 4 characters indicating the
object attribute (priv, prot or pub), add another underscore, then
enter the object name:
- asllc_Priv_MyForm
- asllc_Pub_MyMethod
Declaring variables
By default, 4D Compiler does not display the names of private methods.
However, in case of data type conflict, 4D Compiler will display the
names of all suspect methods, regardless of their attributes. Therefore it is
strongly advised to type all 4D variables used in component methods.
For specific instructions on creating and using 4D Components in your
databases, read the 4D, Inc. document 4D_Insider_67_Addendum.pdf.
Using Insider with 4D Server
With 4D Insider you can open one 4D Server database at a time, on both
Windows and Mac OS. When used this way, 4D Insider is in read-only
mode and any operations which would affect an object will be disabled.
12 – 16 4D Insider
Jumpstart 4D

(Therefore you cannot rename objects.) 4D Insider can connect to 4D


Server using any one of the following network protocols:
+ AppleTalk
+ TCP/IP
+ IPX (Windows only)
To make a connection, 4D Insider must have the proper network compo-
nents installed. If a Designer password is required to open the structure of
your database, you will be asked to enter it.
If you are using 4D Insider with a database published by 4D Server, other
programmers may be modifying the structure or the objects in the data-
base during your 4D Insider session. In this case, the cross-references con-
structed by 4D Insider may become obsolete.
If the table of cross-references needs to be updated, the word Reparse
flashes in the upper-left portion of the current window’s title bar. You can
then choose to reparse the structure when it is convenient.
Creating documentation in a multi-user environment
When you first create the documentation for an object, the documenta-
tion window opens in read-write mode by default.
When you open documentation for a 4D Server database, 4D Insider dis-
plays the documentation in read-only mode. This is indicated by display-
ing the read-only icon in the lower-left corner of the window. To modify
the documentation, click the read-only icon.
If the documentation is being modified by another user, you will not be
able to access it in read-write mode. The documentation will be in read-
write mode when the user who is currently modifying it closes the docu-
mentation window.

4D Insider 12 – 17
Jumpstart 4D

12 – 18 4D Insider
Jumpstart 4D

Chapter 13 – 4D Utilities

4D is supplied with a number of utility programs, the most important


being:
+ 4D Tools – checking, compacting and repairing databases.
+ Customizer Plus – setting preferences.
+ 4D Transporter – converting applications for use on different plat-
forms.
The latest version of these programs can be downloaded from http://
www.4d.com
4D Tools
4D Tools is used to check, compact, recover, and repair the structure
and data files of your database.
In the event of serious damage to your data file, 4D Tools can create a new
empty copy of your data file, recover the undamaged portion of your old
data file into it, and then rebuild new (undamaged) indexes. You may lose
some records in this process.
Checking the structure and data files
Structure and data files can become corrupted for many (unknown) rea-
sons. You can check your structure for certain types of damage, and check
your data file for damaged indexes and data. 4D Tools can automatically
fix many of the problems it may find.
First you must open your database using 4D Tools. You can either open
4D Tools, then select the database to open using the File ¬ Open Data-
base… menu item, or drag and drop the structure file onto the 4D Tools
program icon, or onto its alias (on Mac OS) or shortcut (on Windows).
The data file will not be recognized if you attempt to drag and drop it.
If your database is password protected, you will be presented with the
standard 4D password dialog. You will need either the Designer or
Administrator password to open the database.

4D Utilities 13 – 1
Jumpstart 4D

The password, as always, is case-sensitive so make sure that your CAPS


LOCK key is not on when typing your password.

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

The Used Space thermometer gives you an approximate idea of the


amount of space that can be reclaimed if the data file is compacted. The
Used Space value displays the percentage of space used within the data
file. The lower the percentage, the higher the fragmentation.
In this example the data file fragmentation is approximately 1% and 4D
Tools advises you that the data file does not need to be compacted.
 As records are deleted from the database, holes are left in the data
file. 4D attempts to reuse these holes when new records are created.
Sometimes though the new records may be too large to fit into the
holes. This leads to the data file becoming fragmented. Performance
may decrease when the fragmentation is very high. When 4D Tools
measures that the fragmentation is too high, it will suggest that you
compact the data file.
The Last Check field indicates the date when the database was last
checked with 4D Tools.
Maintain tab
Figure 13-2: Maintain Tab

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

+ Compacted structures occupy less disk space (not usually a problem


these days).
+ Small structures can be e-mailed/ftp’d more quickly.
+ In a 4D Server environment compacted structures take less time to
download to client computers as .RES and .REX files.
Click the Check… button to check the structure.
Figure 13-6: Check and Recover Options

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

Figure 13-7: Customizer Plus Main Screen for a Structure File

The window title indicates the name of the database.


 Double-clicking any icon will allow you to edit the settings.
 Double-clicking any grayed out icon will create the new resource
first, then allow you to edit the settings.
Keys
Figure 13-8: Keyboard Shortcuts Dialog

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

Clicking OK will create the resource and open it:


Figure 13-11: WEDD Resource

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

Size of one block


The size of one block in MB.
Compatibility
Figure 13-13: Compatibility Dialog

For databases that have been updated from 4D v2 to 4D v6.0 or higher,


this dialog allows you to decide on the behavior of certain events within
4D. Even if you have converted your database from 4D v2, you should
modify your code and events to work in the 4D v6.7 way.
Update
Figure 13-14: Update Dialog

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

Platform Default Font

MacOS Geneva 9

Windows NT 3.51 MS Sans Serif 10

Windows 95 MS Sans Serif 12

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.

Database Cache Memory


Use new memory allocation scheme (Macintosh only)
If this option is selected, 4D uses the memory allocated to the 4D applica-
tion to manage the main memory. Database cache memory uses any avail-
able memory from the Mac OS system (also known as multi-finder
memory). This may affect the ability of other programs to open.
If this option is not selected, 4D assigns parts of the memory allocated to
it to the database cache memory and part to the main memory. The allo-
cation between the two will be done using the Cache group parameter.
The maximum and minimum cache values are not taken into account.

4D Utilities 13 – 19
Jumpstart 4D

Minimum cache (Macintosh only)


These parameters are used when the Use new memory allocation
scheme (Macintosh only) option is selected. When opening the data-
base, 4D tries to allocate a memory block of a size that corresponds to
Maximum Cache value. If the available memory is insufficient, 4D will
try values between the maximum and minimum values until it finds a
cache size that matches the available space. If there is not enough system
memory, 4D then uses a part of its allocated memory.
Web Server
Web server TCP port number
This is the desired port number for 4D’s Web server. The default is 80.
4D Transporter
4D Transporter is a simple and fast application from 4D, Inc. that con-
verts a 4D application (both structure and data files) into a Windows-
compatible format and vice versa. (It is provided only for Mac OS. If you
purchased 4D for Windows you can download it free of charge from
http://www.4d.com) For Mac OS to Windows this means splitting a sin-
gle 4D file into two files: the application and the pseudo resource file. For
Windows to Mac OS these two files are merged into one. The process is
fast and simple.
+ When you transport a database from Mac OS to Windows, it copies
the data and resource forks of a Mac OS file into two separate files
that can be copied and used on Windows.
+ If you transport a database from Windows, it copies the file and its
related resource file (if it exists) into one Mac OS file whose data
fork contains the file and whose resource fork contains the related
resource file.
4D Transporter performs the transport of a Mac OS 4D database as fol-
lows:
+ The data fork of the structure file is copied into a .4DB file. This file
is called the database structure file on Windows.
+ The resource fork of the structure file is copied into a .RSR file. This
file is called to the database resource file on Windows.

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

Figure 13-16: 4D Transporter Main Window

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

option. If you deselect this option, 4D Transporter will no longer display


its window when you drag and drop files onto its icon; it will instead per-
form the transport operation immediately using the transporting options
stored on the disk.
Note:
If Show Preferences is deselected, you no longer have access to the 4D
Transporter window. To get it back, press the Option key while launching
4D Transporter.
Use Creator
When transporting from Windows to Mac OS the contents of this field
are used to set the Mac OS creator code. This allows the Mac OS to
launch the correct application program when a file is double-clicked.
Windows does not use creator codes.
Store Settings Button
If you change some options and want those options to be used automati-
cally the next time you use 4D Transporter, click this button. Storing your
options and deselecting the Show Preferences option allows to you to
transport files quickly: 4D Transporter does the transport operations
immediately and then quits.
Transport
This allows you to choose from which platform you are transporting.
Mac to PC
This splits files from Mac OS to Windows.
PC to Mac
This combines files from Windows to Mac OS.
Move the Original File
If you select Move the original file, 4D Transporter does not create any
folder and splits or merges the file(s). If you use this option, 4D Trans-
porter will not save your original file. Therefore, 4D Transporter will

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:

When selecting a 4D database to transport, you can choose either:


13 – 24 4D Utilities
Jumpstart 4D

+ An interpreted 4D database—this becomes a .4DB database for


Windows.
+ A compiled database—this becomes a .4DC database for Windows.

4D Utilities 13 – 25
Jumpstart 4D

13 – 26 4D Utilities
Jumpstart 4D

Chapter 14 – Plug-ins

Plug-ins Extend 4D’s Functionality


4D supports a plug-in architecture. Special programs, written in C/C++,
are placed in the plug-ins folder. These are then loaded into memory, and
extend 4D’s capabilities, when 4D is launched. Some 4D plug-ins are
built into 4D, such as 4D Chart.
Plug-ins can work on either 4D (single-user) or 4D Server and can be
developed for either Mac OS or Windows.
Some plug-ins are platform-specific: System8 Pack (also known as
System7 pack, and System9 Pack) handles AppleEvents and is therefore
Mac OS -pecific, Basic4D is Windows-only. You need to be careful if you
are writing a cross-platform application: you may want to avoid using
plug-ins that are not available for both platforms, or you may need to
detect which platform you are running on and structure your code accord-
ingly. This will be covered in the chapter on cross-platform issues).
If you are developing a commercial application, you may want to avoid
too much dependence on plug-ins: free or shareware plug-ins often have
little technical support and even commercial plug-ins can be dropped
from development if unprofitable.
Installing 4D Plug-ins
Plug-ins can be located in one of two locations (depending on the OS):
On Mac OS
+ Inside a folder named Mac4DX in the same folder as your database
application structure file. Plug-ins located here are only available to
the 4D application whose folder the Mac4DX folder resides in.
Therefore different database applications can have different combi-
nations of plug-ins.
+ Inside the universal 4DX folder:
- YourSystemFolder:Preferences:4D:Mac4DX

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

Selecting any command places it in the method at the cursor insertion


point. Plug-in commands can be typed into the method editor (just like
normal commands).
Creating a Plug-in Area
You can use the plug-in area tool on the tool palette to draw a plug-in
area. You can only work with plug-in areas on detail (input) forms. Note
that in this case the area’s name has been prefixed with chart. This is not
14 – 2 Plug-ins
Jumpstart 4D

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

4D, Inc. Plug-ins


4D Pack
4D Pack contains a number of utility functions that are gradually being
incorporated into 4D.
4D Chart (incorporated within 4D)
4D Chart (the plug-in formerly known as 4D Graph) is unusual in that
the plug-in is installed in the structure of 4D, yet in all other ways behaves
as a standard plug-in.
The plug-in provides the capability of producing both 2D and 3D charts
of various styles. You can open 4D Chart in an external window and use it
to chart any data, or more commonly you can create a 4D Chart area on a
form and chart data that is in the database. Consider the example of a sales
database: you could have a form where you viewed an individual sales per-
son’s sales figures. Next to the figures you could display a pie chart that
showed that sales person’s sales as a percentage of the sales team’s sales.
If you wish to give your users access to the 4D Chart functions from the
Custom Menus Environment you can create a project method (called
from a menu item) that contains the code:
GRAPH TABLE([Contact])

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

Figure 14-3: Sample Chart Created in External Window

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

+ Documents stored in BLOBs can be up to 2 GB in size.


+ Tear off tool palettes.
+ Support for templates.
Database support
+ Fields, variables and methods can be inserted in documents. For
example a project method could build an address from fields in the
record, then clean up blank lines and format the address according
to the style used in the destination country.
Document formats
+ Multiple platform document support for Mac OS and Windows
including Word™ 98 (Mac), Word™ 97 (Win), 4D Write 6.7, 4D
Write 6.5, 4D Write 6.0, template, RTF, HTML, Windows text,
Mac OS text, and Unicode text.
Figure 14-4: Typical Form Incorporating a 4D Write Area

This form incorporates both 4D fields, objects (buttons) and a 4D Write


area.

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

Support for standard graphic functions


+ Rulers, scales, grids, and text.
+ Lines, rectangles, ovals, arcs, polygons, and freehand objects.
Support for advanced functions
+ Multiple documents open simultaneously.
+ Object attributes.
+ Drawing attributes can be bound to database fields.
Database support
+ Fields, variables, and methods can be inserted in documents.
Document formats
+ Cross-platform document support for Mac OS and Windows.
+ Able to open MacPaint, PICT, and EPSF documents.
4D Internet Commands
Simple Mail Transfer Protocol (SMTP) is the primary mail transfer proto-
col used for sending e-mail over the internet. 4D Internet Commands
allow users to quickly build and send mail via a SMTP server. You can cre-
ate a simple message with a single command. The commands also provide
you with the ability to encode attachments in different ways such as: Bin-
hex, Base64, AppleSingle, AppleDouble, etc. You can encode and then
send multiple attachments per message.
4D Internet Commands also contains commands which will connect to
POP3 (Post Office Protocol 3) mail servers for retrieval of mail messages
and encoded attachments.
The File Transfer Protocol (FTP) commands provide a very easy-to-use
mechanism for communicating with an FTP server to send/receive text or
binary files. Commands within the FTP suite can obtain directory listings
of files, enabling you to create 4D interfaces to remote volumes.
Transmission Control Protocol/Internet Protocol, (TCP/IP) is the pri-
mary protocol used for sending and receiving data over the Internet. 4D
Internet Commands contains several commands for sending and receiving

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

+ Implementation of deferred mode.


+ Array processing.
+ Use of native types with automatic cross conversion.
+ Support for Binary Large Objects (BLOBs).
+ A debugging window for tracing the communication between 4D
and 4D for ORACLE.
+ Support for Versions 1 and 2 of SQLNet.
Third-Party Plug-ins
There have been over 300 plug-ins developed for 4D since 4D v1. (Many
of these may not work with 4D v6.7, or may not be supported.)
Details of most of the plug-ins are available from the plug-ins section of
the Inner Dimension Web site at http://www.inner-dimen-
sion.com.
Developing Your Own Plug-ins
Developing your own plug-ins for 4D is not a trivial task. You need to
understand both 4D and C/C++, plus understand the internal architec-
ture of 4D and in some cases have a detailed knowledge of OS issues.
To make the task a little easier 4D, Inc. has supplied a tool called the
Plug-in Wizard. This is a 4D application that helps you build a C/C++
framework for developing your plug-in (it makes the job a lot easier). This
tool is bundled free of charge with many of the 4D products and the doc-
umentation Plug-in_Wizard_Reference.pdf is available as a free down-
load from the 4D, Inc. Web site.
Since it is written in 4D the Plug-in Wizard is cross-platform.
Web Assistant
4D Web Assistant (introduced with 4D v6.7) is not actually a plug-in but
a 4D component. A 4D component is a special type of 4D Insider library
that can be installed directly into the structure of a database. It adds new
functionality to the database. Once installed, it behaves in much the same
way as a plug-in.
When you create a new database in 4D, you are offered the option of
installing 4D Web Assistant. If you choose not to install it, you can always
install it at a later time.

14 – 10 Plug-ins
Jumpstart 4D

 4D Web Assistant is the component formerly known as DataWave.


Installing Web Assistant in a new database
If you are creating a new database and would like to use the Web Assistant,
select the Install 4D Web Assistant option that appears in the Open
Database dialog box when you launch 4D. If the Install 4D Web Assis-
tant option is non-selectable (grayed out), that means you do not have the
Web Assistant installed in the correct directory. Whether you use either
4D Stand-alone or 4D Server, both applications need a 4D Extensions
folder in its directory.
Windows
C:/4D Standalone/4D Extensions
C:/4D Server/4D Extensions
Mac OS
4D:4D Standalone:4D Extensions
4D:4D Server:4D Extensions
Inside the 4D Extensions folder should be the Web Assistant compo-
nent. Once the 4D Extensions folder has been installed in the correct
place, the Install 4D Web Assistant option should now be selectable.
Installing Web Assistant in an existing database
To install the 4D Web Assistant in an existing database:
+ Using 4D Insider, open the database in which you want to integrate
4D Web Assistant.
+ From the Components menu, select Update/Install. An Open
file dialog is displayed.
+ Select the 4D Web assistant component.
+ Quit 4D Insider.
Although 4D Web Assistant is automatically installed and the necessary
options automatically set, you should check the following:
+ Open the database using 4D (stand-alone).
+ Go to the Design Environment.
+ Select Database Properties from the File menu.
Plug-ins 14 – 11
Jumpstart 4D

+ In the Web Server I tab, uncheck Publish Database at Startup.


+ In the Web Server I page, check Start without Context.
+ In the Web Server II page, check the Use Passwords option.
+ In the Web Server II page, uncheck the Include 4D Password
option.
If this last option is not unchecked, the password system will not operate
properly.
In addition to the previous steps, you should make sure the password sys-
tem is activated. In 4D, the password system is activated by creating a
Designer password. (To actually use 4D Web Assistant you will need to
make various changes to your code, such as making the call to the wbaP-
alette project method and modifying your database methods On web
connection and On web authentication. These are covered in the 4D
Web Assistant documentation.)
What is 4D Web Assistant?
4D Web Assistant turns existing data in a 4D Database into HTML
pages, allowing it to be read by any Web browser supporting tables and
forms, such as Navigator and Internet Explorer. Since 4D Web Assistant
creates every page on-the-fly, any changes or modifications to your data
are published in real time.
How does this differ from 4D’s built-in Web Server? Using 4D’s Web
commands the designer has to make decisions as to what data to publish,
and what data not to publish. If later the users change their minds, the
developer needs to modify the code and send new structures to the users.
4D Web Assistant is a tool that lets the user decide which data to publish.
From an easy-to-use interface they can select the tables and fields that
should be published. Executing the wbaPalette project method, for exam-
ple, displays the 4D Web Assistant palette:
Figure 14-5: 4D Web Assistant Palette

14 – 12 Plug-ins
Jumpstart 4D

From here you can:


+ Start and stop Web publishing.
+ Define which tables and fields are visible.
+ Edit the HTML that is used in the header and footer areas.
+ Access the Appearance Editor.
The HTML editor allows you to customize the HTML which occurs
immediately before (header) or after (footer) the HTML automatically
generated by 4D Web Assistant. This would allow the use of custom
graphics or text to be used in conjunction with 4D Web Assistant.
Figure 14-6: HTML Editor

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

Chapter 15 – Developer Standards and Improving


Your Code

Writing Better Code


Programming is part art and part science. Often there is no single correct
way to solve a problem: like skinning cats there’s usually more than one
way. But whatever way you choose to solve your problem, you should be
sure that it’s the most efficient way (within reason), and that whatever
code you write is maintainable both by you and any future programmers.
Spending hours micro-optimizing your code is usually a waste of time,
time that would be better spent on optimizing your design in the first
place. It is usually a better investment in time to write code that is easy to
follow which will then make the code easier to maintain:
+ Your code will be quicker and easier to write in the first place.
+ Your code will be easier to debug.
+ Your code will be easier to understand in three years time when you
come back to change it.
+ Other developers will be able to understand your code.
An important first step is to understand what each command and func-
tion in 4D actually does. While this may sound obvious there are many
subtleties to 4D that may affect how you write your code. Here’s a few
examples to ponder:
+ What is the difference between the three main loop constructs:
For…End for, Repeat…Until and While… End while? (Hint:
What is the minimum number of times each loop can execute?)
- This can be important when deciding which type of loop
structure to use. (Using an unexpected loop structure can be
puzzling to another programmer, since each different type is
typically used in different circumstances.)
+ After a query where is the current record pointer? Are any records
loaded into memory if records have been found?
+ After a SELECTION TO ARRAY what is the status of the current
selection and where is the current record pointer?
Developer Standards and Improving Your Code 15 – 1
Jumpstart 4D

Understanding these issues is essential before choosing which command to


use, in other cases it will enable you to eliminate unnecessary commands.
Another useful technique is to read the technical notes and tips that are
published by 4D, Inc., and to review the sample databases that come with
them. Seeing how other programmers have tackled problems is always
instructive, even if you don’t agree with them. You should always be open
to alternative techniques.
Keep your project methods short
Project methods are limited in length to approximately 32,000 characters
by 4D. However your methods should never be this long. Reading meth-
ods that are several screens in length is tedious on-screen and nearly as dif-
ficult when printed. It is better to break them down into shorter chunks –
something around a screen in length is handy, or code that would print on
one piece of paper. (Matching up multiple If…End if statements gets
tricky when split over several pages.)
A project method should carry out one function only if possible. (That
function should be obvious from the method name.) Having many small
project methods, rather than fewer long methods, makes little difference
in the size of your database, the time it takes to compile or execute. It does
however usually make it easier to read and debug.
Replace nested If statements
Sometime you end up with a rat’s nest of multiple, embedded If state-
ments. These can often be replaced by a single Case statement (which
should always end with an Else test to trap unforeseen conditions).
Use meaningful names for objects
All database objects should have meaningful and descriptive names which
indicate their usage. (Standards that can be used to help create these
names are discussed later.) Variables in particular need careful naming: one
bad habit of many old school programmers is to name loop counters as
single letter variables for example:
For ($i;1;Records in selection([Invoice]))

This name conveys nothing. (Ideally the table name should give some
indication of what the loop is processing.)

15 – 2 Developer Standards and Improving Your Code


Jumpstart 4D

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]))

Later you might need to add code such as:


MESSAGE ("Processing invoice # " + String ($Invoices) + " of "
+ String (Records in selection([Invoice])))

A meaningful variable name is useful here.


Leave Range Checking On in compiled databases
It will catch all manner of programming errors that would otherwise get
missed.
Be proactive in trapping for errors
+ Use the Else test wherever possible to test for unforeseen conditions
and handle them appropriately.
+ Learn to use ON ERR Call.
+ Test the condition of the OK system variable wherever relevant.
(But be aware that many different operations affect this variable, and
perhaps not the one you were expecting.)
Developer Standards
Even if you develop applications solely for your own use, there is a chance
that you will have to update it at some time in the future, perhaps long
after you have forgotten what you were trying to do at the time! Defining
and using some standards will help you when you have to come back to
your code later. If someone else has to maintain your code, it will make
their lives much easier. One part is to define and use standard naming
conventions for database objects, the other is to comment your code.
The precise format of your naming conventions is less important than
using them consistently. Different developers have different ideas as to
how the various database objects should be named. Some of these can
become religious issues. For example, some developers feel that tables
should be named in the singular, since each record in that table represents
one instance of the data. Other developers name them in the plural. Some
developers feel that boolean variables should be prefixed bool, some prefer
b, and others bln. It doesn’t really matter.

Developer Standards and Improving Your Code 15 – 3


Jumpstart 4D

What matters is that you decide on a reasonably logical standard, docu-


ment it, and use it consistently.
You may find that some of your ideas don’t work out but don’t worry: 4D
Insider can be used on a regular basis to check and rename your database
objects as required.
Naming Conventions
There are many reasons to use standardized naming conventions when
programming in any language (and especially in 4D):
+ Readability of code. Consider the variable named ToBeDeleted.
This could be a date, time, or boolean field. Prefixing the variable to
indicate the variable type removes all doubt.
+ Reuse of code between different applications using 4D Insider.
+ Avoiding naming conflicts with 4D commands (e.g. Date) and con-
stants (e.g. Tab).
+ Ease of maintenance. How long will you be able to remember all
those variable names and what they mean?
+ Reduction in coding errors caused by data type mismatches
(attempting to assign values from a field to a variable of a different
type or vice versa).
+ Avoiding the repetition of similarly named variables.
+ Increased modularity of code.
- Project methods are listed in 4D Insider in alphabetical order.
Prefixing methods with a module name groups them together.
If necessary, you can also group variables by appending a mod-
ule prefix after the data type prefix: e.g.
str_INV_Invoice_Date.)
Tables
+ Are generally named in the singular.
+ Use underscores, rather than spaces, between the elements of a
name. This way you can double-click a name to select it since the
OS treats it as one word. With spaces you have to click and drag
through the name to select it.
+ Follow 4D’s naming rules on the use of non-alphabetic characters.
Some examples:

15 – 4 Developer Standards and Improving Your Code


Jumpstart 4D

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):

15 – 6 Developer Standards and Improving Your Code


Jumpstart 4D

SET ENTERABLE (*;etx_@; TRUE)

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.

Developer Standards and Improving Your Code 15 – 7


Jumpstart 4D

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

The project method WND_Title contains code that builds a window


name based on the current selection of records in the table:
Developer Standards and Improving Your Code 15 – 9
Jumpstart 4D

SET WINDOW TITLE($2+": "+String (Records in selection($1->))+"


of "+String (Records in table($1->)))

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.

15 – 10 Developer Standards and Improving Your Code


Jumpstart 4D

Chapter 16 – Deploying Your 4D Database

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

+ Your compiled application is merged with the 4D Runtime Classic


by 4D Compiler. This reduces the apparent complexity and num-
ber of files that need installing on the target computer.
+ You purchase additional 4D Runtime Classics as and when you
need them. The current price is $99 in the USA.
Remember that you cannot use 4D Runtime Classic to create or edit
databases. This is a deployment-only option.
4D Engine
If you intend to develop a vertical market application, or distribute a large
number of compiled 4D applications, you may find that 4D Engine is the
cheapest solution (in the USA and some other countries you must be a
member of the 4D partner plan to purchase 4D Engine). There is one 4D
Engine for Mac OS and another for Windows.
4D Engine is similar to the 4D Runtime Classic – you merge your fin-
ished, compiled application with the 4D Engine to create a stand-alone,
double-clickable application.
With 4D v6.5 the engine license allowed you to create an unlimited num-
ber of merged applications for each platform that you purchased, for a
fixed one-time fee per platform.
With 4D v6.7 the engine licensing system changed: you now purchase 4D
Engines in blocks of 10 or 25.
If you anticipate selling a lot of copies of a 4D Engine-based product you
should contact OEM sales at OemSales@4d.com.
A Few Thoughts Before Deployment
Pre-flight checklist
Before delivering the final version of a 4D-based product you will need to
check and recheck every facet of the application. When you have been
working with an application for a long time it is easy to overlook even the
most glaring of errors. One way of handling this is to create a checklist
and give this to your Software Quality Assurance (SQA) team. (This is
usually you or your spouse!)
Once you have created your application-specific checklist, you can use this
to check various facets of your application before compiling and merging
16 – 2 Deploying Your 4D Database
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.

Deploying Your 4D Database 16 – 3


Jumpstart 4D

16 – 4 Deploying Your 4D Database


Jumpstart 4D

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

(although informally moderated). It is interesting to note that both mail-


ing lists have an exceptionally high signal to noise ratio due to the policies
of their owners or moderators.
4D Networked User Group (NUG)
This has now been divided into technical, business, and social mailing
lists. To join any of these lists (either for single messages or digests) visit
http://www.4dnug.com/resources.html.

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

The database is an Oracle database that allows simple to complex queries.


4D Zine
Programming resources and news from Steve Willis (who also hosts the
Jumpstart Web site as well as many others).
http://www.4dzine.com/

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/

Dimensions Magazine is a quarterly magazine covering many aspects of


4D programming and product reviews. Code samples are provided via the
Web site.
As of March 1st, 2001 Alto Stratus LLC (authors of this book) acquired
all rights to Dimensions Magazine.
HPO Soft
Excellent three-part PDF guides to beginning 4D (from a FileMaker Pro
user’s perspective).
http://www.amug.org/~hposoft/

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

Programming 4th Dimension


This is an excellent intermediate to advanced book by David Adams that
includes a CD-ROM with sample code. It is available from Automated
Solutions Group at
http://www.asgsoft.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

Chapter 18 – Cross-Platform Issues

One of 4D’s greatest strengths is its cross-platform capabilities. Although


4D was originally developed for Mac OS, it became a cross-platform data-
base with the release of 4D v3.5. Since then it has matured into a fully
cross-platform development environment.
Developers can develop an application on their platform of choice and
deploy the finished product on either Windows or Mac OS, or any mix-
ture of the two.
For example, a company could use 4D Server on Windows NT (for per-
formance) and the developers could develop on either Mac OS or Win-
dows according to their personal preferences. The software could then be
tested on both platforms as desired to ensure that all features work in both
environments.
The customer can then choose whichever server platform they prefer, and
the users can use any mixture of Mac and Windows for their client com-
puters.
4D automatically handles most of the issues that plague cross-platform
developers, but there are a few issues that must be handled by the devel-
oper. 4D provides you with a number of commands and functions to do
this.
Developers Should Understand the Operating Systems
Many developers work primarily on one OS platform such as Mac OS or
Windows. Often their knowledge of the “other” platform is weaker than
the platform that they use the most. (To many developers, this is almost a
religious issue.) But when developing cross-platform applications it is
essential to understand both platforms equally well. The Mac OS and
Windows environments are very different despite their superficial similari-
ties. Items that differ for example are:
+ Maximum file name length.
+ Valid filename characters (Mac OS accepts ‘/’ for example in a file
name whereas Windows does not.)

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

Windows Handling of CD Installed Applications


When copying files from a CD-ROM using Windows be aware that the
File Properties will be set to Read Only. After you copy files to your
hard disk they will still be Read Only. Use the Program Manager to reset
them. If you do not, you can make changes both to the structure and data
files but they will not be saved. 4D does not warn you that the files are
read-only.
This is not a problem if you install from the 4D, Inc. installation disks, or
if you are distributing an application to your users; you can create an
installer of your own using 4D’s InstallMaker application. Another way
to avoid this problem is to zip the files into an archive for distribution, or
create a self-extracting file.
Database Properties
Figure 18-1: Database Properties Dialog

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

Figure 18-3: Setting the Platform Interface (Object Properties)

For Windows, objects such as buttons should be set to Focusable.


User Interface Differences
Menus
On Mac OS, a menu would appear as follows:
Figure 18-4: Sample Menu on Mac OS

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

Command key Ctrl key

Shift key Shift key

Caps Lock key Caps Lock key

Option key Alt key

Control key Mouse Right Button

Special characters within 4D’s editors


Some of the special characters used in the 4D procedural language have an
ASCII code greater than 127. These characters may have a different ASCII
code on Windows or they may not even exist. In order to solve this prob-
lem, 4D uses symbols that will be common between the Windows version
and the Mac OS version.
+ Character reference symbols: the expression MyString≤1≥ (Mac
OS) can also be written MyString_<.1>_ (Windows)
+ Interprocess symbol: the expression ◊MyVar (Option+Shift+v on
Mac OS) can also be written <>MyVar (Windows).
+ Time constant. The constant †11:59:59† (Option+t on Mac OS)
can also be written as ?11:59:59? on 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

There are two major reasons for doing this:


+ It is unusual to find a font with both the same name and appearance
on both Windows and Mac OS.
18 – 8 Cross-Platform Issues
Jumpstart 4D

+ 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

Figure 18-8: Style Sheet Editor

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

Constant Type Value

Macintosh 68K Long Integer 1

Power Macintosh Long Integer 2

Windows Long Integer 3

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

This method then uses the PLATFORM PROPERTIES command to


determine the platform and assign a value to an interprocess variable, for
example ◊Platform. Then whenever you need to determine the platform
you can check the value of this variable (since the platform you are cur-
rently running on cannot change).
The following code tests the platform and sets the delimiter character used
in file paths:
PLATFORM PROPERTIES($Platform)
If ($Platform=Windows)
$DirSymbol:="\"
Else
$DirSymbol:=":"
End if

If you use 4D commands such as Open document you do not need to


worry about the file path and which delimiters are used. 4D knows (from
which platform you are on) the appropriate format to use.
However if you wish to manipulate the file path in some way such as by
appending a file name to a previously defined path you will need to deter-
mine your platform and write your code accordingly.

18 – 12 Cross-Platform Issues
Jumpstart 4D

Get platform interface


This function does not require any parameters. The command Get plat-
form interface returns a value that denotes the current platform inter-
face used for displaying forms. You can change the platform interface
using the command SET PLATFORM INTERFACE or within the
Design Environment you can use Database Properties.
SET PLATFORM INTERFACE (interface)
The command SET PLATFORM INTERFACE sets the platform inter-
face used for displaying the forms.The command does nothing if the value
you pass does not change the current platform interface. The platform
interface can also be changed in the Design Environment Database
Properties dialog box.

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

4D.EXE Executable 4D application

4D.HLP Windows help file for 4D

4D.RSR Resource file of 4D

ASIFONT.FON Altura Toolbox file

ASIFONT.MAP Editable font map

ASINTPPC.DLL Mac2Win dll from Altura

ASIPORT.RSR Altura Toolbox resource file

BYTESWAP.TXT Copes with ASCII characters > than 128

Table 18-4: Windows Database Structure Files

File Notes

WIN4DX extensions folder Contains Windows plug-ins or stubs

FILE.4DB Database structure

FILE.4DC Compiled database structure

FILE.4DD Data file

FILE.4DR WEDD resource file

FILE.RSR Resource fork of structure

18 – 14 Cross-Platform Issues
Jumpstart 4D

Table 18-5: 4D File Types & Extensions

Mac OS Windows
File
File Type File Extensions

Structure file BAS5 .4DB, .RSR

Compiled structure file BASY .4DC, .RSR

Data file dat5 .4DD, .4DR (optional)

Data Segment dax5 .4DS

Log File 4LOG .4DL

ASCII files TEXT .TXT

4D Client Resource File res .RES

4D Client Local file LOC4 .REX

Proc.Ext PEXT .ESR

4D Plug-in (Mac OS) 4DPX .4DX, .RSR

4D Plug-in (Windows) n/a .4DX

Hot Link file 4DHL .4LK

Quick Report document 4DSE .4QR

Labels document 4DET .4LB

SAVE SET document SETT .4ST

SAVE VARIABLE document VAR1 .4VR

User & Groups set 4DUG .4UG

Pathname document paTH .PTH

ASCII Map document FILT .4FI

Apply formula document EFRM .4FR

Search document RECH .4DF

Formula document TFRM .TFR

Any file n/a .DTA (optional)


.RSR (optional)

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 ™

solid understanding of the


background. ”
~ Charlie Tiggs
Tiggs Consulting basics of 4D:

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 ISBN: 0-9712895-1-4


by Steve Hussey SHELVING CATEGORY: PROGRAMMING 4 D P R E S S . 4 D . C O M
Jumpstart 4D™ © 2002 by Steve Hussey. The 4D WebSTAR and the 4D Press Logo are registered trademarks of 4D, Inc. 4D is a registered trademark of 4D SA. Brands and
products referenced herein are the trademarks or registered trademarks of their respective holders. Printed in the U.S.A. BK0300C00ESB001

You might also like