Progress PDF
Progress PDF
Progress PDF
Language Tutorial
for Windows
©
2001 Progress Software Corporation. All rights reserved.
Progress® software products are copyrighted and all rights are reserved by Progress Software Corporation.
This manual is also copyrighted and all rights are reserved. This manual may not, in whole or in part, be
copied, photocopied, translated, or reduced to any electronic medium or machine-readable form without
prior consent, in writing, from Progress Software Corporation.
The information in this manual is subject to change without notice, and Progress Software Corporation
assumes no responsibility for any errors that may appear in this document.
The references in this manual to specific platforms supported are subject to change.
Progress, Progress Results, Provision and WebSpeed are registered trademarks of Progress Software
Corporation in the United States and other countries. Apptivity, AppServer, ProVision Plus, SmartObjects,
IntelliStream, and other Progress product names are trademarks of Progress Software Corporation.
SonicMQ is a trademark of Sonic Software Corporation in the United States and other countries.
Progress Software Corporation acknowledges the use of Raster Imaging Technology copyrighted by
Snowbound Software 1993-1997 and the IBM XML Parser for Java Edition.
©
IBM Corporation 1998-1999. All rights reserved. U.S. Government Users Restricted Rights — Use,
duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
Progress is a registered trademark of Progress Software Corporation and is used by IBM Corporation in the
mark Progress/400 under license. Progress/400 AND 400® are trademarks of IBM Corporation and are used
by Progress Software Corporation under license.
Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the
United States and other countries.
Any other trademarks and/or service marks contained herein are the property of their respective owners.
.
May 2001
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Organization of This Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
How to Use This Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Typographical Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
Syntax Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Example Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
Progress Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxvi
Other Useful Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxviii
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxviii
Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Reporting Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxx
4GL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxi
Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii
DataServers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii
SQL-89/Open Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii
SQL-92 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxiii
Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxiv
WebSpeed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxiv
Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxv
iv
Contents
v
Contents
vi
Contents
vii
Contents
viii
Contents
ix
Contents
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Glossary–1
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index–1
x
Contents
Figures
Figure 1–1: Paper-based Ordering Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1–3
Figure 1–2: Components of the Progress 4GL/RDBMS Product . . . . . . . . . . . . . . 1–5
Figure 1–3: Relationship of Paper and Electronic Filing Systems . . . . . . . . . . . . . 1–7
Figure 1–4: Structure of a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1–8
Figure 1–5: Simple and Compound Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1–9
Figure 2–1: The ADE Desktop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–3
Figure 2–2: Procedure Editor Main Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–4
Figure 2–3: File Pull-down Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–10
Figure 2–4: Accessing On-line Help Information . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–20
Figure 2–5: Help Topics: Procedure Editor Help Dialog Box . . . . . . . . . . . . . . . . . 2–21
Figure 2–6: Index Tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–22
Figure 2–7: Informational Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–22
Figure 2–8: Find Tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–23
Figure 3–1: Basic Character Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–3
Figure 3–2: Basic Graphical User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–4
Figure 3–3: How an Application Responds to Events . . . . . . . . . . . . . . . . . . . . . . . 3–13
Figure 3–4: A Simple Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–34
Figure 4–1: Data Dictionary Main Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–3
Figure 4–2: Data Dictionary Main Display Components . . . . . . . . . . . . . . . . . . . . . 4–7
Figure 4–3: Property Sheet for the Cust-Num Field . . . . . . . . . . . . . . . . . . . . . . . . 4–10
Figure 4–4: Table Properties Sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–12
Figure 4–5: Field Properties Sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–13
Figure 4–6: Index Properties Sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–14
Figure 4–7: Sequence Properties Sheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–16
Figure 4–8: Table Validation Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–18
Figure 4–9: Field Validation Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–18
Figure 4–10: Table Triggers Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–20
Figure 4–11: Format Examples Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–22
Figure 4–12: VIEW-AS Phrase Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–23
Figure 6–1: Main Procedure and Subprocedures . . . . . . . . . . . . . . . . . . . . . . . . . . 6–3
Figure 6–2: Main Procedure and Internal Procedures . . . . . . . . . . . . . . . . . . . . . . 6–5
Figure 6–3: Defining and Using a User-defined Function . . . . . . . . . . . . . . . . . . . . 6–7
Figure 6–4: Using an Include File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–9
Figure 6–5: Shared Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–11
Figure 7–1: Format Phrase Positioning Options . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–7
Figure 7–2: Parts of a Fill-in Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–22
Figure 7–3: Parts of a Text Widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–26
Figure 7–4: Parts of a Toggle Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–28
Figure 7–5: Parts of a Radio Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–32
Figure 7–6: Parts of a Slider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–38
Figure 7–7: Parts of a Selection List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–44
Figure 7–8: Parts of a Combo Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–53
Figure 7–9: Parts of an Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–58
xi
Contents
xii
Contents
Tables
Table 2–1: Basic Key Functions in the Procedure Editor . . . . . . . . . . . . . . . . . . . . 2–8
Table 2–2: Procedure Editor Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–9
Table 2–3: Progress Menu Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–12
Table 2–4: Basic Editing Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2–13
Table 2–5: Key Functions to Define Text-Block Operations . . . . . . . . . . . . . . . . . 2–15
Table 2–6: Buffer Tasks and Associated Menu Options . . . . . . . . . . . . . . . . . . . . 2–16
Table 2–7: Procedure Editor Help Menu Options . . . . . . . . . . . . . . . . . . . . . . . . . 2–20
Table 3–1: Widget Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–14
Table 3–2: Commonly Used Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–29
Table 3–3: Important Event Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–32
Table 3–4: Event Categories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–32
Table 4–1: Data Dictionary Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–8
Table 4–2: Tables in the sports Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–11
Table 4–3: Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–13
Table 4–4: Index Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–15
Table 4–5: Sequence Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–16
Table 4–6: Database Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–19
Table 4–7: Field Format Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–21
Table 4–8: Reports Menu Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4–24
Table 5–1: Syntax Components of DEFINE VARIABLE . . . . . . . . . . . . . . . . . . . . 5–3
Table 5–2: Constant Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–10
Table 5–3: Numeric Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–11
Table 5–4: Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–12
Table 5–5: Date Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–13
Table 5–6: Character Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–13
Table 5–7: Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–14
Table 5–8: Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–17
Table 6–1: Elements of the FUNCTION Statement . . . . . . . . . . . . . . . . . . . . . . . . 6–6
Table 6–2: Block Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–31
Table 7–1: Ways to Define or Modify a Data Widget . . . . . . . . . . . . . . . . . . . . . . . 7–2
Table 7–2: Format Phrase Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–5
Table 7–3: Frame Phrase Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–8
Table 7–4: Widget System Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–14
Table 7–5: Radio Set Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–33
Table 7–6: Slider Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–39
Selection List Syntax 7–45
Table 7–8: Selection List Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–48
Table 7–9: Selection List Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–48
Table 7–10: Combo Box Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–54
Table 7–11: Editor Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–59
Table 8–1: DISPLAY Statement Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–15
Table 8–2: Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–25
Table 8–3: DEFINE BROWSE Statement Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 8–55
xiii
Contents
xiv
Contents
Procedures
lt-03-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–7
lt-03-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–10
lt-03-03.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–19
lt-03-04.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–21
lt-03-05.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–23
lt-03-06.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–25
lt-03-07.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–39
lt-03-08.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–43
lt-03-09.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–48
lt-03-10.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–51
lt-05-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–7
lt-05-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5–22
lt-06-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–16
lt-06-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–16
lt-06-03.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–16
lt-06-04.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–28
lt-06-05.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6–35
lt-07-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–11
lt-07-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–16
lt-07-03.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–21
lt-07-04.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–25
lt-07-05.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–31
lt-07-06.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–35
lt-07-07a.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–42
lt-07-08.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–51
lt-07-09.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–57
lt-07-10.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7–62
lt-08-08.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–9
lt-08-f1.i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–11
lt-08-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–17
lt-08-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–22
lt-08-03.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–29
lt-08-04.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–37
lt-08-05.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–43
lt-08-06.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–47
lt-08-07a.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–62
lt-08-07b.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8–63
lt-09-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9–7
lt-09-02.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9–12
lt-09-03.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9–14
lt-09-04.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9–22
lt-09-05.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9–24
lt-10-01.p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10–6
xv
Contents
xvi
Preface
Purpose
This book introduces the basic concepts of the Progress 4GL and programming model and
provides opportunities for hands-on experience designing applications and user interfaces.
Audience
This book is intended for the person with some programming experience who wants to start
developing applications in Progress.
Introduces the Progress relational database management system and the application
development language.
Explains how to start and exit Progress, how to use the Procedure Editor, and how to
access the help system and online example procedures described in this manual.
Describes the Progress programming model and the basic syntax and structure of
procedures.
Progress Language Tutorial for Windows
Explains how to use the Data Dictionary tool to view the properties of database tables,
fields, indexes, and sequences.
Introduces the Progress conventions governing variables, data types, expressions, and
operators.
Describes the structures for creating modularized code and controlling an application.
Explains the syntax, events, attributes, and programming techniques used with widgets.
Explains how to integrate menu bars, submenus, and menu items into your application.
Suggests how to expand the development skills you acquired from this tutorial.
“Glossary”
xviii
Preface
Solution
filename
Problem 5-1 lt-05-s1.p
Problem Using a FOR EACH block, increase all customer credit limits by 10%. Display the
customer name, old credit limit, and new credit limit.
You can access the sample solutions on-line. Refer to the “Example Procedures” section later
in this Preface for the specific details to access this information.
The best advice for success is to set a pace for yourself that makes the tutorial fun and gives you
plenty of time to practice what you learn.
xix
Progress Language Tutorial for Windows
Typographical Conventions
This manual uses the following typographical conventions:
– New terms
– Code examples
– System output
• Small capitals are used for Progress key functions and generic keyboard keys.
END-ERROR, GET, GO
ALT, CTRL, SPACEBAR, TAB
• When you have to press a combination of keys, they are joined by a dash. You press and
hold down the first key, then press the second key.
CTRL–X
• When you have to press and release one key, then press another key, the key names are
separated with a space.
ESCAPE H
ESCAPE CURSOR-LEFT
xx
Preface
Syntax Notation
The syntax for each component follows a set of conventions:
• Uppercase words are keywords. Although they are always shown in uppercase, you can
use either uppercase or lowercase when using them in a procedure.
SYNTAX
• Italics identify options or arguments that you must supply. These options can be defined
as part of the syntax or in a separate syntax identified by the name in italics. In the
ACCUM function above, the aggregate and expression options are defined with the
syntax for the ACCUM function in the Progress Language Reference.
• You must end all statements (except for DO, FOR, FUNCTION, PROCEDURE, and
REPEAT) with a period. DO, FOR, FUNCTION, PROCEDURE, and REPEAT
statements can end with either a period or a colon, as in this example:
• Square brackets ([ ]) around an item indicate that the item, or a choice of one of the
enclosed items, is optional.
SYNTAX
In some instances, square brackets are not a syntax notation, but part of the language.
xxi
Progress Language Tutorial for Windows
For example, this syntax for the INITIAL option uses brackets to bound an initial value
list for an array variable definition. In these cases, normal text brackets ([ ]) are used:
SYNTAX
• Braces ({ }) around an item indicate that the item, or a choice of one of the enclosed
items, is required.
In this example, you must specify the items BY and expression and can optionally
specify the item DESCENDING, in that order:
SYNTAX
{ BY expression [ DESCENDING ]}
In some cases, braces are not a syntax notation, but part of the language.
For example, a called external procedure must use braces when referencing arguments
passed by a calling procedure. In these cases, normal text braces ( { } ) are used:
SYNTAX
{ &argument-name }
In this example, EACH, FIRST, and LAST are optional, but you can only choose one:
SYNTAX
xxii
Preface
SYNTAX
• Ellipses (...) indicate that you can choose one or more of the preceding items. If a group
of items is enclosed in braces and followed by ellipses, you must choose one or more of
those items. If a group of items is enclosed in brackets and followed by ellipses, you can
optionally choose one or more of those items.
In this example, you must include two expressions, but you can optionally include more.
Note that each subsequent expression must be preceded by a comma:
SYNTAX
In this example, you must specify MESSAGE, then at least one of expression or SKIP,
but any additional number of expression or SKIP is allowed:
SYNTAX
In this example, you must specify {include-file, then optionally any number of
argument or &argument-name = "argument-value", and then terminate with }:
SYNTAX
{ include-file
[ argument | &argument-name = "argument-value" ] ... }
• In some examples, the syntax is too long to place in one horizontal row. In such cases,
optional items appear individually bracketed in multiple rows in order, left-to-right and
top-to-bottom. This order generally applies, unless otherwise specified. Required items
also appear on multiple rows in the required order, left-to-right and top-to-bottom. In cases
where grouping and order might otherwise be ambiguous, braced (required) or bracketed
(optional) groups clarify the groupings.
xxiii
Progress Language Tutorial for Windows
SYNTAX
In this example, ASSIGN requires one of two choices: either one or more of field, or one
of record. Other options available with either field or record are grouped with braces
and brackets. The open and close braces indicate the required order of options:
SYNTAX
Example Procedures
This manual provides numerous example procedures that illustrate syntax and concepts.
Examples use the following conventions:
• If they are available online, the name of the procedure appears above the left corner of the
box and starts with a prefix associated with the manual that references it, as follows:
If the name does not start with a listed prefix, the procedure is not available online.
xxiv
Preface
• If they are not available online, they compile as shown, but might not execute for lack of
completeness.
1 ♦ From the Control Panel or the Progress Program Group, double-click the Proenv icon.
Running Proenv sets the DLC environment variable to the directory where you installed
Progress (by default, C:\Program Files\Progress). Proenv also adds the DLC
environment variable to your PATH environment variable and adds the bin directory
(PATH=%DLC%;%DLC%\bin;%PATH%).
3 ♦ Enter the following command at the proenv prompt to create the prodoc directory in your
Progress working directory (by default, C:\Progress\Wrk):
MKDIR prodoc
MKDIR prodoc\langref
5 ♦ To extract all examples in a procedure library directory, run the PROLIB utility. Note that
you must use double quotes because “Program Files” contains an embedded space:
xxv
Progress Language Tutorial for Windows
To extract one example, run PROLIB and specify the file that you want to extract as it is
stored in the procedure library:
Progress Messages
Progress displays several types of messages to inform you of routine and unusual occurrences:
• Compile messages inform you of errors found while Progress is reading and analyzing a
procedure prior to running it (for example, if a procedure references a table name that is
not defined in the database).
• Startup messages inform you of unusual conditions detected while Progress is getting
ready to execute (for example, if you entered an invalid startup parameter).
• Continues execution, subject to the error-processing actions that you specify, or that are
assumed, as part of the procedure. This is the most common action taken following
execution messages.
• Returns to the Progress Procedure Editor so that you can correct an error in a procedure.
This is the usual action taken following compiler messages.
• Halts processing of a procedure and returns immediately to the Procedure Editor. This
does not happen often.
xxvi
Preface
Progress messages end with a message number in parentheses. In this example, the message
number is 200:
Use Progress online help to get more information about Progress messages. Many Progress
tools include the following Help menu options to provide information about messages:
• Choose Help→ Recent Messages to display detailed descriptions of the most recent
Progress message and all other messages returned in the current session.
• Choose Help→ Messages, then enter the message number to display a description of any
Progress message. (If you encounter an error that terminates Progress, make a note of the
message number before restarting.)
xxvii
Progress Language Tutorial for Windows
Getting Started
Progress Electronic Documentation Installation and Configuration Guide (Hard copy only)
A booklet that describes how to install the Progress EDOC viewer and collection on UNIX
and Windows.
A manual that describes how to install and set up Progress Version 9.1 for the UNIX
operating system.
A manual that describes how to install and set up Progress Version 9.1 for all supported
Windows and Citrix MetaFrame operating systems.
A guide that provides a brief description of each new feature of the release. The booklet
also explains where to find more detailed information in the documentation set about each
new feature.
Progress Master Glossary for Windows and Progress Master Glossary for Character (EDOC
only)
Platform-specific master glossaries for the Progress documentation set. These books are
in electronic format only.
xxviii
Preface
Progress Master Index and Glossary for Windows and Progress Master Index and Glossary for
Character (Hard copy only)
Platform-specific master indexes and glossaries for the Progress hard-copy documentation
set.
A reference manual that describes the Progress startup commands and parameters in
alphabetical order.
A booklet that explains how Progress software and media are packaged. An icon-based
map groups the documentation by functionality, providing an overall view of the
documentation set. Welcome to Progress also provides descriptions of the various services
Progress Software Corporation offers.
Development Tools
Progress ADM 2 Guide
A programmer’s guide to using the Progress AppBuilder visual layout editor. AppBuilder
is a Rapid Application Development (RAD) tool that can significantly reduce the time and
effort required to create Progress applications.
Progress Basic Database Tools (Character only; information for Windows is in online help)
A guide for the Progress Database Administration tools, such as the Data Dictionary.
Progress Basic Development Tools (Character only; information for Windows is in online help)
A guide for the Progress development toolset, including the Progress Procedure Editor and
the Application Compiler.
xxix
Progress Language Tutorial for Windows
A guide for the Progress Application Debugger. The Debugger helps you trace and correct
programming errors by allowing you to monitor and modify procedure execution as it
happens.
A guide that describes how to develop and integrate an online help system for a Progress
application.
A guide that describes how to use the Progress Translation Manager tool to manage the
entire process of translating the text phrases in Progress applications.
A guide that describes how to use the Progress Visual Translator tool to translate text
phrases from procedures into one or more spoken languages.
Reporting Tools
Progress Report Builder Deployment Guide (Windows only)
An administration and development guide for generating Report Builder reports using the
Progress Report Engine.
A tutorial that provides step-by-step instructions for creating eight sample Report Builder
reports.
A guide for system administrators that describes how to set up and maintain the Results
product in a graphical environment. This guide also describes how to program, customize,
and package Results with your own products. In addition, it describes how to convert
character-based Results applications to graphical Results applications.
xxx
Preface
Progress Results User’s Guide for Windows and Progress Results User’s Guide for UNIX
Platform-specific guides for users with little or no programming experience that explain
how to query, report, and update information with Results. Each guide also helps advanced
users and application developers customize and integrate Results into their own
applications.
4GL
Building Distributed Applications Using the Progress AppServer
A guide to accessing non-Progress applications from Progress. This guide describes how
to use system clipboards, UNIX named pipes, Windows dynamic link libraries, Windows
dynamic data exchange, Windows ActiveX controls, and the Progress Host Language Call
Interface to communicate with non-Progress applications and extend Progress
functionality.
A guide to developing Progress applications for markets worldwide. The guide covers
both internationalization—writing an application so that it adapts readily to different
locales (languages, cultures, or regions)—and localization—adapting an application to
different locales.
A three-volume reference set that contains extensive descriptions and examples for each
statement, phrase, function, operator, widget, attribute, method, and event in the Progress
language.
xxxi
Progress Language Tutorial for Windows
Database
Progress Database Design Guide
A guide that uses a sample database and the Progress Data Dictionary to illustrate the
fundamental principles of relational database design. Topics include relationships,
normalization, indexing, and database triggers.
This guide describes Progress database administration concepts and procedures. The
procedures allow you to create and maintain your Progress databases and manage their
performance.
DataServers
Progress DataServer Guides
These guides describe how to use the DataServers to access non-Progress databases. They
provide instructions for building the DataServer modules, a discussion of programming
considerations, and a tutorial. Each DataServer has its own guide, for example, the
Progress DataServer for ODBC Guide, the Progress DataServer for ORACLE Guide, or
the Progress/400 Product Guide.
The Enterprise DataServer for ODBC includes MERANT ODBC drivers for all the
supported data sources. For configuration information, see the MERANT documentation,
which is available as a PDF file in installation-path\odbc. To read this file you must
have the Adobe Acrobat Reader Version 3.1 or higher installed on your system. If you do
not have the Adobe Acrobat Reader, you can download it from the Adobe Web site at:
http://www.adobe.com/prodindex/acrobat/readstep.html.
SQL-89/Open Access
Progress Embedded SQL-89 Guide and Reference
xxxii
Preface
A guide that describes how to write and deploy Java and ActiveX applications that run as
clients of the Progress AppServer. The guide includes information about how to expose
the AppServer as a set of Java classes or as an ActiveX server.
A user guide and reference for programmers who use interactive Progress/SQL-89. It
includes information on all supported SQL-89 statements, SQL-89 Data Manipulation
Language components, SQL-89 Data Definition Language components, and supported
Progress functions.
SQL-92
Progress Embedded SQL-92 Guide and Reference
A guide to the Java Database Connectivity (JDBC) interface and the Progress SQL-92
JDBC driver. It describes how to set up and use the driver and details the driver’s support
for the JDBC interface.
A guide to the ODBC interface and the Progress SQL-92 ODBC driver. It describes how
to set up and use the driver and details the driver’s support for the ODBC interface.
A user guide and reference for programmers who use Progress SQL-92. It includes
information on all supported SQL-92 statements, SQL-92 Data Manipulation Language
components, SQL-92 Data Definition Language components, and Progress functions. The
guide describes how to use the Progress SQL-92 Java classes and how to create and use
Java stored procedures and triggers.
xxxiii
Progress Language Tutorial for Windows
Deployment
Progress Client Deployment Guide
A guide that describes the client deployment process and application administration
concepts and procedures.
A guide to using the Developer’s Toolkit. This guide describes the advantages and
disadvantages of different strategies for deploying Progress applications and explains how
you can use the Toolkit to deploy applications with your selected strategy.
A guide that explains how to use the Progress toolset to build applications that are portable
across all supported operating systems, user interfaces, and databases, following the
Progress programming model.
WebSpeed
Getting Started with WebSpeed
Provides an introduction to the WebSpeed Workshop tools for creating Web applications.
It introduces you to all the components of the WebSpeed Workshop and takes you through
the process of creating your own Intranet application.
Provides instructions for installing WebSpeed on Windows and UNIX systems. It also
discusses designing WebSpeed environments, configuring WebSpeed Brokers,
WebSpeed Agents, and the NameServer, and connecting to a variety of data sources.
Provides a complete overview of WebSpeed and the guidance necessary to develop and
deploy WebSpeed applications on the Web.
A booklet that provides a brief description of each new feature of the release. The booklet
also explains where to find more detailed information in the documentation set about each
new feature.
xxxiv
Preface
A booklet that explains how WebSpeed software and media are packaged. Welcome to
WebSpeed! also provides descriptions of the various services Progress Software
Corporation offers.
Reference
Pocket Progress (Hard copy only)
A reference that lets you quickly look up information about the Progress language or
programming environment.
A reference that lets you quickly look up information about the SpeedScript language or
the WebSpeed programming environment.
xxxv
Progress Language Tutorial for Windows
xxxvi
1
Welcome to Progress
Welcome, and congratulations for choosing Progress as your development product for database
applications. Progress has a rich array of features and options, all contributing to an application
development environment that allows you to deliver complete database applications quickly
and easily. This tutorial couldn’t possibly cover all the features of Progress, but it does cover
those features that you need to begin coding right away.
The tutorial focuses on teaching you the Progress application development language. You’ll use
the demonstration database that comes with Progress to jump past database development and
into code development. You’re ready right now to discover why programming in the Progress
4GL is the best way to turn your ideas into robust applications.
Before you begin the tutorial, make sure that your hardware is set up correctly and that Progress
is installed and ready to go. For complete installation and setup instructions, see the Progress
Installation and Configuration Guide Version 9 for Windows or Progress Installation and
Configuration Guide Version 9 for UNIX.
This chapter introduces you to some fundamental concepts and terminology. After you read this
chapter, you’ll be ready to begin working with the software in Chapter 2, “Getting Started.”
This contains information on:
1. Second Skin Scuba calls All Around Sports to place orders for its annual “Deep Savings
Sale.” Before the sales representative (sales rep) can take the order, she needs to retrieve
the file on Second Skin Scuba from the customer filing cabinets. Once she finds the folder,
she copies the billing and shipping addresses from the folder onto an order form.
2. The sales rep writes down the name, quantity, and price of each item that Second Skin
Scuba wants. Referring to a typed list, the sales rep quotes prices and calculates the grand
total. After hanging up, the sales rep copies all the information neatly onto the order from.
3. The sales rep now needs to walk to the inventory filing cabinet, make sure the items are in
stock, and subtract the newly sold items from the inventory sheets. Finally, the sales rep
stores the order form where the Finance and Shipping departments can make copies.
1–2
Welcome to Progress
Figure 1–1 shows the All Around Sports paper-based ordering process.
Customers
1 Check
Customer Second Skin Scuba
Account
Information Folder
Orders
Order Form
2 Complete
Ship To: Second Skin Scuba
Order Form Bill To:
Inventory
Inventory Sheet
3 Update
Inventory
ITEM QTY
Buoyancy Vests 100 92
Fins 110
Swim Goggles 200
Wet Suits 104 88
1–3
Progress Language Tutorial for Windows
Both management and the sales reps agree that the sales reps need to spend more time with their
customers and less time on paperwork. Management decides that the time is right to bring
computer professionals into All Around Sports. Management envisions a system where the
sales reps can use computer terminals on their desks to take orders and check inventory while
they are still on the phone with their customers.
1. Move the business information from paper to an electronic form that can be stored in a
computer. This step involves:
a. Gathering together the relevant business information, called data, and analyzing the
relationships among the data. At All Around Sports, the relevant data is in the
customer, order, and inventory filing cabinets.
b. Designing and creating an electronic storage structure for the data. The electronic
storage structure is called a database. A database that allows users to organize data
so that it’s easy to define relationships is called a relational database.
Progress provides the tools that let you easily design, create, and maintain relational
databases.
c. Creating computer programs that run with an overall look and feel and are easy to
learn and use.
1–4
Welcome to Progress
Progress provides the tools that let you create and maintain procedures quickly. When you
use Progress, you don’t have to program the low-level data-access routines that move data
around and take care of the database. This functionality is present and ready for you to tap
into from the very first Progress 4GL statement that you write.Your computer
instructions—also called code—can concentrate on displaying and manipulating the data
in the database.
The database and procedures that you create with Progress form an application—a complete
solution to a business problem. The first business problem that All Around Sports wants to
tackle is speeding up the sales and inventory process. To do this, it needs a sales and inventory
application. In other words, it needs a database for the sales and inventory data and procedures
to perform the business tasks associated with the sales and inventory process.
The bottom line is that Progress allows you to create complete solutions to business problems
quickly and easily. All Around Sports agrees and joins the fast growing list of Progress
application developers.
Store data
Relational Database
Define tasks
Application Language
Write code and verify language
Procedure Editor syntax
1–5
Progress Language Tutorial for Windows
1–6
Welcome to Progress
Figure 1–3 illustrates the relationship of the sales and inventory paper filing system to a
database.
Paper
Tables
Customer Customer
Information
Folders
Database
Inventory Item
Sheets
1–7
Progress Language Tutorial for Windows
In a database table, each discrete piece of information also represents the intersection of a row
and column and is called a field. In addition to the data, each field in a record includes a
descriptive name, just like the column heading in a paper table. For example, the customer’s
telephone number is one piece of information, and that information is stored in a field named
Phone. Each record in the Customer table has a Phone field. Figure 1–4 illustrates the structure
of a database.
Database
Table Table
= + ...
Table Record
Table
= + ...
Record
Field
1–8
Welcome to Progress
In a database, an index is a list that contains a value for each record in the table. When you define
an index, you choose the field or fields used to derive the index value for each record. For
example, if you choose the Name field as an index, Progress creates an index for the Customer
table that consists of a list of customer names, just like the list of tabs in the paper filing system.
A simple index is based on the value of one field, while a compound index is based on two or
more fields. Figure 1–5 shows an example of a simple and a compound index.
Simple Index
02176
Compound Index
Abbot, Jan
1–9
Progress Language Tutorial for Windows
Application Defaults
A major part of your application’s work involves presenting database fields for end users to
view and manipulate. Each time you access and display a field, you won’t have to write lots of
code—you can rely on Progress to use default information stored in the Data Dictionary to
properly present the data. Progress stores these defaults in a Progress database:
• Default display information for fields, such as display formats and help messages
• Default data access behavior for both fields and tables, such as data input checking
routines and default values
This ability to store defaults in the database saves time for developers. Using defaults makes it
easier to enforce data-access rules and reduces error-checking code, default value generation,
and display-formatting code in your procedures.
See Chapter 4, “Understanding the Database Environment,” for more information about the
Data Dictionary and Progress databases.
• Provides powerful statements that perform the work of multiple 3GL statements
• Employs a highly readable syntax that is succinct and much closer to natural English
1–10
Welcome to Progress
Besides giving you the complete flexibility of a general-use programming language, the
Progress 4GL allows you to do two main tasks: access and manipulate data in a database, and
present that data for user inspection and interaction.
Look at this Progress code:
This compact loop, where Customer is the name of a database table, performs these functions:
• Reads the contents of each Customer table record, beginning with the first record
• Accesses the default display format for each field in the record
• Pauses and waits for the user to signal when to display more information
Each of these tasks would require many lines of 3GL code. The Progress 4GL executes these
tasks implicitly.
Progress also makes useful assumptions about what you want, relieving you from the tedious
task of coding every tiny detail. For example, notice that the DISPLAY statement in the
example does not offer any detail about how to format the output. Progress constructs a default
output format by combining default formatting information for each database field with default
output algorithms. This intuitive handling of defaults is called default behavior. This advantage
does not come at the expense of customization. Every Progress statement includes options that
allow you to override default behavior.
You’ll find yourself relying on default behavior in the beginning of a project so that you can
quickly create a prototype. Later, you’ll get more involved with programming options to fine
tune your application.
1–11
Progress Language Tutorial for Windows
1.6 Summary
First, you learned how Progress can solve tough business problems. A computerized solution to
a business problem is called an application. An application consists of a database and Progress
procedures. Here’s a summary of important points about databases:
• A database is an electronic filing system for organizing and storing data that relates to a
broad subject area, like sales and inventory.
• A database that lets you organize data so you can easily define and exploit relationships
among data is called a relational database.
• At the top level, a database is made up of tables. A table is a collection of records about a
specific subject, like customers.
• A record is a collection of pieces of information, called fields, about one thing, like a single
customer.
• An index uses data from a field or fields as the basis for searching, sorting, or otherwise
processing records.
Progress procedures are collections of statements that let you define tasks. Here are some
important points about Progress procedures:
• You create procedures with the Progress fourth generation language (4GL).
• A 4GL is much easier to use than a third generation language (3GL) because 4GL
statements perform the work of many 3GL statements and use default behavior to relieve
you from programming every tiny detail.
1–12
Welcome to Progress
You also learned about the Progress tools for creating and maintaining applications:
• You can also use the Data Dictionary to store display and data-access defaults, which help
cut down on redundant coding.
• The Procedure Editor lets you create, edit, and run procedures. The Procedure Editor also
lets you check the syntax of your code.
1–13
Progress Language Tutorial for Windows
1–14
2
Getting Started
This chapter teaches you the essentials of starting Progress and using the basic tools.
Specifically, this chapter covers:
• Starting Progress
1. Confirm that the Progress Data Dictionary, Procedure Editor, and Application Compiler
are properly installed on your system.
2. Create a directory named mytut. The mytut directory will be your working directory for
all tutorial exercises.
3. Create a subdirectory of mytut named sports. The sports subdirectory will contain
procedures that are part of the Progress demonstration database. The tutorial uses the
demonstration database, named sports, as the basis for programming examples and
exercises.
4. Extract the example source programs from the prodoc.pl procedure library according to
Section 2.2 below. The procedures in this book assume that your program examples are in
a working directory called Progress\Wrk\prodoc\langtut.
If you run into problems with these tasks, consult the Progress Installation Notes, your
operating system documentation, or your system administrator.
2.3.1 Windows
Click the Start button on the taskbar and choose Programs→ Progress→ Desktop. Click on the
Progress Desktop program option to display the ADE Desktop.
2–2
Getting Started
• Menu bar — The menu bar is a horizontal list of menu titles. A menu is a collection of
related options. You’ll learn how to use menus later in this chapter.
• Tool buttons — Tool buttons are images that you click to start a tool. There are seven tool
buttons on the ADE Desktop. From left to right, the tool buttons representing these tools:
– Data Dictionary
– Procedure Editor
– AppBuilder
– Results
– Report Builder
– Application Debugger
– Translation Manager.
• When you are running Progress either on Windows 95 or on Windows NT 4.0, the labels
do not automatically display. Pause your mouse pointer over each tool button to display a
ToolTip that identifies each icon by its tool name. A ToolTip is a brief text message that
defines various user interface elements on Windows 95 or on Windows NT 4.0.
NOTE: If you are running Progress on Windows NT 3.51, each tool button has a permanent
label displayed.
2–3
Progress Language Tutorial for Windows
As you can tell from the ADE Desktop, there are several tools that you can explore from the
ADE Desktop. However, this tutorial focuses on the Procedure Editor and the Data Dictionary.
Let’s get started with the Procedure Editor. Click the Procedure Editor icon on the ADE
Desktop to start the Procedure Editor.
Menu bar
Insertion point
Procedure area
Status area
2–4
Getting Started
• Title bar —Shows the name of the current edit buffer. An edit buffer is a temporary work
area for procedures under construction in the Procedure Editor. The Procedure Editor
allows you to have several buffers open simultaneously. If a buffer has no name assigned,
it appears as “Untitled” followed by a number to make the name unique (for example,
Untitled:1).
• Menu bar — Allows you to access and execute tasks. Each item on the menu bar is a
menu title. A menu provides access to menu options. Menu options perform tasks.
• Insertion point — Marks the location where text appears when you start typing.
• Procedure area — The visible part of the current edit buffer. This is where you type and
edit Progress procedures.
• Status area — The one line panel at the bottom of the window where Progress displays
helpful information for the user.
3 ♦ On the PRO*Tools Tool Buttons bar, select Propath, which is the button with the blue
letters, .P, .W, and .R on the yellow swirl. The Propath Editor displays.
4 ♦ In the Propath Editor, select the Add button. Enter the name of the directory where your
sample programs reside, for example, C:\Progress\Wrk\prodoc\langtut, and select
OK.
5 ♦ Your new directory remains highlighted. Select the Move Down button and move your
new directory below (current directory). You may rearrange your directories for more
efficient searching.
6 ♦ Select OK. An alert box will display. Select Yes to save this setting to your startup file.
2–5
Progress Language Tutorial for Windows
Exercise 1 ♦ Enter the name of the on-line demonstration program. Because you have modified the
PROPATH, you do not have to enter the entire absolute address. The following example
shows how to enter this command on Windows:
RUN widget.p.
RUN c:\Progress\Wrk\prodoc\langtut\widget.p.
2–6
Getting Started
Window widget
Instructions
(Text widget)
Button widgets
4 ♦ Follow the instructions you see on your display. You can press ESC at any time to end the
on-line tutorial, and ESC again to return to the Procedure Editor.
2–7
Progress Language Tutorial for Windows
In the tutorial, you use just one of your mouse buttons. Take a moment to determine which of
the buttons on your mouse is set up as the main button. You use this main button to invoke two
mouse functions: choosing and executing. When you single-click a display item with the main
mouse button, you are signifying that you want to work with that item. This action is called
choosing or selecting.
When you double-click the main mouse button, you are executing the implied function of the
widget, if it has one. For example, double-clicking a minimized window restores the window.
In some cases, clicking a display item both chooses and executes the associated function. For
example, clicking a button chooses the button and executes the button’s function.
Common
Key Keyboard
Function Mapping Description
2–8
Getting Started
Menu Description
File Create new edit buffers; open text files that contain Progress language
statements; save the contents of an edit buffer to a text file; print the
current buffer; escape to the operating system; exit the Procedure Editor.
Edit Manipulate blocks of text in edit buffers; insert a text file or a database
field into the current edit buffer.
Search Search and replace text in the current edit buffer; go to a specified line
position in the current edit buffer.
Compile Run, compile, and check the syntax of the Progress code contained in the
current buffer.
Help Get information about the current tool, system messages, the 4GL, and the
Progress system.
2–9
Progress Language Tutorial for Windows
Figure 2–3 displays the File pull-down menu of the Procedure Editor.
2 ♦ Use the ← and → keys to navigate through the menus on the menu bar and highlight the
File menu.
4 ♦ Use the ↓ and ↑ keys to navigate through the menu options on the File menu and highlight
the Exit menu option. Then press RETURN or ENTER to choose the highlighted menu
option.
2–10
Getting Started
3 ♦ Type x to choose the Exit menu option from the File menu.
Finally, you can also execute menu options without entering the menu bar by using accelerator
keys. Accelerator keys are the quickest way to access a menu option. When a menu option has
an accelerator key associated with it, the key is listed next to the option on the menu. For
example, F6 is the accelerator key for the Save option. Many of the Progress key functions
shown in Table 2–2 are also accelerator keys; that is, they execute menu commands.
The mouse is the best way to explore menus in a tool and find out about available menu options.
Once you become familiar with a tool, accelerator keys offer a quicker way to get things done.
• The menu option that exits a tool is always the last menu option on the first menu.
• A Help menu is available on all menu bars in the Progress toolset and is always the last
menu on the menu bar.
• Some menu options have symbols that provide information about how they work. Menu
options that do not use symbols are commands and simply execute the function that they
represent.
2–11
Progress Language Tutorial for Windows
menu option → Indicates that the menu option is a submenu. When the user chooses
a submenu from a menu, additional menu options appear next to the
original pull-down menu.
menu option . . . Indicates that the menu option requires additional user input. When
the user chooses a menu option with this symbol, a dialog box
appears. Progress uses dialog boxes to prompt users for additional
input before executing the function.
√ menu option Indicates that the menu option is a toggle for a tool setting. When the
symbol is present, the setting is active or in the ON state.
• The Progress documentation set uses the following notation to represent a menu option.
File→ Exit
This notation is a shorthand representation of the Exit option on the File menu.
2–12
Getting Started
Table 2–4 presents basic keys available in the Procedure Editor that help you move around and
edit text in the current buffer.
Common
Keyboard
Key Function Mapping on Windows
Description
2–13
Progress Language Tutorial for Windows
Common
Keyboard
Key Function Mapping on Windows
Description
The next section describes more advanced text editing techniques in the Procedure Editor.
2 ♦ Hold down the mouse selection button and drag to highlight the text block.
4 ♦ Choose the desired text-block operation. You can cut a text block, copy a text block, or
paste over a text block.
The Procedure Editor uses the Windows Clipboard for these three operations: cut, copy, and
paste. When you cut or copy a block of text, the text goes onto the Clipboard and remains there
until you cut or copy another block of text or exit the Procedure Editor. A paste operation inserts
the contents of the Clipboard at the current cursor location.
2–14
Getting Started
Table 2–5 lists the set of keys that allow you to define a block and execute a text-block operation
on Windows.
Common
Keyboard
Mapping on
Key
Windows
Function Description
COPY CTL+C Copy the current text block into the cut/paste buffer.
This key function is the same as Edit→ Copy.
CUT CTL+X Cut the current text block into the cut/paste buffer. This
key function is the same as Edit→ Cut.
PASTE CTL+V Paste the contents of the cut/paste buffer at the current
cursor location. This key function is the same as Edit→
Paste.
With this functionality, you can cut and paste code from one position to another in the current
edit buffer. You can also cut and paste between edit buffers.
2–15
Progress Language Tutorial for Windows
NOTE: Although you can open multiple buffers in the Procedure Editor, you can open only
one buffer for each operating system file.
Table 2–6 summarizes the Procedure Editor features that help you create and manage buffers.
Create a new buffer. File→ New Create a new “Untitled” buffer and make
it the current buffer.
Open a procedure file File→ Open Open a specified procedure file into a
and create a buffer for new buffer named after the procedure
it. filename. The newly opened buffer
becomes the current buffer.
Close a buffer. File→ Close Close the current buffer. If you modified
the contents of the buffer, Progress
notifies you and asks you if you would
like to save the modifications to a
procedure file.
View multiple buffers. File→ New Open multiple windows for viewing
Procedure Window buffers. A dialog box prompts you to
select buffers for viewing. Although you
can manipulate text in the view
windows, you can’t save any of the
changes.
Save the contents of a File→ Save Save the current buffer to a procedure
buffer to a procedure file. If the current buffer is “Untitled,”
file. the Save As dialog box prompts you for
the name of a procedure file.
Save the contents of a File→ Save As Save the contents of the current buffer to
buffer to a specified a specified procedure file.
procedure file.
Print the contents of a File→ Print Print the contents of the current buffer.
buffer.
List the open buffers. Buffer→ List Display a list of open buffers in the
Buffer List dialog box. You can go to
another buffer or save an open buffer
from this dialog box.
2–16
Getting Started
Go to the next open Buffer→ Next Make the next buffer in the buffer list the
buffer. Buffer current buffer.
Go to the previous open Buffer→ Previous Make the previous buffer in the buffer
buffer. Buffer list the current buffer.
Modify fonts. Buffer→ Font Select which font the current buffer uses.
Compile and run the Compile→ Run Compile and attempt to run the contents
contents of the buffer. of the current buffer as a Progress
procedure. If there are syntax errors in
the current buffer, Progress displays a
dialog box that contains a list of error
messages.
Check the contents of Compile→ Check Check the contents of the current buffer
the current buffer for Syntax for 4GL syntax errors. If there are syntax
4GL syntax errors. errors in the current buffer, Progress
displays a dialog box that contains a list
of error messages.
2–17
Progress Language Tutorial for Windows
This procedure contains the following Progress language constructs and elements:
• Phrases — A phrase is a collection of keywords and values that modify the way Progress
executes a statement. In the code above, the keyword WITH begins a frame phrase in the
DISPLAY statement. Phrases can contain options and values.
• Options — An option is like a phrase, only smaller. Options usually consist of a single
keyword and a possible accompanying value. Options also modify the way Progress
executes a statement. In the code above, the keyword AS is an option of the DEFINE
VARIABLE statement and the keyword CENTERED is an option in the frame phrase of
the DISPLAY statement.
Progress is a block-structured language—that is, you can group statements together into blocks.
Procedures are the largest block structures in Progress. Later in the tutorial, you’ll learn about
other types of blocks that can exist inside a procedure block.
2–18
Getting Started
A repeat block is similar to the repeat loop, which is found in many 3GLs) The following code
fragment shows a repeat block:
Block structures within a procedure normally begin with a block-header statement and end with
an END statement. You can use these block structures to apply processing services to a group
of statements.
You will learn about more Progress language constructs and blocks as you proceed through this
tutorial. To learn more about the syntax of the Progress language, see the Progress Language
Reference or the Progress On-line Reference module in the Progress help system.
• Press HELP to get information about the current window or dialog box. This is known as
context-sensitive help. Most dialog boxes in the Progress toolset also have a Help button
you can choose to get information about the dialog box.
• Use the Help menu from the menu bar to access information about the current tool or to
display reference information.
2–19
Progress Language Tutorial for Windows
Figure 2–4 shows the Help menu with the possible menu options displayed.
Help
2–20
Getting Started
2.11.2 Using the Help Topics: Windows Help Topics dialog box
The Progress help system organizes information into discrete units called help topics. An
individual help topic typically contains information about one thing, such as a particular dialog
box in the Progress Procedure Editor or a 4GL language element. When you access the help
system from a tool, you can display related help topics as they are organized under the various
tabs that display on the Help Topics: Windows Help Topics dialog box. Figure 2–5 shows the
Help Topics: Procedure Editor Help dialog box that displays when you access help from the
Procedure Editor.
NOTE: The Help Topics: Windows Help Topics dialog box title changes to reflect the
specific help that is displayed. The title change can help keep you oriented as to
which part of the help system you are currently using. For example, when you
display help from the Procedure Editor, the title bar in the dialog box reads Help
Topics: Procedure Editor Help. However, when you display help from the Data
Dictionary, the title bar in the dialog box reads Help Topics: Data Dictionary Help.
2–21
Progress Language Tutorial for Windows
2–22
Getting Started
The Find Tab allows you to search for specific words or phrases in a database that comprises
the actual words used in the help files. Figure 2–8 shows the Find Tab.
2–23
Progress Language Tutorial for Windows
1. Choose Help→ Help Topics from the Procedure Editor menu bar. The Help Topics:
Exercise
Procedure Editor Help dialog box displays with the Contents Tab on top.
2. On the Contents Tab, click on the book icon associated with the Procedure Editor Interface
Reference. Then, click on the Procedure Editor Window.
2–24
Getting Started
3. In the Notes section of the Procedure Editor Window topic, click on the Progress
Language Reference link to display the Progress Language Reference help window:
2–25
Progress Language Tutorial for Windows
4. Click on the Progress 4GL Cross Reference information link defined on the Progress
Language Reference topic to display the Progress 4GL Cross Reference:
2–26
Getting Started
When you exit the Procedure Editor, the editor checks the open buffers for unsaved changes. If
there are buffers with unsaved changes, the following dialog box appears:
If you choose the Yes button to save modified buffers, the Save Buffers with Changes dialog
box appears:
The box around a buffer name indicates that the buffer is selected. To toggle the selection of a
buffer in the list, click the buffer name. This dialog box presents three options:
• Save the selected buffers in the buffer list by choosing the Save Selected button.
• Opt not to save any buffers and exit the Procedure Editor by choosing the Save None
button.
• Cancel the exit and save operations and return to the Procedure Editor display by choosing
the Cancel button.
2–27
Progress Language Tutorial for Windows
2.13 Summary
Before you finish this chapter, take a moment to review your progress on these topics.
Starting Progress:
• To start Progress on Windows NT 3.51, double-click the Progress Desktop icon to display
the ADE Desktop. Then, to start the Procedure Editor, double-click on the Procedure
Editor tool button.
• To start Progress on Windows 95 or Windows NT 4.0, click the Start button on the taskbar
and choose Programs→ Progress→ Desktop. Click on the Progress Desktop program to
display the ADE Desktop. Then, to start the Procedure Editor, double-click on the
Procedure Editor tool button.
• The Procedure Editor is a text text editor that you can use to create, compile, and run
Progress procedures. A procedure is a series of Progress language statements that performs
a desired data processing task.
• A key function is an event in Progress that describes a behavior that occurs when you use
a particular keystroke or key combination. Some common key functions are HELP,
ENTER-MENUBAR, and GO. However, the keyboard mappings for specific keys may vary
depending on the console you are using and the platform on which Progress is running.
• Many functions of the Procedure Editor are accessible from the menus and menu
commands on the Procedure Editor menu bar.
• The computer displays that enable a user to accomplish tasks are called the user interface.
In Progress, interfaces are made up of objects, called widgets, that can be controls,
representations of data, decorations, or containers. Widgets also serve as receptors for user
input and application output.
• The Procedure Editor supports the basic editing keystrokes that are standard to most text
editors and word processors.
• You can define blocks of text to cut, copy, and paste in an edit buffer or between edit
buffers.
2–28
Getting Started
• A procedure file is a text file that contains one or more Progress procedures. By
convention, procedure files have a .p file extension.
• The Procedure Editor provides menu commands that allow you to edit and manage
multiple edit buffers and open and save procedure files.
• Phrases and options consist of keywords and values and alter the way Progress executes a
statement.
• Press HELP to access information about the current display or dialog box.
• Use the Help menu to access information about the current tool.
• You can access these sample procedures on line in the procedure libraries prodoc.pl and
prohelp.pl in the src directory where Progress is installed.
• The File→ Exit menu option allows you to exit the Procedure Editor and return to the
operating system or the tool that called the Editor.
2–29
Progress Language Tutorial for Windows
2–30
3
Programming the Progress Way
So far you’ve learned what Progress is about and you’ve had a chance to work with the
Procedure Editor. Now it’s time to begin working with the 4GL. This chapter covers what is
fundamental to every Progress application. First, the chapter presents the underlying concepts
and techniques of the Progress 4GL. Second, the chapter examines the components of a
Progress procedure. By the end of the chapter, you will be able to recognize a well-structured
Progress procedure and understand the function of its constituent parts.
Specifically, you’ll learn about:
In this chapter, you’ll see examples of complete Progress procedures. For now, your goal isn’t
to master all the language elements introduced. Instead, your goal is to become familiar with
and comfortable with the major components of a Progress procedure.
Progress Language Tutorial for Windows
• Make the application developer more productive by minimizing the amount of code
needed to create complete and powerful applications.
• Isolate the developer from as many portability issues as possible—let Progress handle
platform-specific issues during compile time or run time.
• Provide flexible and intelligent features that allow the end user to work intuitively and
productively with highly responsive Progress applications.
Chapter 1 discussed the nature of the 4GL and how it streamlines application development by
providing more functionality with less code. The second philosophy, easy portability, allows
you to focus on developing one application, using one programming language and one program
structure. Then, when you move your application to other platforms, you’ll see the benefits of
Progress’s portability philosophy:
The third philosophy, providing the end user with intuitive and responsive applications, takes a
little more time to present. Creating responsive applications requires a certain style of
coding—what Progress calls the Progress programming model. To use the programming model
effectively requires looking at the process of user and application interaction in a certain way.
The rest of this section discusses the concepts, terminology, and language elements that make
up the basic Progress programming model.
• The keyboard and the mouse are the user’s mechanism for communicating with your
application.
3–2
Programming the Progress Way
Fill-in fields
3–3
Progress Language Tutorial for Windows
NOTE: Progress supports a character client that runs in DOS only when DOS is running on
Windows. However, when a character client is running in this manner, the interface
that displays on both of these platforms is a character interface, not a graphical one.
Window
Fill-in Fields
3–4
Programming the Progress Way
3–5
Progress Language Tutorial for Windows
Exercise 1 ♦ From the Procedure Editor, open the lt-03-01.p procedure. (Use the Open option on the
File menu.) Don’t worry about trying to understand the code right now.
2 ♦ Choose Compile→ Run. You now see the basic interface you saw in Figure 3–2:
Input focus
Notice that the cursor is positioned in Field1. This cursor illustrates two points:
• The user is normally aware of which widget has input focus by the visual cues
provided automatically by Progress and the underlying operating system.
3 ♦ Press TAB to move input focus among the fields. These actions illustrate the last important
point about input focus: after startup, the location of input focus is normally controlled by
the user. In other words, users can enter data into the fill-in fields in any order.
3–6
Programming the Progress Way
4 ♦ Move input focus to Field3 and press RETURN to end the procedure.
Because the user has more control of input focus, the user has more control of the application.
The application’s job is to respond to the user’s events in a way that correctly interprets the
user’s desires. Because of this reliance on events, this type of programming model is called
event-driven programming.
lt-03-01.p
1. The first part of a Progress procedure defines widgets. The three DEFINE VARIABLE
statements create three new variables for text data (AS CHARACTER) and initialize them
with a string (INITIAL " "). Progress displays variables or database fields as fill-in fields
by default.
2. The second part of a Progress procedure creates the user interface. The DISPLAY
statement creates an interface that consists of the default window, blank lines (SKIP),
fill-in fields, and labels for the fields (SIDE-LABELS). This DISPLAY statement also
centers the widgets within the default window (CENTERED) and suppresses the default
border that surrounds the widgets (NO-BOX).
3. The third part of a Progress procedure enables the widgets of the user interface. The
ENABLE statement turns on the widgets. By default, the first widget listed in an ENABLE
statement gets initial input focus. Assigning input focus to Field1 means that Field1
receives events at startup.
3–7
Progress Language Tutorial for Windows
4. The fourth part of a Progress procedure blocks execution. Now that you have
presented a complete interface and enabled it for the user, you have to pause the execution
of the procedure to allow the user to interact with the interface. This process is called
blocking. If you did not block, Progress would execute the code to the end of the file and
end the procedure.
The WAIT-FOR statement is your primary tool for blocking execution. With it, you
establish the condition that signals that the user has finished working with the current
interface. In this case, if the user presses RETURN (WAIT-FOR RETURN) while input
focus is in Field3 (OF Field3), then the procedure completes.
Every Progress procedure that interacts with the user follows this basic four-step process:
1. Define widgets.
2. Display widgets.
3. Enable widgets.
4. Block execution.
You explicitly code these four steps. Progress provides much of the additional functionality
required to make this interface flexible and responsive to the user. For example:
• Progress takes care of the normal events associated with a widget. For example, the user
might want to type new text into the fields. Progress handles these events by default.
3–8
Programming the Progress Way
Now you need a way to program new responses for widget-event pairs. For example, in the
“Hello Progress World!” application, suppose you want to display a message as soon as input
focus moves to Field3. The Progress programming structure for this task consists of an ON
statement and a block of code called a trigger. The ON statement is the device that establishes
the condition that executes a trigger. A trigger is the code that Progress executes only when a
specified widget receives a specified event. A trigger is a programmed response. A programmed
response occurs before the default response.
1 ♦ Open lt-03-02.p.
3 ♦ Click Field3. Notice the message that now appears at the bottom of the window:
Message
3–9
Progress Language Tutorial for Windows
lt-03-02.p
/* TRIGGER */
ON ENTRY OF Field3
DO:
MESSAGE "Press Return in Field3 to exit the procedure.".
END.
Notice the new language element in the example, the ON statement. The ON statement sets up
the trigger. In the example, ENTRY is the event and Field3 is the widget. (ENTRY is an event
that occurs when the user or the application gives input focus to a widget.) The MESSAGE
statement is the trigger that occurs when Field3 receives the ENTRY event.
NOTE: By default, window widgets reserve space at the bottom of the window to display
messages from Progress and your application. The MESSAGE statement
automatically outputs text enclosed in quotes to the message area.
This is a partial syntax for the ON statement. (For complete syntax descriptions, see the
Progress Language Reference or access the On-line Language Reference module of the help
system.)
SYNTAX
ON event-list OF widget-list
[ OR event-list OF widget-list ] ...
trigger-block
3–10
Programming the Progress Way
Components Description
OR Use the OR phrase to create another widget-event pair that can execute
the code in the trigger block.
ON event OF widget
MESSAGE "No DO syntax needed.".
Defining triggers is part of the basic Progress code template. Adding triggers to the basic
template gives you this new coding template:
1. Define widgets.
2. Display widgets.
3. Enable widgets.
4. Define triggers.
5. Block execution.
3–11
Progress Language Tutorial for Windows
3–12
Programming the Progress Way
Yes
Programmed Response
TRIGGER
ON event OF widget
DO:
Programmed Response
END.
Yes
Done
3–13
Progress Language Tutorial for Windows
When you create the interface (define, display, and enable widgets), Progress automatically
provides all the default behavior the user needs as they interact with that interface. The real work
that your application does normally occurs as a response to a specific event from the user. That
means that much of your functionality resides inside triggers. A good way to visualize this
structure is to think of the code outside of the triggers as the code that creates and controls your
interface. The code inside your triggers performs the tasks for which you created the
application. The ON statement is the connection between the interface and the functionality
inside the trigger.
3.2 Widgets
Since widgets make up the part of your application with which the end user interacts, it’s
important to thoroughly understand how to use each widget. Table 3–1 provides a brief
description of each type of widget.
Widget Use
Fill-in field Displays and accepts any kind of data. When you display a variable or
database field, the fill-in field is the default widget.
Text Displays any kind of data as read-only text. The text widget is useful for
creating lists, reports, or labels.
Selection list Presents a list of value choices for a character variable or database field. A
selection list can use scroll bars and allow multiple selections.
Combo box Like a selection list, a combo box presents a list of value choices for a
character variable or database field. The value list of a combo box is only
visible after a user chooses the button next to the combo box. When the
user selects a value, the combo box closes and displays only the selected
value.
Editor Displays and accepts as input character variables or database fields that
can contain long strings. Use editor widgets where you want users to enter
notes, descriptions, and so on.
3–14
Programming the Progress Way
Widget Use
Radio set Displays and accepts data that has a limited number of possible values.
Use radio sets to display options where the user understands that only one
option can be true at a time.
Toggle box Displays and accepts data that has either a YES/NO or TRUE/FALSE
value.
Browser Displays and optionally updates key fields from a subset of database
records. You define the subset of records and fields which the browse
displays. The user interacts with a browse in the same way as a selection
list.
Slider Displays and manipulates integer data. When the user moves the pointer
on the trackbar inside the slider, the value changes proportionally to the
move.
Rectangle Creates a box. You might use a rectangle to group a set of widgets.
Button Explicitly executes tasks. Use a button to allow the user to execute triggers
or control the interface.
Dialog box Creates a frame that overlays the current interface. The main interface is
disabled until the user is done working with the dialog box. A dialog box
notifies the user of important information or requests more information. A
dialog box is a container for other widgets.
Menu bar Creates a collection of pull-down menus in a window. A menu bar can be
attached only to a window widget.
Since the goal of this section is to introduce widgets in general, you’ll work with just four
widgets: fill-in fields, text widgets, rectangle widgets, and button widgets. The tutorial covers
other widgets in later chapters.
3–15
Progress Language Tutorial for Windows
• Window Widgets — Window widgets are workspace for your application. A window
contains all other widgets. Character interfaces use one window, while graphical
interfaces can use multiple windows.
• Container Widgets — Container widgets allow you to organize data, action, and graphic
widgets. Container widgets include frames and dialog boxes.
• Data Widgets — Data widgets are the widgets you use to represent data from fields and
variables. Data widgets include fill-in fields, text, editors, selection lists, combo boxes,
radio sets, toggle boxes, sliders, and browse widgets.
• Action Widgets — Action widgets allow the user to direct the operation of your
application. Menus provide groups of related processing options while buttons execute a
single option. Buttons, menu bars, submenus, and menu items make up action widgets.
• Graphic Widgets — Graphic widgets help you decorate your interface. Use rectangles to
make different kinds of borders. Images, which are available on graphical interface
systems, allow you to include high-resolution graphics in your interface.
3–16
Programming the Progress Way
Before describing how you dress up a field or variable as a widget, you need to understand the
syntax for defining variables. This is a partial syntax.
SYNTAX
Component Description
variable-name A name you supply to uniquely identify the variable. The variable
name must begin with an alphabetic character (A–Z, a–z).
LABEL string Specifies a label that Progress uses when it displays the widget. If you
do not specify a label, the variable name is the default label.
So, the DEFINE VARIABLE statement defines a variable and allows you to define the default
data representation for that variable. The Progress language element for specifying data widgets
is the VIEW-AS phrase. This is the general syntax.
SYNTAX
3–17
Progress Language Tutorial for Windows
Component Description
widget-type Specify the Progress keyword that indicates the appropriate data
representation. The keywords are:
FILL-IN
TEXT
SELECTION-LIST
COMBO-BOX
RADIO-SET
TOGGLE-BOX
EDITOR
SLIDER
options Specific widgets have options that let you define functional and display
characteristics.
Note that VIEW-AS is a phrase, not a statement. This means that VIEW-AS can be attached to
certain Progress statements to expand the function of the statement. When you attach the
VIEW-AS phrase to a DEFINE VARIABLE statement, you are defining the default data
representation of the variable as shown in this brief code example:
Whenever Progress displays Field1, it displays the variable as a text widget. (Text widgets are
typically used for labels and reports.) If you do not use a VIEW-AS phrase in the DEFINE
VARIABLE statement, Progress displays the variable as a fill-in field.
You don’t have to stick with the default data representation, however. You can override the
default widget for a variable or a database field by attaching the VIEW-AS phrase to a run-time
screen output statement, like this DISPLAY statement shows:
3–18
Programming the Progress Way
Examine the code below, and load it into the Procedure Editor if you like:
lt-03-03.p
ENABLE Field1.
Defining Buttons
Button and rectangle widgets differ from data representations in that they are exclusively user
interface components and are not related to database fields or variables. The button allows the
user to execute a function directly and the rectangle is an interface decoration.
This is a partial syntax for the DEFINE BUTTON statement.
SYNTAX
Typically, you associate a button with a trigger in your code. The button then becomes a tool
that lets a user explicitly execute a trigger.
3–19
Progress Language Tutorial for Windows
1 ♦ Open lt-03-04.p.
Exercise 2 ♦ Choose Compile→ Run. The interface, shown below, contains two buttons, Display Data
and Exit:
3 ♦ Choose the Display Data button. The trigger executes on the CHOOSE event of the button
widget, and displays Field1 as a text widget.
3–20
Programming the Progress Way
lt-03-04.p
ON CHOOSE OF btn-Data
DO:
DISPLAY Field1.
END.
The Exit button does not have a trigger associated with it. That’s because the procedure uses the
CHOOSE event of btn-Exit to signal the unblocking response. Since this is a default response,
the procedure doesn’t require a trigger and a programmed response.
Defining Rectangles
The basic syntax for defining a rectangle lets you decide the size of the rectangle, whether it’s
filled or empty, and how wide the edge is.
This is a partial syntax for the DEFINE RECTANGLE statement.
SYNTAX
3–21
Progress Language Tutorial for Windows
The steps below use the same code as the last exercise, modified to use a DEFINE
RECTANGLE statement:
1 ♦ Open lt-03-05.p.
Exercise
2 ♦ Choose Compile→ Run. The interface, shown below, contains two buttons:
Display Rectangle and Exit:
3–22
Programming the Progress Way
lt-03-05.p
ON CHOOSE OF btn-Rect
DO:
DISPLAY Rect1 WITH NO-BOX.
END.
As shown at point 1, the size of the rectangle is 12 columns (width) by 8 rows (height). The
NO-FILL option makes the rectangle empty. The EDGE-CHARS option specifies a border
that’s two characters wide. The trigger executes on the CHOOSE event of the btn-Rect widget,
and displays a rectangle.
Defining Frames
A frame is a container for widgets. Frames allow you to organize data, action, and graphic
widgets. Data, action, and graphic widgets that can be placed in a frame (or dialog box) are
called field-level widgets.
You cannot place widgets in a window unless they are first contained in a frame widget. (One
exception: menu bars go directly into the window.) If you don’t specify a frame, Progress
creates one for you. This frame is called the default frame.
3–23
Progress Language Tutorial for Windows
1 ♦ Open lt-03-06.p.
Exercise 2 ♦ Choose Compile→ Run. The interface you see is the same “Hello Progress World!”
interface, except that a graphic border surrounds the fill-in fields. The graphic border
shows the area of the default frame follows:
Default frame
graphic border
3 ♦ Move input focus to Field3 and press RETURN to end the procedure.
3–24
Programming the Progress Way
lt-03-06.p
ON ENTRY OF Field3
DO:
MESSAGE "Press Return in Field3 to exit the procedure.".
END.
In the code you saw earlier, the DISPLAY statement included the NO-BOX option, which
suppressed the default frame border. Since the option is not included here, as shown at point 1,
the border appears.
The DEFINE FRAME statement allows you to name a frame and list the field-level widgets it
contains. You also have several options for controlling the arrangement of the widgets within
the frame, such as the SKIP option, which you have already seen.
Here is a partial syntax.
SYNTAX
The following table describes the elements of the DEFINE FRAME statement:
3–25
Progress Language Tutorial for Windows
Component Description
form-item Form items can include database fields, variables that have been
previously defined, buttons, rectangles, and SKIP options.
Frame phrase The options shown at the bottom of the syntax diagram make up what is
(WITH) called the frame phrase. The frame phrase, which begins with WITH, lets
you specify options that affect the frame itself or all the widgets in the
frame as a group.
The frame phrase has other important applications outside of the DEFINE FRAME statement.
The frame phrase can be attached to statements that output data to the screen to:
3–26
Programming the Progress Way
SYNTAX
In the following example, the DISPLAY statement uses a frame phrase to alter the
characteristics of a default frame:
When you use a frame phrase without specifying a frame name, Progress applies the phrase to
the default frame.
• Control the hiding and viewing of child frames through the parent, or independently
• Use default or cancel buttons from any other frame in the same family
Child frames behave like field-level widgets of the parent frame. Child frames must be
positioned physically within the parent frame. When you specify a location of a child frame, the
options you specify are with respect to the parent frame, not the window. However, the
field-level widgets of child frames are not controlled by the parent frame. You must explicitly
display, enable, and disable field-level widgets of child frames.
3–27
Progress Language Tutorial for Windows
To define a frame family, set the FRAME attribute of the child frame to the widget handle of
the parent frame. As shown in this example, frame child1 is a child frame of frame parent1 and
button btn-Exit is a field-level widget of frame child1:
You can use frame families to create useful interactions among frames, but they do carry some
restrictions that are important to remember. For example:
• Child frames cannot be down frames. (Down frames are frames that display multiple
records, one per line, one after another.)
• Child frames must appear within the display area of their parent frame.
• Appearance
• Functionality
When you first create a widget, Progress automatically determines many of the attributes.
Progress defines or changes other attributes during run time.
3–28
Programming the Progress Way
An attribute has a keyword identifier, a data type, and in some cases, a default value. For
example, every widget has the VISIBLE attribute. The VISIBLE attribute is a logical
(TRUE/FALSE) value. When VISIBLE is TRUE, the widget is visible on screen. When
VISIBLE is FALSE, it is not visible to the user. When you execute a DISPLAY statement,
Progress sets the VISIBLE attribute to TRUE.
The remaining two properties of an attribute describe how you can access it. Some widget
attributes are readable, some are settable, and some are both. Readable means that your
application can read the current value and assign that value to a variable. Settable means that
your application can assign a new value to the attribute.
Table 3–2 describes some attributes that you’ll use frequently. The table also lists the data type
of each widget and introduces a new data type: WIDGET-HANDLE. Basically, a widget handle
is an internal identifier for a Progress widget. Most of the time, you can work with a widget by
referencing the name of the variable or database field it is associated with. At other times, you’ll
need to provide the WIDGET-HANDLE. The tutorial describes how to use widget handles in
later chapters.
3–29
Progress Language Tutorial for Windows
Typically, the default attribute values assigned implicitly by Progress statements provide the
appearance and functionality you want in your widgets. Later, you’ll learn how to read and set
attributes directly.
3–30
Programming the Progress Way
ON F1 OF widget-name
DO:
/* Code */
END.
ON HELP OF widget-name
DO:
/* Code */
END.
The first trigger relies on the event action, while the second trigger relies on the event function.
For any particular widget, you can write a trigger for either the event action or the event
function, but not for both. However, you should write your triggers for event functions wherever
possible because:
• Your code is more portable. In the example above, writing a trigger for F1 would not work
on some platforms. Writing a trigger for HELP works everywhere.
• Execute a trigger
You’ve already seen the syntax for the ON statement, which handles events that execute trigger
code. Now, examine this partial syntax for the WAIT-FOR statement.
SYNTAX
The WAIT-FOR statement translates to “on this widget-event pair, unblock execution.” The
result is that the user moves into another part of the procedure or completes the procedure.
3–31
Progress Language Tutorial for Windows
Function Description
ENTRY Any action by the user or the application that gives a widget input focus.
LEAVE Any action by the user or the application that takes input focus from a
widget.
GO Any action that signals Progress to accept new data and continue
processing.
Event Categories
There are literally hundreds of events, so the Progress documentation uses some terms to refer
to groups of related events. Table 3–4 describes the categories.
Category Description
Universal key These events are “universal” to all widgets, except menu widgets.
functions They tend to be basic event functions, like GO or HELP.
Navigation key These events are the keystrokes that let you move input focus in an
functions interface, like TAB or BACK-TAB.
Field-editing key These events are the keystrokes that let you manipulate text inside a
functions widget, like BACKSPACE or DELETE.
High-level Progress These are the most important event functions in Progress, like
event functions LEAVE and ENTRY. They represent the easiest way to connect
triggers with widgets. For the most part, the tutorial uses high-level
events because they make readable, portable code.
3–32
Programming the Progress Way
2. Define frames.
3. Define triggers.
4. Display widgets.
5. Enable widgets.
6. Block execution.
3–33
Progress Language Tutorial for Windows
Envisioning an Interface
You decide that creating the main interface of the sales and inventory application is enough to
satisfy the curiosity of your bosses. What should that first screen consist of? You make a short
list:
• Buttons that launch the major sections of the application (for now, Customer, Order Entry,
and Inventory)
3–34
Programming the Progress Way
These notes explain how field-level widgets serve various functions in this application:
1. Use the rectangle widget to create a large (SIZE-CHARS 40 BY 7) empty (NO-FILL) box
with a one-character wide edge (EDGE-CHARS). The box makes the application title
stand out.
2. Create two variables to hold the application title. The FORMAT "x(19)" option specifies
how many characters of display space Progress should allow the text widgets to occupy.
The default is 8. You define these variables as text widgets because you are using the
values as a title. The variables are read-only text.
3. Create another variable to hold the initials of the user. Here, you need a fill-in field, but
you don’t have to specify it as such because fill-in field is the default.
4. Create three buttons that launch various functions of a sales and inventory application.
NOTE: Keep in mind that you can access online help information about a Progress keyword
by highlighting the keyword and pressing the HELP key function (F1).
3–35
Progress Language Tutorial for Windows
Define Frames
Your next step is to organize your widgets into frames. While you typically need only one frame
per interface, here you use two because you don’t want the buttons to appear until the user has
entered valid initials in the fill-in field. Here is the code:
With the DEFINE FRAME statement, you list the widgets you want contained in each frame.
In the first frame, you want precise placement of each widget. The AT phrase allows you to
place a widget at a specific ROW and COLUMN within the frame, not the window. Here, you
place the title variables inside the rectangle widget and you place the fill-in field below the
rectangle. In the second frame, the default spacing works fine, so you don’t need to use the AT
phrase.
Define Triggers
You only need one trigger for now. When the user chooses any of the function buttons, you want
to display the message “Sorry, that function is not yet implemented.” Here is the code:
As you can see, one ON statement can apply to many widgets. It can also apply to many events.
The HIDE MESSAGE NO-PAUSE statement clears the default message area without pausing.
It’s a good habit to always use this statement before sending a new message.
3–36
Programming the Progress Way
/*1*/ DISPLAY Name1 NO-LABEL Name2 NO-LABEL Username WITH FRAME Frame1.
1. The DISPLAY statement displays the title variables without labels (NO-LABEL). Next it
displays the fill-in field. Finally, by using the frame phrase (WITH FRAME), you tell
Progress to use a frame you’ve already defined.
2. Only the fill-in field in the frame is meant to have user interaction, so you enable it.
3. You block execution until the user presses RETURN in the fill-in field.
4. When the user presses RETURN, the application executes the code that follows the
WAIT-FOR statement. Here, you disable the fill-in field from receiving further input.
5. This statement serves to more precisely illustrate the function of the DISPLAY statement.
As you can see, you do not need a DISPLAY statement to make the buttons
appear-enabling the buttons makes them appear. Basically, you use the DISPLAY
statement with data widgets to display both the widget and the underlying value of the
variable or database field that the widget represents. If you had skipped the DISPLAY
statement for the first frame, the values of the text widgets, “All Around” and “Sports”,
would not appear.
The ALL keyword tells Progress to enable all the widgets in the defined frame.
6. You establish the condition that signals the end of the application—when the user chooses
the Exit button.
3–37
Progress Language Tutorial for Windows
It’s time to put all your hard work together and view the results. Perform these steps:
1 ♦ Open lt-03-07.p.
3 ♦ Type your initials in the fill-in field and press RETURN. A row of buttons appears.
4 ♦ Choose one of the buttons. The “Sorry, that function is not yet implemented” message
appears in the default message area.
3–38
Programming the Progress Way
lt-03-07.p
3–39
Progress Language Tutorial for Windows
Practice Problems
If you feel like you need some practice creating interfaces, complete the exercise below. The filename
listed next to the problem contains a sample solution. You can load the file into the Procedure Editor.
The procedure you just worked with, lt-03-07.p, creates a complete interface that follows the Progress
programming model. Using the same techniques, you should be able to duplicate the interface shown
below.
3–40
Programming the Progress Way
3–41
Progress Language Tutorial for Windows
Follow these steps for a demonstration of how you can enable and disable widgets during run
time:
1 ♦ Open lt-03-08.p.
Exercise
2 ♦ Choose Compile→ Run. The interface shown below appears. Note that buttons #1 and
Exit are enabled, and #2 is disabled:
3 ♦ Choose the first button. The second button becomes enabled and the first becomes
disabled.
4 ♦ Choose the second button. The first button becomes enabled again and the second button
becomes disabled. You can repeat this process as many times as you like.
3–42
Programming the Progress Way
lt-03-08.p
The effect of the ENABLE and DISABLE statements at points 1 and 2 is that only one of the
buttons can be active at a time. By selectively enabling and disabling parts of the interface, you
help the user focus on the parts of the interface that are important at a given moment.
This is a partial syntax for the ENABLE statement.
SYNTAX
SYNTAX
3–43
Progress Language Tutorial for Windows
The following table describes the important elements of the ENABLE and DISABLE
statements:
Element Description
frame-phrase Specifies the frame where the targeted widgets exist. Even when Progress
does not require it, it is good programming practice to specify the frame.
SYNTAX
VIEW widget-list
SYNTAX
3–44
Programming the Progress Way
Element Description
MESSAGE You can also use the HIDE statement to hide the contents of the default
message area.
NO-PAUSE Use the NO-PAUSE option to prevent Progress from pausing before
hiding data.
To hide or view a frame, substitute the keyword FRAME and frame name for widget-list:
To hide or view one or more widgets in a frame, specify a list of widgets and, if necessary,
append the IN FRAME frame-name syntax to individual widget references:
Up to now you used the frame phrase, which begins with WITH, to specify a frame. Here you
use the IN FRAME syntax. The difference is that WITH is used to create or modify a frame and
its attributes, while IN FRAME merely references an existing frame.
One very important thing to remember about using VIEW and HIDE is that they do not affect
the enabled status of a widget. If a widget is enabled when you hide it, it will still be enabled
when you view it again. Enabling and viewing are separate functions.
3–45
Progress Language Tutorial for Windows
1 ♦ Open lt-03-09.p.
Exercise 2 ♦ Choose Compile→ Run. The visible interface consists of buttons and a small frame with
its border showing and a widget within the frame. All the HIDE and VIEW statements will
operate on this small frame and the widget within it:
5 ♦ Choose Hide Widget. The widget inside the small frame disappears.
8 ♦ Choose Hide Frame and then View Frame. Notice that the widget inside the small frame
is not visible. When you explicitly hide a widget within a frame, viewing and hiding the
containing frame does not affect the hidden widget.
3–46
Programming the Progress Way
3–47
Progress Language Tutorial for Windows
lt-03-09.p
1. When you display the default border of a frame, you can use the TITLE option to give the
whole frame a label.
3–48
Programming the Progress Way
2. The first trigger views the frame. You must include the keyword FRAME or Progress will
attempt to find a field-level widget with the specified name.
3. As with VIEW, the HIDE statement only requires a valid frame reference.
4. Here, you are viewing a widget within a frame. You need to specify the widget and the
frame reference with IN FRAME.
5. Hiding a specific widget also requires both widget and frame references.
SYNTAX
ASSIGN widget-name:attribute-name
You can also assign widget attribute values to variables, as long as the variable is of the same
data type, using the following syntax.
SYNTAX
To set an attribute, you assign the new value to the attribute, but you must also specify the frame
in which the widget resides. You use the IN FRAME phrase to identify the containing frame.
Here is the syntax.
SYNTAX
3–49
Progress Language Tutorial for Windows
1 ♦ Open lt-03-10.p.
Exercise 2 ♦ Choose Compile→ Run. You see a fill-in field with the label “Is Rectangle Visible?” and
the value no.
3 ♦ Choose the Show Rectangle button. A rectangle becomes visible and the value of the fill-in
field becomes yes, as shown below:
3–50
Programming the Progress Way
lt-03-10.p
1. When you first create a widget, the VISIBLE attribute is set to YES by default. However,
a field-level widget is not visible until its frame is visible. Therefore, when a frame
becomes visible, all the widgets in it are visible by default. In this statement, you set the
VISIBLE attribute to NO. When the frame displays, you won’t see the rectangle.
3. When the user chooses the button, the trigger changes the value of the VISIBLE attribute
to YES, making the widget visible, since its frame is currently visible.
5. The DISPLAY statement outputs the new value of Field1 to the screen.
3–51
Progress Language Tutorial for Windows
This example also illustrates an important rule about accessing attributes for field-level widgets:
You cannot access a widget’s attributes until that widget is referenced in a frame.
Methods
A method is a specialized function that modifies how a widget works. For example, the
READ-FILE method allows you to read an operating system file into an editor widget. Methods
are relatives of attributes and you access them in the same way you access attributes.
To use a method, follow these basic steps:
3. Assign the result of the method call to a variable of the same data type.
Here’s an example:
The later chapters of the tutorial discuss some of the most useful methods.
3–52
Programming the Progress Way
3.6 Summary
The Progress programming model is a way of programming that creates highly responsive
interfaces. A user interface is made up of a keyboard, or other input device such as a mouse, and
whatever the user sees on the screen.
A window is an object that contains your application’s workspace. Character interfaces use only
one window. Graphical interfaces, such as Windows 95 or Windows NT, can have multiple
overlapping windows on the screen.
Progress interfaces are made of objects called widgets. An interface is a tool for displaying data
and receiving events. A particular interface can receive events when it is enabled for input and
the procedure or the user designates that widget as the event receiver. A widget so designated
is said to have input focus.
Each widget responds to each possible user event (keyboard or mouse action) with a default
response. You can program a widget to have a response in addition to the default response using
triggers. A trigger is a block of code following an ON statement. The code executes when the
widget specified in the ON statement receives the user event specified in the ON statement.
The parts of a Progress procedure include:
• Widget definition
• Frame definition
• Trigger definition
• Interface creation
• Interface enabling
• Execution blocking
• Interface disabling
• Window Widgets — Window widgets are workspace for your application. A window
contains all other widgets. Character interfaces use one window, while graphical
interfaces can use multiple windows.
• Container Widgets — Container widgets allow you to organize data, action, and graphic
widgets. Container widgets include frames and dialog boxes.
3–53
Progress Language Tutorial for Windows
• Data Widgets — Data widgets are the widgets you use to represent data from fields and
variables. Data widgets include fill-in fields, text, editors, selection lists, combo boxes,
radio sets, toggle boxes, sliders, and browse widgets.
• Action Widgets — Action widgets allow the user to direct the operation of your
application. Menus provide groups of related processing options while buttons execute a
single option. Buttons, menu bars, submenus, and menu items make up action widgets.
• Graphic Widgets — Graphic widgets help you decorate your interface. Use rectangles to
make different kinds of borders. Images, which are available on graphical interface
systems, allow you to include high-resolution graphics in your interface.
• DISPLAY displays widgets and the data contained in the associated fields.
• WAIT-FOR blocks execution and establishes the condition that unblocks execution.
• DEFINE FRAME creates a frame, including the field-level widgets that it contains.
3–54
4
Understanding the Database Environment
This chapter introduces you to the Data Dictionary, a tool that you use to create, modify, and
view the properties of a database. The chapter covers:
• Generating reports
For additional information about the Data Dictionary, see the Progress Basic Development
Tools on-line help. For a discussion of designing and creating effective databases, see the
Progress Database Design Guide.
Progress Language Tutorial for Windows
To illustrate how the Data Dictionary and application defaults work, you’ll create and use your
own copy of the sports database.
1. From the ADE Desktop, click the Data Dictionary tool button.
4–2
Understanding the Database Environment
Before any Progress tool can work with a database, you must connect to that database.
Connecting a database means that Progress opens the database file and has access to the schema
and data from the file. Depending on whether or not databases are already connected, the startup
behavior of the Data Dictionary is different:
• If you haven’t connected a database, Progress displays a series of dialog boxes to let you
specify one. The next section describes how to use these dialog boxes.
• If you have connected a database, Progress loads the schema of that database into the Data
Dictionary and displays the Data Dictionary main display, as shown in Figure 4–1.
Connected
database
4–3
Progress Language Tutorial for Windows
This dialog box permits you to save or discard all changes you have made to the current database
during the current Data Dictionary session. Choose Yes to keep your changes and No to discard
them. This dialog box also appears when you switch between databases in the Data Dictionary.
While you work with this tutorial, always choose No when this dialog box appears. The
exercises in the tutorial depend on the sports database schema remaining the same.
This dialog box prompts you to connect an existing database, create a new database, or
continue with no database.
4–4
Understanding the Database Environment
2 ♦ Choose Create a New Database and then OK. The Create Database dialog box appears as
shown below:
4 ♦ The Start With radio-button set displays the following copy options:
• A Copy of Some Other Database — You can specify another Progress database to
copy.
5 ♦ Activate the Replace If Exists toggle box. In this case, the Replace If Exists toggle box
represents a YES/NO question. (Do you want the new database to replace any existing
database of the same name in the current directory?)
7 ♦ Once you create a Progress database, you must connect the database to access the data in
it. When you choose OK in the Create Database dialog box, the Database Connect dialog
box appears to help you connect the sports database. Choose Cancel for now. The next
section describes how to access this dialog box directly.
4–5
Progress Language Tutorial for Windows
1 ♦ In several cases, the Data Dictionary displays the Database Connect dialog box
Exercise automatically. To access it directly, choose Database→ Connect from the Data Dictionary
main display. The dialog box appears, as shown below:
The Connect Database dialog box allows you to specify how you want to connect to a
database. For specifics on database connection parameters, see the Progress Startup
Command and Parameter Reference.
The physical name is the name of the operating system file that contains the database. The
physical name for the sports database is sports.db. You don’t need to type the .db
extension because Progress looks for files with that extension.
The logical name of a database is the database’s internal name. The default logical name
is the same as the physical name. In this case, it’s sports. The logical name is the name
you use to reference a database in a Progress procedure.
3 ♦ Choose OK to connect to the new sports database and return to the Data Dictionary
display. The Data Dictionary display confirms the database connection. The Databases
selection list now lists the sports Database.
You can connect several databases, but you can only work with one at a time in the Data
Dictionary. If you have several connected, choose the one you want to work with from the
Databases selection list.
4–6
Understanding the Database Environment
1 ♦ Choose Database→ Disconnect. Progress displays a dialog box and prompts you to verify
that you want to disconnect:
Exercise
2 ♦ Choose Yes. The Databases selection list no longer lists the sports database.
3 ♦ Reconnect the sports database so that it is available for the next exercise.
Menu bar
Mode buttons
Selection list of
database objects
Action buttons
4–7
Progress Language Tutorial for Windows
Menu Description
Database Create, connect, and disconnect databases; create schema reports; exit the
Data Dictionary.
Edit Delete or view properties for the current database object; commit or undo
all actions since your last save or when you last opened the Data
Dictionary. This menu is not available until you connect a database.
Create Create tables, sequences, fields, or indexes. This menu is not available
until you connect a database.
View Display hidden tables or order fields alphabetically. This menu is not
available until you connect a database.
Options Rename fields globally and renumber fields in a table. This menu is not
available until you connect a database.
Help Access help topics about menu commands and system messages.
4–8
Understanding the Database Environment
1. Select the type of database object that you want to work with by choosing the appropriate
mode button.
The Data Dictionary displays the correct selection lists and action buttons that go with that
object. In other words, the Data Dictionary has a different mode for each of the four
database objects.
2. Select an individual database object from the selection list. For fields and indexes, you
select the correct table and then the correct field or index object.
• The Create button creates a new object and brings up a new property sheet.
• The Properties button brings up the property sheet for the selected object. You can
view and change properties from this dialog box.
• The Delete button removes the selected object from the database.
4–9
Progress Language Tutorial for Windows
5 ♦ The property sheet for the Cust-Num field appears, as shown in Figure 4–3.
Properties
Bring up dialog
boxes for other
properties
Action buttons
• Choose OK to save the changes you have made and close the property sheet.
• Choose Save to save the changes and keep the property sheet open.
• Choose Cancel to close the property sheet and discard all changes made.
• Choose the left arrow button (<) to clear the property sheet and show the properties of the
object that immediately precedes the current object in the selection list. If you have made
changes, the Data Dictionary asks you to save or discard those changes before moving to
the next object.
• Choose the right arrow button (>) to clear the property sheet and show the properties of
the object that immediately follows the current object in the selection list.
4–10
Understanding the Database Environment
Table Contents
Item Inventory information, such as item name, catalog description, and price.
Order Order form information, such as order date, shipping date, and postal
carrier.
Order-Line Information relevant to a request for one item in a particular order, such as
item number, quantity, price, and associated order number.
Ref-Call Customer call information, such as call number and reason for call.
As you can conclude from these descriptions, this database holds the information necessary for
All Around Sports to take orders, process orders, bill for orders, and keep inventory information
up to date.
4–11
Progress Language Tutorial for Windows
4–12
Understanding the Database Environment
As an example of field properties, access the Cust-Num field property sheet of the Customer
table as shown in Figure 4–5.
CHARACTER Character fields contain any type of data (letters, numbers, and special
characters). Some character fields in the Customer table are Name,
Address, and Phone.
4–13
Progress Language Tutorial for Windows
DATE Date fields contain dates. The Invoice-Date field in the Invoice table
is a date field.
Properties of
selected index
4–14
Understanding the Database Environment
Next, the properties of an index include each component field and whether the component is
ascending or descending. The selection list on the properties sheet lists the component fields and
their ascending or descending status. When a field component is ascending, Progress sorts the
index values from first to last (for example, A to Z or 1 to 10). When a field component is
descending, Progress sorts the index values from last to first (for example, Z to A or 10 to 1).
Note that you cannot change these properties after you create the index. Changing components
or sort direction is equivalent to building a new index.
Finally, an index has a series of logical properties that define how the index works. These
properties are represented as toggle boxes on the property sheet. Table 4–4 describes these
properties.
Property Description
Primary The primary index is the one that Progress uses by default. Each table has
one and only one primary index. Progress uses the primary index when
retrieving records or ordering records for a list (like a report) if you don’t
specify another index. You want your primary index to reflect the most
common or natural sort order.
Unique A unique index is one where each index value must be different. For
example, each customer needs a unique number to identify them. Thus, the
Cust-Num index is a unique index. When you define an index as unique,
Progress will not allow you to enter an index value that’s already in use.
Active An active index is one that Progress updates when you create, delete, or
modify a record. If the index were inactive, you could still find the
definition of the index in the Data Dictionary, but Progress would not
update it until you made it active again.
Word A word index is one based on a character field where each distinct word in
the data becomes a separate index entry. Word indexes allow you to search
character fields quickly for key words.
4–15
Progress Language Tutorial for Windows
For example, All Around Sports customer numbers begin at 1 and increment by 1. Every time
you add a new customer record, you can access the Next-Cust-Num sequence to generate a new,
legal, unique customer number. You would then assign the value to the Cust-Num field of a new
Customer record.
As an example of sequence properties, access the property sheet for the Next-Cust-Num
sequence of the Customer table as shown in Figure 4–7.
Property Description
Initial Value The starting value of the sequence. You can enter any positive or
negative integer.
Increment by The value used to determine the next sequence number. You can use a
positive or negative integer.
Upper Limit The highest acceptable number for the sequence. You can use any
positive or negative integer.
Cycle at Limit Determine whether the initial value is re-used when the sequence
reaches the upper limit.
4–16
Understanding the Database Environment
By using the properties, you can create one of three types of sequences:
• Cycling Sequence — A sequence that begins at an initial value and increments in one
direction until it reaches a designated limit. On reaching the limit, the sequence restarts
with the initial value. You must provide a value for the Initial Value property, the
Increment by property, and the appropriate limit property. Cycle at Limit must be YES. A
cycling sequence does not provide unique values.
• Validation
• Display formatting
4–17
Progress Language Tutorial for Windows
To see an example of table validation, access the property sheet for the Customer table and
choose the Validation button. The dialog box shown in Figure 4–8 appears.
4–18
Understanding the Database Environment
ASSIGN Field Executes when an individual field has new data written
to it. For example, use an ASSIGN trigger to make a
copy of old data before copying new data to a field.
4–19
Progress Language Tutorial for Windows
To specify a trigger, access the table or field property sheet and choose the Triggers button.
Figure 4–10 shows the Table Triggers dialog box for the Item table.
4–20
Understanding the Database Environment
To create format strings, you first need to understand the format symbols. Table 4–7 describes
these symbols.
Symbol Description
> Designates zero suppression. That is, Progress replaces > with a number,
as long as it’s not a leading zero. If it’s a leading zero, Progress replaces >
with a blank.
To create a format string, just put together the symbols to describe how to display the data. For
example, if a character field contains the word “Wonderful”, one format string could be
“AAAAAAAAA”. If you want the data to display in uppercase, change the format string to
“!!!!!!!!!”. If the field can contain numbers too, change the format string to “NNNNNNNNN”.
If the field can contain any number, letter, or character, including blanks, then use the format
string, “XXXXXXXXX”.
Instead of typing long strings of symbols, you can use this shortcut:
4–21
Progress Language Tutorial for Windows
4–22
Understanding the Database Environment
You access the VIEW-AS property by choosing the VIEW-AS button on the field properties
sheet. The VIEW-AS Phrase dialog box appears, as shown in Figure 4–12.
4.8.5 Labels
When you display a field, the field name is the default screen label. You can specify a different
label using the Label property on the field property sheet. Typically, you want your default label
to be more descriptive than the field name, which most programmers like to keep short. You can
also specify a different label in the Column Label field for use when Progress displays data in
columns. Both the label and column label can consist of any text, including blanks.
To keep the default label (field name), enter ? in the label fields.
4–23
Progress Language Tutorial for Windows
Detailed Table Create a complete report of the properties of a table and its
constituent fields.
Quick Field Create a short summary of the fields, from one or all tables.
Table Relations Examine the database and report the natural relationships
found among database tables.
4–24
Understanding the Database Environment
4.10 Summary
The Data Dictionary is a tool that you use to create, view, and modify the properties of a
database and database objects: tables, fields, indexes, and sequences. Database properties
include those that define database objects and those that establish application defaults.
Collectively, database properties are referred to as schema.
Databases have two names:
• The physical database name is the operating system filename of the database.
• The logical database name is the internal Progress name of the database. Procedures
reference the logical name. If you don’t specify a logical name, Progress uses the physical
name by default.
The Data Dictionary allows you to connect databases. When a database is connected, any
Progress tool or application can access the data or schema of the database.
Table objects are defined with a unique name. The definitions of constituent fields and indexes
make up the bulk of a table definition.
Field objects are defined with a unique name and by specifying a data type. Data types
determine what kind of data a field can store:
Index objects are defined by specifying a name and the component fields. Other index properties
define how the index works:
• An active index is one that Progress keeps updated and ready for use.
• A word index is an index of a character field that allows you to search for words within
the field.
4–25
Progress Language Tutorial for Windows
Sequences are objects that generate automatic incremental sequences. Using sequence
properties, you can define three types of sequences:
• Terminating sequences start at an initial value and increment in one direction toward a
limit. Upon reaching the limit, a terminating sequence ceases to generate new values.
• A cycling sequence starts at an initial value and increments in one direction toward a limit.
Upon reaching the limit, the sequence starts over at the initial value.
Tables and fields have a validation property, which allow you to check criteria before allowing
record deletions in a table or new values in a field. The validation property is made up of:
• A validation expression that establishes the logic that allows or disallows record deletions
in a table or new values in a field.
• A validation message that informs the user that an action failed a validation check.
Databases have special events for which you can write triggers:
• A WRITE event occurs when Progress writes a record back to the database.
• An ASSIGN event occurs when Progress writes new data to an individual field.
The database trigger property allows you to add default behaviors to a database, eliminating the
need to code the behaviors in your procedures.
Field formats are symbols that tell Progress how you want to display data by default. Formats
do not affect the actual data, just the display of the data.
4–26
5
Working with Expressions
This chapter discusses different ways to represent and manipulate values. A value can be a
variable or a database field, as you’ve already seen. A value can also be the result of an
arrangement of language elements. An arrangement of language elements that represents a
single value is known as an expression.
Specifically, this chapter contains information on:
• Understanding expressions
• Using operands
• Using operators
• Using functions
• Variables — A location in memory that holds a value that may change during the
execution of a procedure.
• Widget attributes — A value that describes a characteristic of a widget like its width,
height, and so on.
• Constants — A value that does not change during the execution of a procedure.
An operator is a language element that represents an action carried out on one or more operands.
The successful combination of operands and operators, called an operation, always returns a
value. For example, the equal sign (=) is a 4GL operator that assigns the value from the right
side of the operator to the field or variable on the left side of the operator. The plus sign (+) is
another operator that adds the operands on either side of the operator and returns the result.
A function is a prewritten program that performs a specific task and returns a value. A function
is like an operand in that it represents a value, but it is also like an operator in that it represents
an action. You can think of a function as a prepackaged solution to a task that can be used in an
expression. Because the code already exists, either as a pre-defined function or one that you
create as a user-defined function, it offers a shortcut to providing a programmed solution to a
coding task or problem.
Progress supports pre-built Progress-supplied functions and user-defined functions. The 4GL
contains many functions that perform a wide range of common tasks. For example, the
ASC(character) function returns the ASCII integer code for a supplied character. Also, you can
use the FUNCTION statement to create specific functions that suit your programming needs.
The sections that follow provide more information about expression components.
5–2
Working with Expressions
Defining Variables
The partial syntax for the define statement below contains more options than you encountered
in Chapter 3.
SYNTAX
Table 5–1 describes the new syntax components of the DEFINE VARIABLE statement:.
Component Description
AS datatype Specifies the data type of the variable. Valid data types include:
CHARACTER, INTEGER, DECIMAL, DATE, LOGICAL and
WIDGET-HANDLE
LIKE Copies the attributes of an existing field or variable. When you use
LIKE, the new variable gets the data type, format, label, extent, and
initial value specification of the target field or variable.
FORMAT Specifies the data format of the variable. If you do not specify
FORMAT, the variable uses the default format for its data type.
5–3
Progress Language Tutorial for Windows
Component Description
LABEL Specifies the display label for the variable. For arrays, if you specify
a single label, then every element of the array uses that label. You can
also specify a different label for each element of the array using a
comma-separated list of labels after the keyword.
INITIAL Gives the variable an initial value. For arrays, if you specify a single
value, then every element of the array has that initial value. You can
also specify a different initial value for each element using a
comma-separated list of values enclosed in brackets.
Using LIKE
When defining a variable, you must specify either the data type or a database field or another
variable whose format and attributes you want to copy to the new variable. When you specify
the LIKE option, the new variable acquires the format, label, and initial value attributes of the
referenced field or variable. You can override an inherited attribute by using the FORMAT,
LABEL, and INITIAL options.
NOTE: To use a LIKE phrase that references a database field, you must be connected to the
database that contains the field you want to copy.
Examine the following code:
2. Your second variable is identical to the first; that is, New-Name2 has the same value,
format, and label that you specified in the New-Name1 definition.
3. In this statement, you create a third variable that inherits many of the attributes of a
database field. Notice the general syntax for making a specific reference to a database
field: table-name.field-name. The period separates the table and field names.
5–4
Working with Expressions
NOTE: Keep in mind that you can access on-line help information about a Progress keyword
by highlighting the keyword and pressing the HELP key function (F1).
Using Arrays
Arrays are fields or variables that contain multiple data elements. The extent of an array is the
number of elements it contains.
To define a field or variable as an array, specify the extent. If you want to define a database field
as an array, use the extent option in the Data Dictionary. To define a variable as an array, use
the EXTENT option in the DEFINE VARIABLE statement.
To initialize the array with values, you can use the INITIAL option with the values listed
between square brackets as shown in the following code:
If you do not supply enough values to fill up the elements of the array, Progress copies the last
specified value into the remaining elements of the array. If you supply too many values,
Progress returns an error message.
Within a procedure, you can:
• Refer to all the elements in the array at once. Simply specify the array name.
• Refer to a specific array element. Specify the array name and the element number, called
the index, enclosed in square brackets. For example: Letters[2]. Note that the index value
of the first array element is 1.
5–5
Progress Language Tutorial for Windows
Follow these steps to see how to set up an array, present the whole array for user interaction,
and reference the array in a trigger:
1 ♦ Open lt-05-01.p and run it. The interface shown below appears:
Exercise
The array of 12 elements contains the number of days in each month. Each element has an
individual label that corresponds to the name of the month.
2 ♦ Press TAB to move through the array elements. Notice the message area of the window. As
you enter each element, the message references the label, data, and index of the element.
5–6
Working with Expressions
lt-05-01.p
1. The DEFINE VARIABLE statement with the EXTENT option defines the array.
2. To give each element an individual label, use a comma-separated list of strings after the
LABEL keyword.
3. To initialize the elements, use a bracketed, comma-separated list of values after the
INITIAL keyword.
5–7
Progress Language Tutorial for Windows
When you use the COLON option of the format phrase, Progress positions the field by the
colon that terminates the widget label. When used with an array, the COLON option stacks
the elements neatly.
5. Here, you use the array variable name (Months) as a reference to the whole array. If the
user enters a fill-in field associated with any of the elements, the trigger executes.
6. The SELF keyword is called a system handle. The LABEL, SCREEN-VALUE, and
INDEX keywords are widget attributes. A system handle is a global variable that holds a
widget handle. The system maintains system handles for you. SELF is a system handle that
holds the widget handle of the current widget (a widget that has input focus or a widget for
which a trigger is firing). SELF is a convenient way of referring to an individual array
element without having to keep track of the index. You’ll learn more about SELF later in
the tutorial.
The LABEL attribute holds the widget label. The SCREEN-VALUE attribute holds the
value shown on the screen, which may not be the same as the value in the underlying
variable. (Perhaps the user changed the screen value or the procedure changed the field
value.) The tutorial covers screen values and field values more thoroughly later. Finally,
the INDEX attribute holds the index value of the array element where the cursor currently
resides. If you need to know explicitly where the cursor is, as opposed to relying on SELF,
the INDEX attribute is your tool.
SYNTAX
table-name.field-name
In many cases, programmers feel that supplying both the table and field name makes the code
more readable, even if it is not required.
5–8
Working with Expressions
At other times, you may need to specify the database name that contains the table. Add the
database name and a period before the table name.
SYNTAX
database-name.table-name.field-name
SYNTAX
You only need the IN FRAME option when two or more frames have a widget of the same
name. Here’s an example of using a widget attribute in an expression:
5–9
Progress Language Tutorial for Windows
As you can see for LOGICAL values, TRUE, T, YES, and Y all represent the TRUE state.
Similarly, FALSE, F, NO, and N all represent the FALSE state.
• Numeric
• Comparison
• Date
• Character
• Logical
5–10
Working with Expressions
Numeric Operators
Use numeric operators with numeric data to perform calculations. Table 5–3 describes the
operators.
5–11
Progress Language Tutorial for Windows
Comparison Operators
Use comparison operators to compare fields, variables, constants, or expressions. The result is
always a logical value. Table 5–4 describes the comparison operators.
5–12
Working with Expressions
Date Operators
You use date operators to manipulate date values. Table 5–5 describes the date operators.
Character Operator
You use the character concatenation operator to combine two character expressions. Table 5–6
describes the operator.
5–13
Progress Language Tutorial for Windows
Logical Operators
The logical operators allow you to make compound Boolean conditions. Table 5–7 describes
the logical operators.
Operator Description
• Pre-defined function
• User-defined function
The following sections provide more details about each of these kinds of functions.
5–14
Working with Expressions
The example below uses the pre-defined, Progress-supplied function for calculating square
roots: SQRT( ):
A = 100 + SQRT(9).
Here, 9 is the input parameter and the SQRT function returns 3, the square root. You could write
code with Progress to calculate square roots, but using the prebuilt function is far more
convenient.
For more information about pre-defined functions, see the function entries of the Progress
Language Reference.
ASSIGN var1 = 20
var2 = 10
var3 = 250.
5–15
Progress Language Tutorial for Windows
1. Progress evaluates functions first. So, Progress executes the ASC functions, which return
the ASCII integer code for a supplied character as shown in the following code:
3. Progress has predefined levels of operator importance based on the laws of mathematics
and logic. These levels of precedence define which operators Progress executes first.
Table 5–8, which follows this description, shows the levels of precedence. Operators with
a higher number are executed first. In this example, the division operator has the highest
level of precedence:
Among operators of equal precedence, Progress evaluates them from left to right.
var1 <= 20
5. Finally, the less than or equal to operator remains. Since this is a logical operator, the final
result of the expression will be TRUE or FALSE. In this case the final value is TRUE.
5–16
Working with Expressions
Table 5–8 depicts the levels of operator precedence which Progress follows from highest (7) to
lowest (1):
7 Unary Negative -
Unary Positive +
6 Modulo MODULO
Division /
Multiplication *
5 Date Subtraction -
Subtraction -
Date Addition +
Concatenation +
Addition +
4 MATCHES MATCHES
Less Than LT or <
Less Than or Equal To LE or <=
Greater Than GT or >
Greater Than or Equal To GE or >=
Equal To =
Not Equal To <>
BEGINS BEGINS
3 Not NOT
2 And AND
1 Or OR
5–17
Progress Language Tutorial for Windows
• Calculating values
• Evaluating conditions
A = 2 + 2.
When you use the assignment operator in this way, it is a complete Progress statement. Now
suppose you need to make several calculations such as those shown in this code:
A = 2 + 2.
B = A + 10.
C = A + B.
You’ve created three Progress statements to perform three calculations. Progress can perform
any number of assignments using the ASSIGN statement. This is a partial syntax for the
ASSIGN statement.
SYNTAX
ASSIGN A = 2 + 2
B = A + 10
C = A + B.
5–18
Working with Expressions
Note that there is only one period—at the end of the last assignment. Using ASSIGN is more
efficient than using multiple assignment statements.
/*1*/ IF A = 2 + 2 THEN . . .
/*2*/ IF B > A THEN . . .
/*3*/ D = B > A.
2. This second expression uses the greater than operator: Is B greater than A?
3. This example is a statement, not a conditional expression. Here, you are assigning the
result of the B > A test to a LOGICAL variable named D.
SYNTAX
WHERE [ expression ]
5–19
Progress Language Tutorial for Windows
Earlier you saw that the FOR EACH statement goes through every record in a database table.
When you attach WHERE to FOR EACH, FOR EACH goes through each record and evaluates
the WHERE expression using each record. If the expression for a particular record evaluates to
TRUE, then Progress executes the statements inside the FOR EACH block. If it evaluates to
FALSE, Progress moves on to the next record in the table. Thus, FOR EACH selects records
based on the WHERE expression, as shown in the following example:
So, as Progress cycles through the Customer records, it displays information from only those
records where the customer number is greater than 30.
• Move a widget by manipulating the ROW and COL attributes. You can actually create
simple animation by incrementing these values.
• Change the size of a widget by manipulating the WIDTH and HEIGHT attributes.
5–20
Working with Expressions
Exercise
2 ♦ Experiment by choosing from the Up, Down, Left, Right button group. The Reset button
moves. You can move the button around within the frame, but can’t move the button
beyond the borders of the frame. The ROW and COL attributes, which the buttons
manipulate, position a widget within a frame.
5–21
Progress Language Tutorial for Windows
lt-05-02.p
5–22
Working with Expressions
1. Choosing the Reset button moves the widget back to its starting location. The trigger
assigns the constant values that correspond to the original coordinates to the ROW and
COL attributes.
2. This trigger moves the Reset button up one row by decrementing ROW.
3. This trigger moves the Reset button down one row by incrementing ROW.
4. This trigger moves the Reset button right one column by incrementing COL.
5. This trigger moves the Reset button left one column by decrementing COL.
5–23
Progress Language Tutorial for Windows
Practice Problems
If you feel like you need some practice writing expressions, complete the exercises below. The filename
listed next to each problem contains a sample solution. You can load the file into the Procedure Editor.
Using a FOR EACH block, increase all customer credit limits by 10%. Display the customer name, old
credit limit, and new credit limit.
Display all customer names and balances where the balance is $5000 or more.
Display all orders that were placed between 1/14/93 and today.
Display all orders that have not been shipped within five days of the promised date.
Based on today’s date, display the number of the month, weekday, and year.
Define an array of dates called Holidays. Initialize the array with the dates you get off from work. Label
each element with the holiday name. Display the result.
5–24
Working with Expressions
5.7 Summary
An expression is a combination of 4GL language elements that results in a value. At a minimum,
an expression consists of one operand, but can include multiple operands, operators, and
functions.
An operand is a language element that represents a value. Operands include:
• Variables — A location in memory that holds a value that may change during the
execution of a procedure.
• Widget attributes — A value that describes a characteristic of a widget like its width,
height, and so on.
• Constants — A value that does not change during the execution of a procedure.
An operator is a language element that represents an action carried out on one or more operands.
An operation, is the successful combination of operands and operators that results in a value.
A function is a prewritten program that performs a specific task and returns a value. There are
two types of functions in Progress: pre-defined functions that Progress provides and
user-defined functions that you can create.
Arrays are fields or variables that contain multiple data elements. The extent of an array is the
number of elements it contains.
5–25
Progress Language Tutorial for Windows
5–26
6
Working with Control Structures
In Chapter 3, “Programming the Progress Way,” you learned about the parts of a Progress
procedure that define and enable an interface. This chapter discusses the various Progress
components that make up the functional part of an application—what’s going on behind the
interface. The discussion describes both the structures you can use for containing code and the
structures you can use to manage flow of control within a procedure.
Specifically, the chapter discusses:
• Sharing information
• Minimize your application development time. You don’t have to retype a sequence of
statements each time you need those statements—you call the subprocedure as many times
as you like.
• Maintain your application easily. If you want to change code, you can change the one
subprocedure that contains it, instead of correcting the code in many different areas of the
main procedure.
To run a procedure from within another procedure, you use the RUN statement. Here’s a partial
syntax of the RUN statement.
SYNTAX
RUN procedure-name
6–2
Working with Control Structures
To demonstrate this process, suppose your main procedure creates an interface that displays
four buttons. When the user chooses a button, a distinct task executes. You store each of these
tasks, or modules, in a separate procedure file. Each module then becomes a subprocedure of
the main procedure. Figure 6–1 illustrates this concept.
ON CHOOSE OF btn-2
DO:
RUN sub2.p.
END.
.
.
.
6–3
Progress Language Tutorial for Windows
SYNTAX
PROCEDURE procedure-name :
statements
END [ PROCEDURE ].
By convention, you store internal procedures at the bottom of a procedure file, after the main
procedure. Internal procedures do not require a file extension (.p). You access internal
procedures in exactly the same way as external procedures—with the RUN statement.
6–4
Working with Control Structures
Figure 6–2 shows a simple example of a procedure file that contains two internal procedures.
main.p
/* Define Widgets */
/* Define Frames */
/* Define Triggers */
ON CHOOSE OF btn-1
DO:
RUN sub1.p.
END.
Main Procedure
ON CHOOSE OF btn-2
DO:
RUN sub2.p.
END.
/* MAIN LOGIC */
PROCEDURE sub1:
PROCEDURE sub2:
END PROCEDURE.
6–5
Progress Language Tutorial for Windows
SYNTAX
FUNCTION function-name
[ RETURNS ] data-type
[ ( param [ , param ] ... ) ]
Component Description
data-type Describes the data type of the value returned from the function.
The FUNCTION statement offers you the advantages of defining an internal procedure while
also returning a value, a capability supported by a function. A function applies the logic that
defines the function to the values that are passed to it, and provides a single return value to the
calling procedure (that is, the procedure that contacted it to perform its function).
NOTE: You cannot define temp-tables, work-tables, shared variables, shared frames, shared
browses or streams within a user-defined function.
6–6
Working with Control Structures
To gain a better understanding of the user-defined function, let’s review the code in Figure 6–3.
main.p
/* Define Function */
FUNCTION compute RETURNS INTEGER
(INPUT hrs AS INTEGER,
User-defined INPUT rate AS INTEGER,
Function Definition OUTPUT tax AS INTEGER).
tax = 1.
RETURN (hrs * rate).
END FUNCTION.
/* Invoke Function */
DISPLAY
"Info1 hrs = 3,rate = 3".
First Invocation DISPLAY (compute (3,3,for_tax)).
/* end of function */
/* Invoke Function */
DISPLAY
"Info2 hrs = 7,rate = 5".
Second Invocation DISPLAY (compute (7,5,for_tax)).
/* end of function */
6–7
Progress Language Tutorial for Windows
associated with this user-defined function are further discussed in the “Using Parameters to Pass
Values” section presented later in this chapter.
6–8
Working with Control Structures
proc1.p proc2.p
DEFINE . . . DEFINE . . .
DEFINE . . . DEFINE . . .
dis-cust.i
proc1.p proc2.p
DEFINE . . . DEFINE . . .
DEFINE . . . DEFINE . . .
{dis-cust.i}
Include {dis-cust.i}
Reference
DISPLAY . . . DISPLAY . . .
ENABLE . . . ENABLE . . .
WAIT-FOR . . . WAIT-FOR . . .
6–9
Progress Language Tutorial for Windows
• Define shared variables to make a variable and its value available to other procedures
When you run internal procedures from a main procedure, the variables defined in the main
procedure are always available to the internal procedure. Therefore, the information-sharing
techniques listed above are not usually necessary for internal procedures.
SYNTAX
When you use a shared variable, only one procedure can own the shared variable. That
procedure creates it, and when that procedure ends, so does the availability of the shared
variable. The owner procedure must use the two keywords NEW SHARED in the DEFINE
VARIABLE statement, as in this example:
Any other procedure that uses the shared variable must also define it, but without the keyword
NEW:
Note that any format phrase option, such as a label or format string, specified in the original
definition (NEW SHARED), does not apply to the variable in subsequent definitions
(SHARED). You can specify different options for the variable in different procedures.
6–10
Working with Control Structures
Also note that you cannot define shared variables in a user-defined function.
Figure 6–5 shows the relationship among three procedures and the shared variable that two of
these procedures access. The proc1.p procedure defines a NEW SHARED variable called
Shareinfo and runs a procedure called proc2.p. The proc2.p procedure does not use Shareinfo
but calls proc3.p, which does. Procedure proc3.p needs to define Shareinfo as a shared
variable. Even though you don’t run proc3.p from proc1.p, it still can still access the shared
variable. Once proc1.p defines the variable, any procedure that also defines that variable can
access the data stored there.
Shared Variable
shareinfo
6–11
Progress Language Tutorial for Windows
SYNTAX
DEFINE
{ INPUT | OUTPUT | INPUT-OUTPUT } PARAMETER parameter
{ AS data-type | LIKE field }
{ [ format-phrase ] }
The statement options are similar to the options you used with the DEFINE VARIABLE
statement. The parameter types are:
• INPUT — A parameter defined in a called procedure that receives a value from the calling
procedure.
• OUTPUT — A parameter defined in a called procedure that returns a value to the calling
procedure.
• INPUT-OUTPUT — A parameter defined in the called procedure that can receive a value
from the calling procedure and return a value back to it.
All procedure and function parameters (that is, pre-defined and user-defined functions) are
passed by value. This means that for any INPUT-OUTPUT or OUTPUT parameter, the field or
variable that receives the output value is not set by the called procedure until and unless the
procedure returns without error.
To call a procedure that contains parameters, place a comma-separated list of parameters
enclosed in parentheses at the end of the RUN statement. You can specify a type for each
parameter in the list. Similarly, to call either type of function, you also define a
comma-separated list of parameters enclosed in parentheses within a statement that invokes the
function.
SYNTAX
RUN procedure-file
[([ { INPUT | OUTPUT | INPUT-OUTPUT } expression ] , ... ) ]
6–12
Working with Control Structures
If you do not specify the parameter type keywords in the RUN statement, Progress assumes that
the parameters are INPUT parameters. The number and type of parameters in the called
procedure must match the number and type of procedures in the RUN statement:
The called procedure matches the values passed by the RUN statement by associating the first
value to the first defined parameter and so on.
SYNTAX
FUNCTION function-name
[ RETURNS ] data-type
{ { [ INPUT ] | OUTPUT | INPUT-OUTPUT }
param-name AS data-type
}
The FUNCTION statement matches parameters by associating the first value to the first defined
parameter, the second value to the second defined parameter, and so on. The number and type
of parameters in the calling procedure must match the number and type of procedures in the
FUNCTION statement.
6–13
Progress Language Tutorial for Windows
For example, in the user-defined function code presented in Figure 6–3 earlier in this chapter,
the function called compute is written to accept two input parameters defined as INTEGER, and
one output parameter that is also defined as INTEGER. In the first invocation of the function,
the actual input parameter values 3 and 3 replace the input parameter values hr and rate. Within
the function definition, these two values are multiplied (hrs * rate) and the function returns the
result, 9, to the calling procedure. The output parameter for_tax is also returned to the calling
procedure.
The second invocation in Figure 6–3 shows how this code is re-usable. The second invocation
provides two different input parameter values, 7 and 5, but the same operation defined for the
function is performed.
Follow these steps to demonstrate passing parameters and shared variables:
• lt-06-02.p
• lt-06-03.p
6–14
Working with Control Structures
The code in procedure lt-06-03.p creates this display, but the value “Paris” originates in
the main procedure lt-06-01.p, passes through lt-06-02.p, and arrives safely for use in
the display.
6–15
Progress Language Tutorial for Windows
Here is the code for the three procedures that create the display:
lt-06-01.p
lt-06-02.p
lt-06-03.p
1. The main procedure creates a new shared variable and gives it an initial value.
2. The main procedure calls the second procedure. Note that the RUN statement uses no
parameters.
3. For this procedure to access the shared variable, it too must define it.
6–16
Working with Control Structures
4. This local variable passes on the value as a parameter. It is not necessary, because a shared
variable can also be a parameter. The point here is to show how to pass the value of a local
variable.
5. This RUN statement calls the next procedure and specifies the local variable London as a
parameter. Note the parentheses.
6. The final procedure defines one parameter. During run time, Progress checks to make sure
that both the calling and called procedures specify the same number of parameters.
7. Because of the defined parameter, you can use Paris as a valid reference anywhere you can
use a variable name.
NOTE: For more information about the keywords associated with this procedure and any
other procedures that you work on in Progress, simply highlight the keyword and
press the HELP key function (F1).
You can modularize this code to work for any table and field name pair by replacing the literals.
Literals are programming symbols, such as table names, field names, or variable names. An
argument passes a literal, not a value. To create a procedure that accepts arguments, replace the
literals with argument references, as shown:
Progress cannot compile this code because {1} is not a table name and {2} is not a field name.
However, if you place any valid table name at {1} and any valid field name at {2}, the procedure
could compile. Once the procedure compiles, the table and field name become valid references
to actual data, and the procedure runs.
6–17
Progress Language Tutorial for Windows
What the external procedure needs is arguments (valid literal references) to complete the code.
You can pass arguments to an external procedure by specifying them after the RUN statement,
as shown in the following code:
“Customer” is argument 1 and “Name” is argument 2. To reference the arguments in the called
procedure, enclose the argument number in braces { } as shown in the following code:
Now the external procedure can compile by substituting the argument references for the
arguments. Remember, you are literally passing the argument specified in the RUN statement,
not the value of the argument. In this case, arguments turn out to be very useful because now
you have a procedure that can create a report for any valid table and field pair.
You can also use variables in the RUN statement, if the values of the variables are valid literals
for the called procedure, as shown in the following code:
The drawback to using arguments is that you cannot compile the external procedures that
contain them until run time, which may slow your application down. In many cases, you can
achieve the same kind of modularity by using parameters or shared variables. In other words,
use arguments as a last resort.
6–18
Working with Control Structures
The example below shows how to use arguments with an include file:
You reference the arguments in the include file the same way you reference arguments in called
procedures, as shown in this example:
6–19
Progress Language Tutorial for Windows
Practice Problems
This problem gives you some practice modularizing code and using parameters.
First, duplicate the interface shown below with a DEFINE FRAME statement. Cost and Cancellation
should be text widgets. All the widgets should be enabled on startup except for Refund Sent.
Next, create an external procedure to calculate cost when the user chooses Calculate Cost. The conference
fee is $75 per attendee and the hotel cost is $100 per guest.
Finally, create an internal procedure that disables all widgets except Exit and enables Refund Sent.
6–20
Working with Control Structures
• Procedures
• Internal procedures
• Triggers
• Control blocks:
– DO
– REPEAT
– FOR EACH
Here are some general statements about blocks, although you’ll learn about some exceptions in
the sections that follow:
• Most block types come with implicitly defined services called block properties. Default
frame allocation, for example, is a service, or block property, of many blocks. In the
tutorial, you’ll work with these block properties: looping, record reading, and frame
allocation.
• Many blocks have syntax options that allow you to define services explicitly, either to
override implicit services or to add new services.
6–21
Progress Language Tutorial for Windows
• You can name blocks by adding a label and a colon before the block header as shown in
the following code:
• Although you can place internal procedures anywhere in a procedure file, by convention,
you usually place them at the very end of the procedure file.
A typical event-driven procedure contains definitions, triggers, and main logic. The task of
blocking the interface with the WAIT-FOR statement usually falls to the procedure block,
because it is the outermost block. Blocks within the procedure block normally work with the
interface created and blocked for input in the procedure block.
The procedure block has implicit frame allocation, that is, any screen I/O statements in the
procedure block that do not explicitly use a defined frame perform their functions in a default
frame owned by the procedure block.
6–22
Working with Control Structures
SYNTAX
ON event-list OF widget-list
trigger-block
The trigger header statement is the ON statement. You enclose the trigger block statements
between DO and END as shown in the following code:
ON CHOOSE OF btn-Exit
Block Header DO:
RUN proc1.p.
END.
SYNTAX
Note that the event name in an APPLY statement is enclosed in quotation marks, which is not
the case for the ON statement.
In general, you should avoid using APPLY because too many APPLY statements make your
code hard to follow and also because APPLY is not a very efficient way to execute triggers. If
you have code in a trigger and want to execute the same code from another location, move the
trigger code into an internal or external procedure. Then, you can access the code with a RUN
statement from inside a trigger or anywhere else.
6–23
Progress Language Tutorial for Windows
• DO
• REPEAT
• FOR EACH
SYNTAX
[ label: ]
DO [ variable = expression1 TO expression2 ]
[ WHILE expression ]
{ [ frame-phrase ] } :
END
6–24
Working with Control Structures
• To provide explicit services to another block. For example, triggers have implicit frame
allocation, but do not have the frame phrase option on the header statement. So, if the
statements in your trigger operate with a frame other than one Progress expects, you can
nest a DO block within the trigger block. As shown in the following code, this technique
eliminates having to specify the frame on every screen-output statement in the trigger:
ON CHOOSE OF btn-New
DO:
DO WITH FRAME Frame2:
ASSIGN Cost = Price + Tax.
DISPLAY Price Tax Cost.
END.
END.
• To provide looping with an incrementing variable using the TO syntax as shown in this
code:
DO i = 1 TO 31:
ASSIGN Total = Total + January[i].
END.
• To provide conditional looping with the WHILE syntax. WHILE allows you to specify an
expression. On each iteration, the block evaluates the WHILE expression and then
executes the block, if the expression evaluates to TRUE. Review the WHILE expression
in this code:
ASSIGN i = 1.
DO WHILE(i < 32):
ASSIGN Total = Total + January[i]
i = i +1.
END.
It’s important to note that the DO and END syntax of a trigger block does not make it a DO
block. As described in this section, DO is a control structure that has no block properties unless
you specify them with optional syntax. The trigger block DO has no explicit syntax options.
6–25
Progress Language Tutorial for Windows
SYNTAX
[ ]
label:
Like the DO block, the REPEAT block can define the iterations of the block by incrementing a
variable to a desired value or by specifying a WHILE expression. If the block contains neither
of these options, then the REPEAT block loops continuously. In other words, there is no implicit
terminating condition.
Progress provides the user with an implicit method of ending the iterations of a REPEAT block:
the END-ERROR key. This feature makes REPEAT useful for coding repetitive tasks, especially
where you cannot predict how many iterations of the task the user will want to complete. The
terminating condition is in the hands of the user. By default, Progress displays a message
instructing the user to press END-ERROR to end the block.
You can also programmatically control the end of a REPEAT block using the LEAVE
statement. The LEAVE statement is useful when you want to evaluate a condition within a
REPEAT block and exit the block based on the outcome. After Progress encounters the LEAVE
statement, it continues execution with the first statement after the end of the block.
6–26
Working with Control Structures
This exercise uses a REPEAT block to type characters in a fill-in field. Follow these steps for a
demonstration of the REPEAT block:
As soon as the interface displays, the letters of the alphabet quickly fill the Alphabet field.
Of course, if you have a very fast computer, you may only see the end result of the
loop—the entire alphabet.
6–27
Progress Language Tutorial for Windows
lt-06-04.p
1. The ASC function returns the integer code for a single character. (The integer value is
interpreted from the current character set)
2. The CHR function returns the character equivalent of an integer code. Applying a
character to a fill-in field is equivalent to a user typing that character.
3. When the loop reaches “z,” the LEAVE statement terminates the loop.
• Can use explicit looping with either the TO or WHILE syntax. Using either of these
options creates a loop with an explicit terminating condition.
• Can use a frame other than the default by specifying one with the frame phrase.
6–28
Working with Control Structures
SYNTAX
This simple example of FOR EACH shows the implicit block properties:
1. The record phrase defines the implicit looping of a FOR EACH block. The actual number
of iterations of the FOR EACH statement is the sum of all records of all tables referenced
in the record phrase. However, the FOR EACH statement does not necessarily execute the
statements inside the block for each record of the database table. FOR EACH executes
these statements when the current record matches the criteria specified in the record
phrase. In this example, the statements execute for every record, since no selection criteria
exist.
2. The record phrase is a Progress language structure that lets you specify options for
selecting, sorting, and relating records. In the last chapter, you learned how to create
record-selection expressions using the WHERE syntax. You’ve also seen that specifying
a table name, as in this example, selects all the records of the table. Both of these
techniques are uses of the record phrase.
6–29
Progress Language Tutorial for Windows
3. This statement performs screen output, so Progress creates a default frame for the FOR
EACH block to use.
/*1*/ /*2*/
FOR EACH Customer WHERE Balance < 1000 WITH FRAME Frame3 NO-BOX:
DISPLAY Name.
END.
1. The WHERE expression in the record phrase restricts the number of records that execute
the statement of the block body. Although Progress reads every record and compares it to
the WHERE expression, Progress executes the block statements for only those records
where the Balance field is less than 1000. On the other hand, the default implicit record
reading property executes the block for every record.
2. The frame phrase here names a frame for use with the screen-output statements of the
block. Frame3 could be either a previously defined frame or a new frame created for the
block.
Although the TO and WHILE syntaxes for explicit looping are valid with FOR EACH,
they are not commonly used.
6–30
Working with Control Structures
Internal
FOR Proce- Proce-
Property REPEAT DO Trigger
EACH dure dure
6–31
Progress Language Tutorial for Windows
Practice Problems
Using a FOR EACH block and a DO block, loop through all the customer records and count the number
of customers whose credit limit is greater than $15,000. Display the customer number, name, and credit
limit.
Using the REPEAT block, increment a counter by 1 up to 10 times and display the counter. Once the
counter has a value of 10 leave the REPEAT block.
SYNTAX
IF expression THEN
{ block | statement }
[ ELSE { block | statement } ]
6–32
Working with Control Structures
The code for either the THEN or ELSE branch can be either a statement or a block, as this
example shows:
The block at point 1 executes when the expression is TRUE, while the block at point 2 executes
when the expression is FALSE.
SYNTAX
CASE expression :
{ WHEN value [ OR WHEN value ] ...
THEN { block | statement }
} ...
[ OTHERWISE { block | statement }]
END [ CASE ]
6–33
Progress Language Tutorial for Windows
Follow these steps to see how a CASE statement and a selection list can work together:
1 ♦ Open lt-06-05.p and run it. The display shown below appears:
Exercise
The selection list allows you to choose a chapter. A short description of the chapter then
appears in the editor widget.
6–34
Working with Control Structures
lt-06-05.p
6–35
Progress Language Tutorial for Windows
2. This DEFINE VARIABLE statement sets up the selection list using the VIEW-AS phrase.
3. This syntax makes the screen value of the selection list the conditional expression of the
CASE statement.
4. For each value of the selection list, the branches of the CASE statement assign an
appropriate value to the editor widget.
Practice Problems
Using the IF statement, identify the number of customers that have BBB for their sales rep, the number
of customers that have the sales rep SLS, and the number of customers that have any other sales rep. Use
the Customer.Sales-Rep field.
Do the same thing as in Problem 6-4, except use the CASE statement.
6–36
Working with Control Structures
6.7 Summary
This chapter discussed those features of the Progress 4GL that allow you to control the flow of
execution within your application. Here’s a summary of what you’ve learned.
• The main procedure accesses an internal procedure with the RUN statement.
• An internal procedure is a procedure file that is stored with the main procedure in one
procedure file.
• A user-defined function is like an internal procedure that has some additional capabilities.
It can return a value and the function can be called from within a Progress expression. You
use the FUNCTION statement to create a user-defined function.
• An include file is a text file that contains Progress source code. When you reference
include files in your procedures, Progress replaces the reference with the contents of the
include file at compile time.
• Using shared variables — Shared variables are specially defined variables that more than
one procedure can use.
• Using arguments to pass literals — Literals are programming symbols, such as table
names, field names, or variable names. You can replace the literals with argument
references in your procedure to make your code more generic. Arguments let you pass
literals that allows code to compile.
6–37
Progress Language Tutorial for Windows
Blocks
Blocks are structures that let you group segments of code. Typically a block consists of a block
header statement, Progress 4GL statements, and an END statement. Progress blocks include:
• Procedure blocks — Encompass the entire procedure file (a .p file), but only those
statements that don’t belong to another block actually belong to the procedure block.
• Internal procedure blocks — Begin with the PROCEDURE header statement and are
accessed with the RUN statement.
• Trigger blocks — Allow the user to control an application by directing processing with
events.
• Control blocks — Have specific implicit properties that affect: loping, frame allocation,
and record reading.
• DO — Groups statements together for execution as a single unit. It has no implicit block
properties.
• REPEAT — Provides implicit looping and frame allocation. It has no explicit terminating
condition, but Progress allows a user to end a REPEAT block with the END-ERROR key,
or you can end it programmatically with the LEAVE statement.
• FOR EACH — Provides implicit looping, frame allocation, and record reading. Each
iteration of the block reads a new record from a database table.
• The IF statement lets you test for a condition and then execute code if the expression is
TRUE. The ELSE option lets you specify a second block of code to execute if the
expression is FALSE.
• The CASE statement lets you test the result of an expression against several values.
6–38
7
Representing Data with Widgets
Using the right data widget with a particular variable or database field makes all the difference
in the world to your end users. The nature of many widgets suggests the kind of data they
contain and the ways that users can interact with them. For example, when users see a slider
widget, they know that they are working with numeric data. On the other hand, some widgets,
like the fill-in field, can work with several data types, so a user relies on other cues in your
interface to determine the expected input.
First, this chapter introduces you to some common widget issues. Then the chapter discusses the
syntax, events, attributes, and programming techniques used with:
• Fill-in fields
• Text widgets
• Toggle boxes
• Radio sets
• Sliders
• Selection lists
• Combo boxes
• Editors
Progress Language Tutorial for Windows
Stage Description
Widget definition For variables, the DEFINE VARIABLE statement supports the
VIEW-AS phrase. This phrase enables you to specify a widget
type and define its major characteristics.
For fields, the Data Dictionary supports properties that match all
the options of the DEFINE VARIABLE statement.
Container definition When you define your frames and dialog boxes, you specify the
widgets found in the containers. After each widget reference,
there are several 4GL options you can specify to further define
the characteristics of the widget. Collectively, these options are
referred to as the format phrase.
The DEFINE FRAME statement supports the frame phrase,
which you use to define the characteristics of the frame widget.
Some frame phrase options modify the characteristics of the
widgets contained in the frame.
Before display Progress screen input and output statements, like DISPLAY,
support both the format phrase and the frame phrase. You can
override earlier format and frame phrase options by respecifying
them on a screen I/O statement.
Note that some control blocks also support the frame phrase.
After display After a widget appears on screen, you can no longer modify many
characteristics with 4GL statements. Instead, you must access the
corresponding widget attributes directly. The Progress Language
Reference contains an appendix that details which attributes you
can set in this way.
7–2
Representing Data with Widgets
SYNTAX
VIEW-AS widget-phrase
The widget phrase consist of a keyword that identifies the widget type and the options that go
with that particular type. This chapter covers each widget phrase in detail.
You can specify a VIEW-AS phrase at several points as noted in the following list:
1. Data Dictionary
4. Format phrase on a screen I/O statement (DISPLAY, ENABLE, UPDATE, SET, and
PROMPT-FOR)
7–3
Progress Language Tutorial for Windows
SYNTAX
A frame item can be a constant, a database field, or a variable. After each, you can specify one
or more options from the format phrase to affect, for example, the label, format, or position of
the frame item. The partial syntax below shows the most frequently used options of the format
phrase.
SYNTAX
[ at-phrase | COLON n | TO n ]
[ LABEL string | NO-LABELS]
[ COLUMN-LABEL string ]
[ FORMAT string ]
[ HELP string ]
[ view-as-phrase ]
[ VALIDATE ( condition , msg-expression ) ]
7–4
Representing Data with Widgets
These options all help you design attractive and intuitive displays. Table 7–2 describes the
options.
LABEL string Specifies a display label for field1 LABEL "Display Label"
the widget.
FORMAT string Specifies a format for the data field1 FORMAT "x(12)"
of the widget.
7–5
Progress Language Tutorial for Windows
You can specify one or many format phrase options after each field, variable, or constant at
these points:
Also, you can specify format phrase options for an expression in a screen I/O statement, but not
in a DEFINE FRAME statement. Note the following code example:
Note that the LABEL, COLUMN-LABEL, FORMAT, and VIEW-AS phrase options are also
available on the DEFINE VARIABLE statement.
7–6
Representing Data with Widgets
Positioned with:
AT ROW x COLUMN
Column 40
Positioned with:
COLON 40
Positioned with:
TO 40
7–7
Progress Language Tutorial for Windows
SYNTAX
WITH
[ SIDE-LABELS ]
[ NO-LABELS ]
[ n COLUMNS ]
[ USE-TEXT ]
SIDE-LABELS Puts the frame in side label WITH FRAME Frame1 SIDE-LABELS
mode. The widget labels then
appear on the left sides of the
widgets. The default mode,
column label mode, positions all
labels above the widgets.
n COLUMNS Puts the frame in side label WITH FRAME Frame1 2 COLUMNS
mode and uses the COLON
option to create (n) number of
neat columns.
USE-TEXT Makes all fill-in fields in the WITH FRAME Frame1 USE-TEXT
frame text widgets. Use this
option to display read-only data.
7–8
Representing Data with Widgets
A frame phrase that occurs later in the execution of a procedure overrides one that occurs earlier.
The characteristics of the fill-in field widget in this example are either default
characteristics or characteristics defined with the DEFINE VARIABLE statement.
7–9
Progress Language Tutorial for Windows
2 ♦ Choose the second button. The new display shows the same variable with a new set of
characteristics established by the format phrase and frame phrase in a DEFINE FRAME
statement.
3 ♦ Choose the third button. This display shows the variable with another set of characteristics.
A format phrase and frame phrase on a screen I/O statement (ENABLE) defined these
characteristics.
Now, pause your mouse pointer over the Exit button. Notice a small piece of text that
displays. It is called a ToolTip. A ToolTip is a brief text piece that you can optionally
define for any of the widgets that will be presented in this chapter. You’ll hear more about
ToolTips throughout the chapter and see a few more examples of how to use them.
7–10
Representing Data with Widgets
lt-07-01.p
7–11
Progress Language Tutorial for Windows
1. The DEFINE VARIABLE statement establishes the default characteristics and the
optional characteristics of the widget associated with the variable.
3. This DEFINE FRAME statement alters the characteristics of the widget with both the
format and frame phrases.
4. This run-time screen I/O statement defines a new frame and alters the characteristics of the
widget with both the format and frame phrases.
5. Because Progress creates one of the frames used in this procedure at run time, the trigger
definitions that reference that frame must follow the run-time frame definition.
NOTE: The TOOLTIP attribute noted in the code example is ignored when this code is run
on a character client.
This example also demonstrates the difference between using the frame phrase or IN FRAME
to make an unambiguous reference to a widget. A single screen I/O statement can only work
with the widgets in one frame. Thus the reference to the frame in the frame phrase creates an
unambiguous reference to all widgets in the frame. On the other hand, you can append the
IN FRAME syntax to any widget reference in any other statement to make a single widget
reference unambiguous.
7–12
Representing Data with Widgets
SYNTAX
widget-name:attribute-name
You append the IN FRAME syntax to the widget attribute reference to make the reference
unambiguous, as follows:
SYNTAX
For example, the assignment statement below assigns an attribute value to a variable:
SYNTAX
Like a function, a method always returns a value. For methods, that value is usually LOGICAL
and indicates whether or not Progress successfully applied the method to the widget. Methods
also may use input and output parameters like a function.
Later in the chapter you’ll see programming examples that use methods.
7–13
Progress Language Tutorial for Windows
Widgetname:HANDLE
You may also want to save the handle of a widget in a variable. Since Progress supports widget
handles as a separate data type, you need to specify the WIDGET-HANDLE data type in your
DEFINE VARIABLE statements as this shows:
Progress maintains several global variables that contain widget handles. These variables are part
of a group of language elements known as system handles. System handles allow you to access
information about the system. Table 7–4 describes the system handles that you can use to access
information about widgets.
DEFAULT-WINDOW Contains the widget handle of the window that all Progress
applications create by default. In single-window applications, the
default window is the only window. In multiple-window
applications, you can choose to make another window the default
window.
FOCUS Contains the handle of the widget that currently has input focus.
SELF Contains the handle of the widget for which a trigger is currently
executing.
7–14
Representing Data with Widgets
2 ♦ Press TAB or use the mouse to move input focus or choose a button. Notice that the
variables at the top of the screen keep track of your actions.
7–15
Progress Language Tutorial for Windows
lt-07-02.p
1. The first frame contains the text widgets that track the user’s actions.
7–16
Representing Data with Widgets
3. This trigger executes when any of the four buttons receive the ENTRY event. Notice the
IN FRAME syntax for specifying the location of the widgets.
4. The ENTRY event occurs before Progress actually moves input focus. This APPLY
statement forces Progress to fully move focus to the new widget. Notice the SELF system
handle. No matter which button executes the trigger, Progress evaluates this statement
using the correct button.
5. You can access an attribute of FOCUS or SELF exactly as you would with an explicit
widget reference.
6. On this screen I/O statement, the frame phrase option specifies the correct frame.
8. Again, you access the system handle attribute exactly as you would a named widget.
This form of the ASSIGN statement can be interpreted as “write the screen values of these
widgets to their associated fields or variables.”
7–17
Progress Language Tutorial for Windows
Notice the use of the INTEGER data conversion function. No matter what data type the
underlying field or variable may be, the screen value is always of type CHARACTER.
Assuming that Variable1 is an integer variable, you need to use the appropriate data conversion
function to make the expression compatible.
IF Field1:MODIFIED THEN
ASSIGN Field1.
Validating Input
You saw earlier that the format phrase has a VALIDATE option. You can use this option to
establish validation criteria for variables or to change default validation for database fields.
Although you can use this option instead of the corresponding Data Dictionary properties, it is
far more valuable to use the Data Dictionary as a central source for validation information.
To use the VALIDATE option, specify a condition and a message expression, as shown in this
example:
7–18
Representing Data with Widgets
Programming Example
This programming example demonstrates the techniques discussed in this section:
Exercise
2 ♦ Type a new value for CharField that does not begin with the letter “A.”
3 ♦ Try to move input focus with TAB or the mouse. An alert box appears telling you that the
entry must begin with the letter “A.”
4 ♦ Choose OK. You return to the main display with input focus on CharField. You cannot
move from this field until you make a valid entry.
5 ♦ Type a new value for CharField that does begin with “A” and move input focus. This time
you can.
6 ♦ Try the same experiment with IntField using a number less than 100.
7 ♦ Now that you have changed the screen values, choose Reset. The original values appear.
7–19
Progress Language Tutorial for Windows
8 ♦ Type new valid entries in the fields and choose Save and then Reset. As you can see, your
new values are now also the values stored in the variables.
7–20
Representing Data with Widgets
lt-07-03.p
1. The VALIDATE option of the format phrase establishes a condition that will allow only
input that begins with the letter “A.”
2. Here the VALIDATE option establishes a condition that disallows input less than 100.
7–21
Progress Language Tutorial for Windows
3. This trigger moves the screen values into the associated variables.
4. The IF statement checks the MODIFIED attribute of the widget to see if any changes were
made, and thus whether it is necessary to write a new value.
5. This trigger copies the values of the variables to the screen with the DISPLAY statement.
SYNTAX
The size phrase is a standard Progress way of describing how much room a widget should
occupy. Normally, the size phrase uses this syntax.
SYNTAX
7–22
Representing Data with Widgets
There is an important relationship between the size-phrase and the format string associated with
a fill-in field. As you learned in Chapter 4, “Understanding the Database Environment,” a
format string establishes the defaults for the number of characters a widget can display or accept
as input. Progress uses this information to determine the default size of a fill-in field widget.
You can override the default Progress format string with the FORMAT option on the DEFINE
VARIABLE statement or the format phrase. You can override the default widget size by using
the size phrase of the VIEW-AS phrase. Examine the code fragment below:
1. When Progress defines this variable, it uses the default format string of x(8) for
CHARACTER variables, the default data widget (fill-in field), and creates a default size
for the widget based on the format string. (The default size is the width of eight
average-width characters.)
2. In this example, x(8) is not adequate, so the FORMAT option overrides the default and
makes it x(20). Progress still determines the default size (20 average-width characters)
based on the new FORMAT option.
3. This statement uses a format string of x(40). However, 40 characters take up too much
room on the display, so the size phrase shortens the display area to 20 characters. Now the
widget displays 20 characters, but can accept up to 40. When a user types beyond the 20th
character, the data in the field scrolls to allow the extra input.
• Accepts input focus by way of the navigation key functions (like TAB) or the mouse
7–23
Progress Language Tutorial for Windows
• Allows the user to move the text cursor within the field with the cursor keys or the mouse
• Allows the user to edit the field with the standard field editing keys of the native
environment
2 ♦ Press TAB. Notice the message that appears in the message area. A trigger attached to
ENTRY displays this message.
7–24
Representing Data with Widgets
3 ♦ Press TAB again. Another message appears: “Hey, where’s the tip!” A trigger attached to
LEAVE displays this message.
lt-07-04.p
As you can see at points 1 and 2, simple triggers on ENTRY and LEAVE are all that you need
to extend the functionality of the widget.
NOTE: LEAVE does not execute when you switch focus between windows or on high-level
event functions, such as GO or menu mnemonics.
7–25
Progress Language Tutorial for Windows
• Text widgets take up less screen space on many platforms and print more compactly,
making them valuable for printed reports.
• You can easily switch between fill-in fields and text widgets. The new widget inherits
many of the attributes of the old widget, such as format and label options.
• You can use text widgets to display static text in your interface display without creating a
variable to hold the data.
SYNTAX
7–26
Representing Data with Widgets
The USE-TEXT option on the screen I/O statement converts the fill-in fields in the frame to text
widgets. The USE-TEXT option does not affect any other type of widget.
Practice Problems
You’ve covered quite a bit of new material so far in this chapter. It’s time to cement your new knowledge
in place by putting it to use.
Create a procedure that accepts input for the List Price, Discount, and Tax Rate with fill-in fields. Using
a LEAVE trigger on the Tax Rate field, calculate the adjusted Price, Tax, and Total with text widgets.
7–27
Progress Language Tutorial for Windows
TRUE Marker
Label
Toggle Box
SYNTAX
As mentioned earlier in this chapter, the TOOLTIP attribute allows you to optionally define a
text message string that automatically displays when the mouse pointer pauses over the toggle
box.
7–28
Representing Data with Widgets
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
7–29
Progress Language Tutorial for Windows
2 ♦ Only the toggle box and Exit button are sensitive. Activate the toggle box. A
VALUE-CHANGED trigger calculates the tax and new total.
Note that if you pause your mouse pointer over the toggle box a ToolTip is displayed.
3 ♦ Deactivate the toggle box. The VALUE-CHANGED trigger executes again and calculates
the total without the tax.
7–30
Representing Data with Widgets
lt-07-05.p
7–31
Progress Language Tutorial for Windows
2. USE-TEXT converts the fill-in fields to text widgets without affecting other widgets.
3. Whenever you change the screen value of the widget, VALUE-CHANGED executes,
forcing the appropriate calculation and update.
NOTE: The TOOLTIP attribute noted in the code example is ignored when this code is run
on a character client.
Value
SYNTAX
VIEW-AS RADIO-SET
[ HORIZONTAL | VERTICAL ]
[ size-phrase ]
RADIO-BUTTONS label, value [ label, value ] ...
[ TOOLTIP tooltip ]
7–32
Representing Data with Widgets
Component Description
HORIZONTAL Progress orients the radio buttons vertically by default. Use the
VERTICAL HORIZONTAL keyword to specify horizontal orientation.
size-phrase You probably won’t use the size phrase for radio sets-Progress radio
sets use the native look and spacing of your platform.
label, value For each radio button, specify the screen label and the corresponding
value. Enclose strings in quotes.
TOOLTIP tooltip You can optionally define a text message string that automatically
displays when the mouse pointer pauses over any of the labels defined
for a radio set.
NOTE: Keep in mind that you can access on-line help information about a Progress keyword
by highlighting the keyword and pressing the HELP key function (F1).
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
• Moves input focus among the radio buttons with the cursor keys
7–33
Progress Language Tutorial for Windows
If you pause the mouse pointer over either set of radio buttons, an appropriate ToolTip text
message is displayed.
4 ♦ Press RETURN or SPACEBAR or click to choose a radio button. Note that the Product Code
field updates after each selection.
7–34
Representing Data with Widgets
Here is the code that created the display. This code also shows how to set up the radio sets:
lt-07-06.p
7–35
Progress Language Tutorial for Windows
1. For each label-value pair, Progress creates a radio button. In this case, the screen labels
describe a product and the values represent an internal code. A radio set has vertical
orientation by default. The keyword HORIZONTAL in the VIEW-AS phrase changes the
orientation.
2. The INITIAL option sets the value of the P-code variable to "11".
3. Whenever you select a different radio button, the VALUE-CHANGED event executes and
Progress concatenates and reassigns the values of the radio-set variables to P-code.
NOTE: The ToolTip attribute noted in the code is ignored when this code is run on a
character client.
7–36
Representing Data with Widgets
Practice Problems
You’ve now added two more widgets to your repertoire. Use the problem below to practice what you’ve
learned about the widgets.
Duplicate this display using variables as the basis for the widgets. Use a VALUE-CHANGED trigger to
update the Package Code field. The first three digits come from the index of the radio sets. The last three
digits are "1" if the corresponding toggle box is TRUE and "0" if it is FALSE. (HINT: Use the online help
system to look up the IF... THEN... ELSE function.)
7–37
Progress Language Tutorial for Windows
Current Value
Tic Marks
Trackbar Pointer
SYNTAX
VIEW-AS SLIDER
MAX-VALUE max-value MIN-VALUE min-value
[ HORIZONAL | VERTICAL ]
[ NO-CURRENT-VALUE ]
[ LARGE-TO-SMALL ]
[ TIC-MARKS
{ NONE | TOP | BOTTOM | LEFT | RIGHT | BOTH }
[ FREQUENCY n ]
]
[ size-phrase ]
[ TOOLTIP tooltip ]
NOTE: A slider works best with a mouse. If your environment does not support the mouse,
your users may prefer another data widget.
7–38
Representing Data with Widgets
Element Description
MAX-VALUE Specify the MAX-VALUE keyword and an integer constant to set the
upper limit of the slider’s range.
Consider using the MAX-VALUE option with the
LARGE-TO-SMALL option to indicate that the slider’s maximum
value displays first.
MIN-VALUE Specify the MIN-VALUE keyword and an integer constant to set the
lower limit of the slider’s range. You can use the MAX-VALUE and
MIN-VALUE options with the LARGE-TO-SMALL option to
indicate that the slider’s maximum value displays first and that the
minimum value displays last as the pointer moves along the slider’s
trackbar.
NO-CURRENT- The default is to display the current value for a given position on the
slider ’s trackbar. The NO-CURRENT-VALUE option allows you to
VALUE override this default behavior to indicate that the slider will not
automatically display its current value.
LARGE-TO- The default numeric range that a slider displays is small (minimum)
to large (maximum). The LARGE-TO-SMALL option allows you to
SMALL
override this default behavior as follows:
When the slider is positioned horizontally, the left most position on
the trackbar displays the maximum value and the right most position
displays the minimum value.
When the slider is positioned vertically, the bottom most position on
the trackbar displays the maximum value and the top most position
displays the minimum value.
7–39
Progress Language Tutorial for Windows
Element Description
TIC-MARKS Enables short hash marks to display on the outside of the trackbar to
help define the movement of the pointer in the trackbar. The default
is not to display tic marks. However, if you want to define tic marks,
you must also specify on which side, or sides, of the trackbar you want
tic marks to display by using the additional TOP, BOTTOM, LEFT,
RIGHT, or BOTH qualifying options.
FREQUENCY This option is used only with the TIC-MARKS option to indicate how
often tic marks will display. For example, if you indicate a frequency
of 5, a tic mark displays in every fifth position along the track bar.
size-phrase The size phrase has a few different syntaxes. The tutorial uses the
most portable syntax:
SIZE-CHARS width BY height
where width and height are integer constants.
If the slider has horizontal orientation, the height has to accommodate
the trackbar, pointer, and labels. For character interfaces, the width
should be a multiple or factor of the range to ensure that the pointer
moves in even increments.
If the slider has vertical orientation, the width has to accommodate the
label. The height should be a multiple or factor of the range to ensure
that the pointer moves in even increments.
TOOLTIP tooltip You can optionally define a text message string that automatically
displays when the mouse pointer pauses over the slider.
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
• Moves the slider pointer with either the cursor keys or when a user drags it with a mouse
7–40
Representing Data with Widgets
Note that VALUE-CHANGED works differently in response to the cursor keys and mouse
drags. Every keystroke is a separate event, so VALUE-CHANGED executes after each
keystroke. This behavior effectively means that VALUE-CHANGED executes on every
increment or decrement of the slider value. A mouse drag is a single event, so the user could
move from one end of the slider to the other and VALUE-CHANGED would execute once, at
the conclusion of the drag.
2 ♦ To change the value, drag the pointer located in the trackbar. At each increment, the value
changes, a trigger executes, and the X character moves.
3 ♦ Press TAB to move to the second slider, or just click on the pointer in the second slider.
4 ♦ Use the cursor keys to move the pointer. At each increment, the value changes, a trigger
executes, and the X character moves.
7–41
Progress Language Tutorial for Windows
lt-07-07a.p
1. The first slider is horizontal and displays the X coordinate of the character that moves
within the area of the sliders. Tic marks are defined for every fifth position in the range
and the tic marks display on the bottom of the slider. The NO-CURRENT-VALUE option
indicates that the current value of a position on the slider will not automatically display.
2. The second slider is vertical and displays the Y coordinate of the character. This slider also
has tic marks defined for every numeric position in the defined range. The tic marks
7–42
Representing Data with Widgets
display on the right-hand side of the slider. Also, the LARGE-TO-SMALL option is
defined; for this vertically orientated slider, this means that the bottom most position on
the trackbar displays the maximum value and the top most position displays the minimum
value of the range. The NO-CURRENT-VALUE is set indicating the current position of
the pointer on the slider will not automatically display.
4. The ROW and COL attributes specify the location of the widget within a frame.
NOTE: Keep in mind that ToolTip information can be added to a slider widget. Refer to the
code examples in either the Toggle Box Programming Example or the Radio Set
Programming Example presented earlier in this chapter that show how to define the
TOOLTIP option.
7–43
Progress Language Tutorial for Windows
Label
List Item
7–44
Representing Data with Widgets
The selection list is an extremely flexible widget, as you can see by the options of the VIEW-AS
syntax.
SYNTAX
VIEW-AS SELECTION-LIST
[ SINGLE | MULTIPLE ]
LIST-ITEMS item-list
[ DELIMITER character ]
[ SCROLLBAR-HORIZONTAL ]
[ SCROLLBAR-VERTICAL ]
{ size-phrase | INNER-CHARS cols INNER-LINES rows }
[ SORT ]
[TOOLTIP tooltip ]
Table 7–7 explains some of the elements of the selection list syntax:
Element Description
SINGLE The SINGLE and MULTIPLE options allow you to specify whether the user
MULTIPLE can select a single value from the list or multiple values. Normally, selection
lists have single selection and that is the default. For more information about
MULTIPLE lists, see the Progress Programming Handbook.
DELIMITER After the keyword DELIMITER, you can specify a character other than the
comma to use as the separator in the item list. This option is necessary when
your data could contain commas.
7–45
Progress Language Tutorial for Windows
Element Description
SCROLLBAR-HORIZONTAL If the selection list has more items than the confining rectangle can show,
SCROLLBAR-VERTICAL then the selection list automatically scrolls the values as the user accesses
the top and bottom values in the selection rectangle. Despite this behavior,
specifying a vertical scrollbar with the SCROLLBAR-VERTICAL option
makes it explicit to your users that the selection list contains more items than
they can see.
Specify a horizontal scrollbar with the SCROLLBAR-HORIZONTAL
option when the selection list items are longer than the confining rectangle.
Scrollbars only appear if Progress cannot fit all the items in the display
rectangle.
INNER-CHARS After the keyword INNER-CHARS, specify the number of characters of the
list items you want to appear in the selection list rectangle. Typically, this
value should equal the length of the longest list item plus one. Progress can
then determine the width of the widget.
INNER-LINES After the keyword INNER-LINES, specify the number of list items you
want to appear in the rectangle of the selection list. Progress will then
determine the height of the widget.
SORT This option sorts and displays the list items in alphabetical order. This
option is especially valuable when populating selection lists at run time.
TOOLTIP tooltip You can optionally define a text message string that automatically displays
when the mouse pointer pauses over the selection list.
7–46
Representing Data with Widgets
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
• Moves input focus among the list items with the cursor keys or the mouse
• Responds to alphanumeric keys by moving the cursor to the first list item that begins with
that letter.
DEFAULT-ACTION Event
A default action is an interaction with a widget that signals the widget to perform a task
associated with the widget. For example, issuing a default action with a selection list might
make the display update with new information about the selection. The default action for a
selection list is to press ENTER or RETURN after selecting a list item or to double-click the
desired list item. When a user issues the default action, the DEFAULT-ACTION event occurs,
making this event the one to use for associating tasks with widgets that support a default action.
7–47
Progress Language Tutorial for Windows
Attribute Description
LIST-ITEMS This attribute contains all the list items in a selection list. The attribute
is formatted as a comma-separated list of CHARACTER strings. The
list does not require quotes around the list items.
NUM-ITEMS This attribute is an INTEGER value that indicates how many list
items are in the selection list.
DELIMITER This attribute defines the character that separates the items in the
LIST-ITEMS attribute. By default, it is a comma. However, since data
frequently contains commas and would therefore corrupt the format
of the LIST-ITEMS attribute, you can use the DELIMITER attribute
to select a different delimiter.
Attribute Description
ADD-LAST(list-item) Adds a new list item to the bottom of the selection list. This
method returns TRUE if the method successfully added the
item to the selection list and FALSE if it failed.
LOOKUP(list-item) Returns the INTEGER index of the supplied list item in the
selection list.
7–48
Representing Data with Widgets
1. Use the VIEW-AS phrase without the LIST-ITEMS option. This allows the Progress
compiler to define the widget for use at runtime.
2. Define the list items of the widget before you display it.
All Around Sports is a growing business, and the responsibilities of its sales people are changing
to meet the new challenges. The sales director asks you to design a simple interface so that she
can quickly view and change sales representative assignments.
2 ♦ Click an item to choose it. The form does not update. If the trigger in the procedure used
VALUE-CHANGED, it would have.
7–49
Progress Language Tutorial for Windows
3 ♦ Double-click a sales representative name, Progress accesses the appropriate record from
the sports database and displays some of the fields. The double-click event executes the
DEFAULT-ACTION trigger for the selection list.
7–50
Representing Data with Widgets
lt-07-08.p
7–51
Progress Language Tutorial for Windows
1. Note that the initial definition of the selection list does not include the LIST-ITEMS.
2. By using DEFAULT-ACTION, the fields in the form do not update until the user
double-clicks a list item or presses RETURN or SPACEBAR. The FIND statement, which
you’ll learn about in the next chapter, accesses the appropriate sales representative record.
3. Since the names in the Salesrep table may contain commas, you have to set the
LIST-ITEM delimiter to some character that won’t be in the data. You choose the asterisk.
4. The FOR EACH block cycles through each record in the Salesrep table.
5. The ADD-LAST( ) method adds the current Salesrep name to the bottom of the list. Since
the SORT option is also employed, Progress will sort the list items before you display the
widget.
6. This FIND statement accesses a record so that some data appears at startup.
NOTE: Keep in mind that ToolTip information can be added to any selection list widget.
Refer to the code examples in either the Toggle Box Programming Example or the
Radio Set Programming Example presented earlier in this chapter that show how to
define the TOOLTIP option.
• A SIMPLE combo-box widget with a read/write edit control and a selection list that is
always visible. This widget is supported in graphical interfaces only, and only in
Windows. If you specify a SIMPLE combo-box widget in a character interface, Progress
treats it as a DROP-DOWN-LIST combo-box widget.
• A DROP-DOWN combo-box widget with a read/write edit control and a selection list that
appears when you click the drop-down button. This option is supported in graphical
interfaces only, and only in Windows. If you specify a DROP-DOWN combo-box widget
in a character interface, Progress treats it as a DROP-DOWN-LIST combo-box widget.
7–52
Representing Data with Widgets
You can use the combo-box widget with a CHARACTER, INTEGER, DECIMAL, LOGICAL,
or DATE field or variable. The value representations in the drop-down list conform to the data
type of the underlying field or variable. Like radio sets and selection lists, combo boxes are
useful for representing fields or variables that have a limited number of possible values. One
advantage of combo boxes is that they take up less screen space than radio sets and selection
lists.
To select a value in the graphical interface, the end user can apply the following techniques:
• Position to the value in the drop-down list using the scroll bar and click on the value in the
drop-down list using the SELECT mouse button.
• Enter text in the fill-in and allow the edit control to complete keyboard input to the
combo-box, based on a potential or unique match, by searching through the items in the
drop-down list.
• Position to the value in the drop-down list using the arrow keys and press SPACEBAR or
RETURN to confirm the selection.
Label Button
Drop-Down List
7–53
Progress Language Tutorial for Windows
SYNTAX
VIEW-AS COMBO-BOX
[ LIST-ITEMS item-list | LIST-ITEM-PAIRS item-pair-list ]
[ INNER-LINES lines ] [ size-phrase ] [ SORT ]
[ TOOLTIP tooltip ]
[ SIMPLE | DROP-DOWN| DROP-DOWN-LIST ]
[ MAX-CHARS characters ]
[ AUTO-COMPLETION [ UNIQUE-MATCH ] ]
Element Description
LIST-ITEM-PAIRS Specify a list of label-value pairs. Each pair represents the label
and value of a field or variable. When the user selects a label,
Progress assigns the corresponding value to the field or variable.
INNER LINES Specify the number of entries that the drop-down list can display.
If you set INNER-LINES to less than the actual number of
entries, the user can scroll through the drop-down list.
TOOLTIP tooltip Defines a text message string that automatically displays when
the mouse pointer pauses over the combo box.
7–54
Representing Data with Widgets
Element Description
MAX-CHARS Specify the maximum number of characters the edit control can
hold.
UNIQUE-MATCH Specify that the edit control complete keyboard input to the
combo-box, based on a unique match, by searching through the
items in the drop-down list.
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
• Moves input focus among the drop-down list items with the cursor keys
7–55
Progress Language Tutorial for Windows
Exercise 1 ♦ Open lt-07-09.p and run it. The display shown below appears:
This application calculates the correct local arrival time of a U.S. domestic flight.
2 ♦ Choose the button for the Departure Time Zone combo box. The drop-down list appears.
You select a value as you do with a selection list.
5 ♦ Choose the Calculate button. The application displays the local arrival time.
7–56
Representing Data with Widgets
lt-07-09.p
1. This DEFINE VARIABLE statement sets up the first combo box with the VIEW-AS
phrase.
2. This DEFINE VARIABLE statement uses the LIKE option to inherit the characteristics of
the first combo box. The other options override specific inherited characteristics.
3. This expression uses departure time and flight time to calculate arrival time. It also uses
the LOOKUP method of the combo box to determine the index values of the selected time
zones. The expression uses these values to adjust the arrival time to the arrival time zone.
Finally, the MOD operator keeps the result in 24 hour format.
7–57
Progress Language Tutorial for Windows
NOTE: Keep in mind that tooltip information can be added to a combo box widget. Refer to
the code examples in either the Toggle Box Programming Example or the Radio Set
Programming Example earlier in this chapter that show how to define the TOOLTIP
option.
Label
Text Area
SYNTAX
VIEW-AS EDITOR
{ size-phrase | INNER-CHARS chars INNER-LINES lines }
[ BUFFER-CHARS chars ]
[ BUFFER-LINES lines ]
[ LARGE ]
[ MAX-CHARS chars ]
[ SCROLLBAR-VERTICAL ]
[ NO-WORD-WRAP [ SCROLLBAR-HORIZONTAL ]]
[ TOOLTIP tooltip ]
7–58
Representing Data with Widgets
Component Description
size-phrase You might want to use the size phrase with an editor to
fit an editor into a particular area of a display. In this
case, use this syntax:
SIZE-CHARS WIDTH cols HEIGHT rows
Where cols and rows are integer constants.
BUFFER-CHARS Use the two buffer options when the text area of an
editor widget is larger than the rectangular area set up
by the previous options. In this case, the editor
rectangle shows only part of the text area at one time.
Use BUFFER-CHARS with an integer constant to
specify the number of characters that one line of the
editor can hold.
7–59
Progress Language Tutorial for Windows
Component Description
SCROLLBAR-VERTICAL When an editor can hold more lines than it can display,
use this option to enable a vertical scrollbar.
TOOLTIP tooltip You can optionally define a text message string that
automatically displays when the mouse pointer pauses
over the editor.
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse
• Moves the text cursor with the arrow keys or the mouse
For information about the attributes and methods associated with more sophisticated editors, see
the Progress Programming Handbook.
7–60
Representing Data with Widgets
1 ♦ Open lt-07-10.p and run it. The display shown below appears:
Exercise
2 ♦ Select the editor widget. The text cursor appears in the widget.
7–61
Progress Language Tutorial for Windows
lt-07-10.p
Simply by defining the size with the INNER-CHARS and INNER-LINES options at point 1,
Progress creates an editor with the text-handling behavior the user expects.
NOTE: Keep in mind that ToolTip information can be added to an editor widget. Refer to the
code examples in either the Toggle Box Programming Example or the Radio Set
Programming Example presented earlier in this chapter that show how to define the
TOOLTIP option.
7–62
Representing Data with Widgets
Practice Problems
The problem below gives you some practice with sliders, selection lists, combo boxes, and editors.
It seems that All Around Sports needs to add another display to its on-line questionnaire application. It needs
widgets to record customer responses to these questions.
A. What percentage of your business is in sports equipment?
B. What percentage of your business is in sports supplies?
C. What percentage of your business is in sports apparel?
D. Of the following categories, which best describes your business?
Department store, general sports retailer, specialty sports retailer, secondary distributor, mail order
distributor, sports club
Create the display All Around Sports needs, using these directions.
Use an editor capable of holding 25 lines of 60 characters to implement question F. However, make the editor
small enough to fit in the same display as the other widgets.
7–63
Progress Language Tutorial for Windows
7.10 Summary
This chapter covered the language elements used to define general widget characteristics as well
as the specific elements used to define data widgets.
• Widget definition — For variables, the DEFINE VARIABLE statement supports the
VIEW-AS phrase and other options to define the major characteristics of a widget. For
database fields, the Data Dictionary supports properties which correspond to all the
options of the DEFINE VARIABLE statement.
• Container definition — When you define your frames and dialog boxes, you specify the
widgets found in those containers and define the characteristics of the widget with the
format phrase. The DEFINE FRAME statement also supports the frame phrase, which has
options that modify the characteristics of the widgets contained in the frame.
• Before display — Progress screen I/O statements support both the format phrase and the
frame phrase.
• After display — After a widget appears on screen, you access widget attributes directly
to redefine widget characteristics.
Programming Widgets
Data widgets are representation of database fields or variables. The data widgets include:
• Fill-in field — The default widget representation for all fields and variables. It presents
data as modifiable text.
• Text widget — Basically a fill-in field for read-only data. Text widgets are useful because
they take up less room than fill-ins on some operating platforms and in reports.
• Radio set — A graphical representation of a field or variable that has a limited number of
possible values. Only one value can be true at a time.
7–64
Representing Data with Widgets
• Selection list — Presents the user with a scrolling list of possible values for a
CHARACTER field or variable.
• Editor — A large rectangular area for displaying and editing long text.
You can create ToolTip information for all of the data widgets previously listed.
7–65
Progress Language Tutorial for Windows
7–66
8
Using Database Records
Up to this point, you’ve learned about interfaces and procedure without learning much about
database access. The tutorial uses this approach because database access techniques make more
sense in the context of fully functional procedures. In this chapter, you’ll learn complete
database access techniques that draw on what you already know about interfaces and
procedures.
Specifically, this chapter describes:
• Retrieving data
• Using queries
• Modifying data
• Releasing records
• Creating records
• Deleting records
1. Your procedure cannot interact with data until the procedure copies the data from the
database to a record buffer. Once in the record buffer, the procedure can manipulate that
data.
2. End users cannot interact with data until your procedure copies the data from the record
buffer to the screen buffer. Once in the screen buffer, the data is visible on screen.
8–2
Using Database Records
3. Progress does not automatically copy changes made in a screen buffer or a record buffer
to the related buffer. For example, if a copy of a particular field exists in both a record
buffer and a screen buffer, changing the data in the screen buffer does not change the data
in the record buffer. Your procedure programmatically controls the movement of data
between buffers.
Think of the data locations as stops along a two-way street. To display a database record,
Progress must first move it to a record buffer and then into a screen buffer. Similarly, Progress
cannot write new screen buffer data to a database without first writing it to a record buffer.
Figure 8–2 shows how data moves in Progress.
8–3
Progress Language Tutorial for Windows
Up to this point, the tutorial used the terms “underlying value” to refer to a record buffer value
and “screen value” to refer to a screen buffer value. (The screen value of a widget is a screen
buffer value.)
Notice the distinction in Figure 8–2 between batch and user manipulation. If you write a
procedure that processes records behind the scenes, then your procedure works exclusively with
record buffers. If you write a procedure that allows users to interact with the data, the procedure
also works with screen buffers. At some point, your interactive procedure copies data between
the screen buffers and record buffers. This chapter focuses on the techniques of interactive
database access.
8–4
Using Database Records
• Displays key data so users know that they are interacting with the correct record
• Separates update mode from display mode and lets users decide whether to save or cancel
their changes on a record-by-record basis
• Lets users create new records and lets the user decide whether to keep or discard the new
record
• Allows users to delete records, but asks for confirmation before deleting the record
8–5
Progress Language Tutorial for Windows
In Figure 8–3, the form’s buttons execute triggers that perform these user tasks: navigate and
display, update, add, and delete. Figure 8–4 shows how the form and triggers work together.
OK Cancel
8–6
Using Database Records
This chapter shows you how to build this fully functional database access form. This simple
model is one that you can use in most situations. The form is also flexible enough to
accommodate many of the advanced techniques that you can learn about in the Progress
Programming Handbook.
SYNTAX
statement-name
table-name [ record-phrase-options ][ statement-options ]
8–7
Progress Language Tutorial for Windows
• FOR statement
• DO PRESELECT statement
It is a good rule of thumb to use field lists only when you are referencing less than 90% of the
record. When you are referencing more than 90%, it makes more sense to fetch the entire record.
Also keep in mind these rules when you use field lists:
• Specify all the fields you plan to reference in your field lists.
• Specify the entire database record if you are updating or deleting the record. Otherwise, if
you delete or update a record from a Progress database, Progress rereads the complete
record before completing the transaction.
8–8
Using Database Records
The lt-08-08.p procedure shows a revision of an example from Chapter 7, “Representing Data
with Widgets,” that uses the FIELDS option of the FOR statement to read only the fields
referenced in this application. This is the revised code:
lt-08-08.p
8–9
Progress Language Tutorial for Windows
1. This FOR statement uses the FIELDS option to specify a field list instead of fetching the
entire record.
2. The Sales-Rep and Region fields of the Salesrep table are also referenced in the
application, but they do not appear in the field list because they are referenced outside of
the FOR statement.
SYNTAX
database-name.table-name
Progress flags all ambiguous references at compilation time. Many programmers always specify
the full reference to avoid ambiguity and make more readable code.
SYNTAX
database-name.table-name.field-name
It is also important to remember that the expanded reference to a database field is also a
reference to the widget that represents it. In most cases, Progress knows from the context of your
code whether you are working with the record buffer (database value) or screen buffer (widget
screen value).
8–10
Using Database Records
The following code, which comes from the include file, sets up the database access form:
lt-08-f1.i
The frame in this code fragment is the main display for the database access form. Notice how
the database references here refer to the widgets associated with the database fields. You can
think of this frame as a formatted representation of the screen buffer.
About Queries
A query is a request for database data that results in one or more records. A results or results list
is the record or set of records defined by a query. Some Progress statements query the database
directly. Other statements work with the results list of a predefined query to query the database.
A results list points to all the records that satisfy a predefined query. For example, the FIND
statement queries the database directly, while the GET statement queries through the results list
of a predefined query.
In general, the Progress documentation uses “query” to refer to a predefined query created with
the DEFINE QUERY and OPEN QUERY statements.
8–11
Progress Language Tutorial for Windows
8–12
Using Database Records
The FIND statement retrieves an individual record and is the basis for the triggers associated
with the navigation buttons. FIND copies a record from a database to a record buffer, as shown
in Figure 8–6.
SYNTAX
FIND
{ FIRST | NEXT | PREV | LAST | CURRENT } record-phrase
NO-ERROR
When you think about it, there are four records that you search for most often in database
applications. They are the first record, the record next after the one currently in the record
buffer, the record previous to the one currently in the record buffer, and the last record. Progress
supports four keywords for the FIND statement to specify these records: FIRST, NEXT, PREV,
and LAST.
With just these four keywords, you have enough context to create an application that
interactively searches one by one through the records of a database table. The record phrase only
has to specify a table name to complete a valid statement, as shown below:
The FIND statement uses the primary index of the database table to determine which record is
first and last. In the next chapter, you’ll learn how to navigate through the records in different
orders.
8–13
Progress Language Tutorial for Windows
The NO-ERROR option suppresses the normal error messages and default behavior that the
RDBMS executes if the FIND attempt fails. Use NO-ERROR when you want to handle error
conditions in your procedure. The programming example at the end of this section demonstrates
error handling.
Once you have a record in the buffer, you can display that record. You’ve already seen the
DISPLAY statement several times. The function of the DISPLAY statement is to move data
from a record buffer into a screen buffer, and thus make the data visible to the user, as shown
in Figure 8–7.
8–14
Using Database Records
SYNTAX
DISPLAY
[ expression [ format-phrase ]
| SPACE [ ( n ) ]
| SKIP [ ( n ) ]
] ...
{ [ frame-phrase ] }
This is an alternate syntax (partial) of the DISPLAY statement for displaying whole records.
SYNTAX
DISPLAY record
[ EXCEPT field ... ]
{ [ frame-phrase ] }
Component Description
frame-phrase The frame phrase lets you specify a particular frame in which to
display the data, as well as frame-formatting options.
EXCEPT Specify fields from the record to not display with the record.
8–15
Progress Language Tutorial for Windows
1 ♦ Open lt-08-01.p and run it. The Database Access Form appears.
Exercise
2 ♦ Choose the Next button several times and notice the changes to the Item No. field. The
procedure navigates through the records starting with the lowest item number and moving
to the highest. FIND uses the Item-Num field for the navigation order because it is the
primary index of the Item table.
3 ♦ Choose Prev until the form displays item number 1. Now choose Prev again. Normally,
trying to find the previous record of the first record would be an error. This procedure,
however, defines the LAST record as the PREV record of the FIRST record. The
procedure also defines the NEXT record of the LAST record as the FIRST record.
8–16
Using Database Records
lt-08-01.p
1. This statement includes the file that contains the frame and button definitions that make
up the interface.
2. The first FIND statement (in the Main Logic section) creates the Item buffer and copies
the first record from the database to the record buffer. The NO-ERROR option is not
necessary here. As long as the table contains one record, Progress will find a record that
satisfies the request. If the RDBMS encounters any other errors, then you want the default
messages and behaviors to execute.
3. This trigger executes when the user chooses the Prev button. It finds the previous record,
which is the record that comes before the current record according to the primary index. If
the current record is the first record (no previous record exists) it finds the last record.
8–17
Progress Language Tutorial for Windows
4. This FIND statement clears the Item buffer, locates the previous record, and copies it to
the Item buffer. The NO-ERROR option suppresses the normal error response. Normally,
if Progress cannot find the previous record, the RDBMS sends a message to the user and
the procedure stops execution of the current code block, which is the trigger. With the
NO-ERROR option, the user gets no error message and the procedure continues executing
the code block. However, because Progress clears the Item buffer during the FIND
request, there is no current record. Any attempt to access the buffer later results in an error.
5. This IF statement checks the Item buffer with the AVAILABLE function. This test allows
you to handle error conditions. If there is no record in the Item buffer, then the FIND
statement failed. If it failed, then it probably failed because the user tried to find the
previous record of the first record. In this situation, finding the last record puts data into
the empty buffer.
6. The DISPLAY statement refreshes the form with the new data in the record buffer.
7. This trigger executes when the user chooses the Next button. It finds the next record,
which is the record that comes after the current record according to the primary index. If
the current record is the last record (no next record exists) it finds the first record.
8. This FIND statement copies the next record to the Item buffer.
9. This IF statement defines the normal behavior for trying to find the next record of the last
record—find the first record.
1. Established the query with the DEFINE QUERY statement at the top of the procedure in
the definitions section.
2. Initialize the results list with the OPEN QUERY statement at the beginning of your main
code block.
8–18
Using Database Records
3. Navigate through the results list with the GET statement, or by using a browse widget, but
not with both.
4. Release the query resources with the CLOSE QUERY statement at the end of your main
code block.
To start with, the DEFINE QUERY statement lets you name your new query and requires you
to list all the tables that the query uses. This is a partial syntax for the DEFINE QUERY
statement.
SYNTAX
Use the SCROLLING option if you plan to use a browse widget or the REPOSITION statement
with the query. SCROLLING is almost always necessary for an interactive database procedure.
Next, you need to initialize the results list with the OPEN QUERY statement. This is a partial
syntax for the OPEN QUERY statement.
SYNTAX
Each instance of the FIND statement uses a record phrase. With a defined query, the record
phrase does its work up front in the OPEN QUERY statement. Therefore, the GET statement
has no need to support the record phrase.
Now, you’re ready to navigate through the results list. The next few sections of this chapter
show you how to do this.
Finally, when you finish working with a query, you should close it. This is the syntax for the
CLOSE QUERY statement.
SYNTAX
8–19
Progress Language Tutorial for Windows
SYNTAX
As with FIND, the four keywords specify which record you are trying to get. Following the
keyword, you provide the name of the query, not the actual table name:
8–20
Using Database Records
Notice that the GET statement does not support the NO-ERROR option. In the last
programming example, you saw that NO-ERROR is very useful for suppressing undesirable
error behavior with the FIND statement. GET does not support the NO-ERROR option because
a failed GET does not invoke an error response. For example, suppose you try to get the next
record of the last record. The GET statement moves the results list cursor to a null position, and
clears the associated record buffer, which remains empty. This condition is known as being off
the end of the results list.
You can use the AVAILABLE function to check for this error condition (an empty record
buffer), or you can use a special query function: QUERY-OFF-END. This is the syntax for
QUERY-OFF-END.
SYNTAX
QUERY-OFF-END ( query-name )
The function takes the query name as a string and returns TRUE if the cursor is off either the
top or bottom end of the results list. Here is a code example using this query function:
Exercise 1 ♦ Open lt-08-02.p and run it. The database access form appears.
2 ♦ Choose the Prev and Next buttons and notice the changes to the Item No. and Name fields.
The code works precisely the same as the FIND statement version.
8–21
Progress Language Tutorial for Windows
lt-08-02.p
2. OPEN QUERY at the beginning of the main code block initializes the results list that
defines the matching subset of records. You cannot use GET until after you open the
query.
3. The GET statement creates a record buffer and copies a record to the buffer from the
database using the query results list.
4. This trigger performs the “retrieve next or retrieve first record” logic, exactly as in the
FIND example. Here, the GET statement replaces the FIND statement and the
QUERY-OFF-END function replaces the AVAILABLE function.
8–22
Using Database Records
5. This trigger performs the “retrieve previous or retrieve last record” logic, exactly as in the
FIND example.
6. The CLOSE QUERY statement after the WAIT-FOR statement releases the resources
used by the query.
Practice Problems
The basic form used in the programming examples can quickly be refitted for use with any other table.
Use the Customer table with the problems below to practice what you have learned so far.
Using the FIND and DISPLAY statements, create a procedure that lets you review records in the
Customer table.
Make a copy olist:f the procedure you created in Problem 8-1. Replace the FIND statements with
DEFINE QUERY and GET statements.
8–23
Progress Language Tutorial for Windows
Both techniques use the database access form and the Update button as shown in Figure 8–9.
1. Use a DISPLAY statement to copy data from the variable to the widget that represents that
variable.
2. Use an ENABLE statement to let the user interact with the widget and the screen value.
3. On some event, use an ASSIGN statement to copy the screen value back to the variable.
Using the form in Figure 8–9, you could follow the same sequence of steps to change database
data. Choosing the Update button will be the event that copies the current screen buffer to the
record buffer and eventually to the database.
To use this basic technique with database records, you need to learn more about locks,
ROWIDs, ENABLE, and ASSIGN.
8–24
Using Database Records
Locks
The technique listed above may not work well with database records because of the possibility
that more than one user might try to use a record at the same time. Since most Progress
applications are designed to work with multiple users, this technique needs modification to
support multi-user mode. The Progress RDBMS has two basic rules for a database in multi-user
mode:
2. Only one user at a time can access a record to change the data.
When a user retrieves a record, Progress puts the user’s copy of the record in one of three lock
states. A lock is a description on the user’s freedom to use the record. Progress has three
keywords that describe the lock states, as shown in Table 8–2.
Lock Description
NO-LOCK The user can only view the data. Progress puts the user’s record
in this state if the NO-LOCK keyword is included in the record
phrase.
To let the greatest number of users successfully access a particular record, it makes sense to
keep the record in NO-LOCK state. The application should only upgrade the lock to
EXCLUSIVE-LOCK during the act of changing data. This means that the record is tied up for
the shortest possible period of time.
8–25
Progress Language Tutorial for Windows
SYNTAX
ROWID ( buffer-name )
This code fragment shows how to retrieve and store a ROWID for later use:
The programming example at the end of this section demonstrates how to use ROWIDs and how
to take specific control over locks. First, you need a more in-depth look at the ENABLE and
ASSIGN statements.
ENABLE Statement
You saw in the last section that the DISPLAY statement moves data from the record buffer to
the screen buffer. ENABLE allows users to enter data directly into the screen buffer, as shown
in Figure 8–10.
8–26
Using Database Records
SYNTAX
Use the EXCEPT widget syntax to enable all the widgets in a frame, except for those you
specify.
ASSIGN Statement
You also have encountered the ASSIGN statement. ASSIGN moves data from the screen buffer
to the record buffer, as shown in Figure 8–11.
SYNTAX
ASSIGN
{{ field | field = expression } ...
record [ EXCEPT field ] ...
}
You can assign fields or the entire record. The EXCEPT syntax is also valid with ASSIGN.
8–27
Progress Language Tutorial for Windows
By using DISPLAY, ENABLE, and ASSIGN together, you create a chain of functionality that
presents current data to your users, allows them to change it, and allows them to save the
changes.
NOTE: Using the DISPLAY, ENABLE, and ASSIGN technique does not automatically
invoke the validation behaviors stored in the Data Dictionary. To force the validation
routines to run, you can query the VALIDATION attribute of a widget or frame. For
more information, see the Progress Programming Handbook. The other techniques
described in this section do invoke Data Dictionary validation.
Exercise 1 ♦ Open lt-08-03.p and run it. Note that the form now uses fill-ins instead of text widgets.
3 ♦ Choose the Next followed by the Prev button. The record does not contain the new data.
This procedure does not save your changes unless you choose the Update button.
5 ♦ Choose the Next followed by the Prev button. The new data is now permanent.
8–28
Using Database Records
lt-08-03.p
ON CHOOSE OF btn-Update
DO:
/*5*/ Current-Record = ROWID(Item).
/*6*/ FIND FIRST Item WHERE ROWID(Item) = Current-Record EXCLUSIVE-LOCK.
/*7*/ IF AVAILABLE(Item) THEN
ASSIGN Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description.
/*8*/ ELSE DO:
FIND FIRST Item WHERE ROWID(Item) = Current-Record NO-LOCK.
MESSAGE "Record in use. Unable to update."
VIEW-AS ALERT-BOX WARNING BUTTONS OK Title "Update Error".
END.
END.
/********** MAIN LOGIC **********/
/*1*/ OPEN QUERY Item-Query FOR EACH Item NO-LOCK.
GET FIRST Item-Query.
DISPLAY Item.Item-Num Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description WITH FRAME Frame1.
/*2*/ ENABLE Item.Item-Name Price On-Hand Allocated Re-Order On-Order
Cat-Page Cat-Description btn-Prev btn-Next btn-Update btn-Exit
WITH FRAME Frame1.
WAIT-FOR CHOOSE OF btn-Exit.
CLOSE QUERY Item-Query.
1. In the main code block, the OPEN QUERY statement contains the NO-LOCK option. This
means that navigating through the records or leaving the application running will not
impede other users.
3. This variable will hold the current ROWID when trying to upgrade a lock.
4. This include file contains the navigation triggers which you have already studied.
8–29
Progress Language Tutorial for Windows
5. Once the user chooses Update, this trigger executes. Here, the trigger saves the ROWID
of the current Item record.
6. Recall that FIND retrieves an individual record. This trigger uses FIND to get a copy of
the record with the EXCLUSIVE-LOCK option. The FIND statement does not affect the
defined query.
7. If any other user has EXCLUSIVE-LOCK or SHARE-LOCK, the FIND will fail, which
is why this IF statement checks the record buffer. If the record is there, the user’s changes
are saved with the ASSIGN statement.
8. If the FIND failed, then refind the record with a NO-LOCK and inform the user.
One way to keep data accessible to all users is to keep the data in NO-LOCK and let the user
change it. When it is time to assign the changes, use the FIND CURRENT or GET CURRENT
statement to get a fresh copy of the record that the user has been modifying with an
EXCLUSIVE-LOCK. Then, use the CURRENT-CHANGED function to test for changes to the
record while the user was working with it. If the record was changed by another user, you can
send a message to the user and display the updated record. If the record is unchanged, you can
assign the changes.
8–30
Using Database Records
You can use this trigger code in place of the trigger code for btn-Update in lt-08-03.p as the
following code fragment illustrates:
.
.
.
ON CHOOSE OF btn-Update
DO:
GET CURRENT Item EXCLUSIVE-LOCK.
IF AVAILABLE(Item) THEN
IF NOT CURRENT-CHANGED Item THEN
ASSIGN Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description.
ELSE DO:
MESSAGE "Record has been changed by another user.
Redisplaying new data.".
DISPLAY Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description.
END.
ELSE DO:
FIND FIRST Item WHERE ROWID(Item) = Current-Record NO-LOCK.
MESSAGE "Record in use. Unable to update."
VIEW-AS ALERT-BOX WARNING BUTTONS OK Title "Update Error".
DISPLAY Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description.
END.
END.
.
.
.
8–31
Progress Language Tutorial for Windows
UPDATE Statement
To put it succinctly, the UPDATE statement is a powerful statement that does the work of the
DISPLAY, ENABLE, ASSIGN, and WAIT-FOR statements. The procedure below is a
complete application that does much of the work of the last programming example:
REPEAT:
END.
• Assigns changes after receiving the GO event function. (Pressing F2 executes GO.
After finishing with each record, the user presses F2 to move on to the next record.)
4. Iterates until it encounters an error condition: either no more records exist or the user
issues the ENDKEY (F5) event function. If the user issues ENDKEY, any changes made
to the current record are discarded.
8–32
Using Database Records
This application is not very flexible, but illustrates both the power of UPDATE and why
UPDATE should normally not be used with an event-driven procedure. As you saw in the
description above, UPDATE blocks application while waiting for GO. If you mixed an update
statement with a WAIT-FOR statement, you would have explicit application blocking and
implicit application blocking conflicting with each other. The result would be confusing to the
end user. UPDATE should be used by itself. As you you’ll see later in the section, you can
combine UPDATE with a dialog box to provide a separate update mode for database records.
Figure 8–12 shows the data movement with UPDATE.
SYNTAX
UPDATE
{ field
| SPACE [ ( n ) ]
| SKIP [ ( n ) ]
} ... { [ frame-phrase ] }
8–33
Progress Language Tutorial for Windows
Dialog Boxes
A dialog box is a container widget that disables all widgets located in other container widgets
while the dialog box is enabled. Since all other widgets are disabled, you can execute an
UPDATE statement with a dialog box from within a block of code that includes a WAIT-FOR
statement. Since the implied application blocking of the UPDATE statement cannot interfere
with the explicit application blocking of the WAIT-FOR, this combination elegantly creates an
update mode.
You create a dialog box by specifying the VIEW-AS DIALOG BOX option in the frame phrase.
The dialog box appears on top of all other frames and stays there until the user or the application
dismisses it. In this case, completing the UPDATE statement dismisses the dialog box. So, if
the user presses F2 (GO), UPDATE assigns the changes and the dialog box disappears. If the user
presses F4 (ENDKEY), the changes are discarded and the dialog box disappears.
The use of the GO and ENDKEY keystrokes are not very elegant in an event-driven application.
Fortunately, the DEFINE BUTTON statement supports options that let buttons automatically
execute the GO and ENDKEY event functions: AUTO-GO and AUTO-ENDKEY. If you
define a button labeled OK with the AUTO-GO option and another button labeled Cancel with
the AUTO-ENDKEY option, you have an interface that fits in nicely with the conventions of
an event-driven application.
8–34
Using Database Records
1 ♦ Open lt-08-04.p and run it. The display appears as shown below, with the fields on the
Exercise form represented as text widgets:
8–35
Progress Language Tutorial for Windows
Note that you cannot move focus to any widget outside the dialog box.
3 ♦ Change the data and choose Cancel. The dialog box disappears and the main form remains
unchanged.
4 ♦ Choose Update again, change some data, and Choose OK. The dialog box disappears and
the main form shows your changes.
8–36
Using Database Records
lt-08-04.p
ON CHOOSE OF btn-Update
DO:
/*2*/ Current-Record = ROWID(Item).
FIND FIRST Item WHERE ROWID(Item) = Current-Record
EXCLUSIVE-LOCK.
IF AVAILABLE(Item) THEN DO:
/*3*/ UPDATE Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description btn-OK btn-Cancel
WITH FRAME Dialog1.
DISPLAY Item-Num Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description WITH FRAME Frame1.
END.
/*4*/ ELSE DO:
FIND FIRST Item WHERE ROWID(Item) = Current-Record NO-LOCK.
MESSAGE "Record in use. Unable to update."
VIEW-AS ALERT-BOX WARNING BUTTONS OK Title "Update Error".
END.
END.
8–37
Progress Language Tutorial for Windows
1. In the main code block, the NO-LOCK option lets all users have complete access.
4. Again, if the lock upgrade fails, refind the record with NO-LOCK and notify the user.
As a general rule, you could say that a record’s scope ends on a new record request or an END
statement. That statement is subject to many exceptions and some special situations where
Progress allows you to bend the rules. As you work through this tutorial, the general rule of
thumb holds. When you finish working with the tutorial, you can read more about record
scoping in the Progress Programming Handbook.
Earlier in the tutorial, you learned that Progress can create and maintain a separate record buffer
for each database table. Actually, each block that can own a record buffer can have a separate
record buffer for the same database table. Blocks that can have buffers include:
• Procedures
• FOR EACH
8–38
Using Database Records
If a block is not capable of owning its own buffer then it uses the buffer of the block in which
it resides. So, unless you have heavily nested blocks, the block uses its own buffer or the main
procedure block’s buffer.
The idea of multiple buffers is important because it means your procedures can work on more
than one record from a table at a time.
Explicit Release
You can end the scope of a record prematurely by forcing Progress to release it with the
RELEASE statement.
This is the syntax for the RELEASE statement.
SYNTAX
RELEASE record
8–39
Progress Language Tutorial for Windows
Practice Problems
Make a copy of your solution to Problem 8-2. Now, add the ability to update the fields of your customer
review program using the UPDATE statement and a dialog box.
SYNTAX
CREATE table-name
As soon as you create a record, you’ll want to fill it with data. One way to acquire new data for
the record is to use a dialog box with an UPDATE statement.
8–40
Using Database Records
1 ♦ Open the file named lt-08-05.p and run it. The following display appears:
Exercise
8–41
Progress Language Tutorial for Windows
2 ♦ Choose Add, enter data in the update dialog box, shown below, and choose OK:
8–42
Using Database Records
lt-08-05.p
ON CHOOSE OF btn-Add
DO:
/*1*/ CREATE Item.
/*2*/ UPDATE Item.Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description btn-OK btn-Cancel
WITH FRAME Dialog1.
/*3*/ DISPLAY Item-Num Item-Name Price On-Hand Allocated Re-Order
On-Order Cat-Page Cat-Description WITH FRAME Frame1.
END.
1. The CREATE statement establishes the record and interacts with the schema to get default
values.
2. Since the record has EXCLUSIVE-LOCK, you can move right to an UPDATE statement.
3. The DISPLAY statement refreshes the main form with the new data.
8–43
Progress Language Tutorial for Windows
2. Upgrade to an EXCLUSIVE-LOCK.
Figure 8–15 shows the data movement for the DELETE statement.
SYNTAX
The VALIDATE function accepts an expression and a message to check and make sure that the
deletion is allowable according to your business rules.
8–44
Using Database Records
Exercise
2 ♦ Choose the Prev button to get one of the records you created in the last exercise. Since the
new records were created with high customer numbers, they appear last in the record list.
(Cust-Num is the primary index.)
An alert box is a sophisticated alternative for sending messages to the status area. The
status area is an extension of the window widget and so is the alert box.
8–45
Progress Language Tutorial for Windows
In event-driven programming, alert boxes ask questions of the user or present the user with
important information. Since alert boxes are bearers of important news, they block the rest
of the interface—like a dialog box—until the user responds to them.
The reason that a major new component is introduced right in the middle of a discussion
on the DELETE statement has to do with good programming style. Good event-driven
programming style dictates that you should always have the user confirm deletion of
important data with an alert box. Chapter 12, “Managing Your Application,” discusses
how alert boxes work.
If you try to delete one of the records that come with the sports database, you may get alert
boxes explaining why you can’t delete the record. These behaviors are established by
database triggers in the schema. They are a way of enforcing business rules.
8–46
Using Database Records
lt-08-06.p
8–47
Progress Language Tutorial for Windows
1. A special VIEW-AS syntax on a MESSAGE statement reroutes a message from the status
area to an alert box. The UPDATE option and variable captures the user’s response to the
question.
5. Reopening the query rebuilds the results list without the newly deleted record.
Practice Problems
Make a copy of your solution to problem 8-3. Add the ability to create new customer records and to delete
customer records using the techniques covered in this chapter.
8–48
Using Database Records
SYNTAX
PROMPT-FOR
{ field
| SPACE [ ( n ) ]
| SKIP [ ( n ) ]
} ... { [ frame-phrase ] }
8–49
Progress Language Tutorial for Windows
SYNTAX
SET
{ field
| SPACE [ ( n ) ]
| SKIP [ ( n ) ]
} ...
{ [ frame-phrase ] }
8–50
Using Database Records
SYNTAX
INSERT record
[ EXCEPT field ... ] { [ frame-phrase ]}
8–51
Progress Language Tutorial for Windows
Column Labels
Viewport
Highlight Bar
Record
8–52
Using Database Records
When you use a browse to let the user view and update record values, it is called an updatable
browse. Figure 8–20 describes the parts of an updatable browse widget.
Selectable
Column Labels
Row Marker
Selected Row
8–53
Progress Language Tutorial for Windows
You can update the form you’ve built in this chapter by replacing the navigation buttons with
an updatable browse widget, as shown in Figure 8–21.
• The type of row marker indicator that displays can vary depending on the platform
on which you are running the Progress character client.
• The mouse cannot be used to select and access records from either a read-only or an
updatable browse widget when the browse widget is displayed in character client
mode on Windows platforms. You must use the keyboard features.
8–54
Using Database Records
The syntax for a browse widget looks like a DISPLAY statement with a frame phrase attached,
but it’s not. The browse widget mimics the syntax of the DISPLAY statement because it is
intuitive and employs many of the same concepts. This is a partial syntax for defining a browse
widget.
SYNTAX
Table 8–3 defines some of the elements of the DEFINE BROWSE statement syntax.
Element Description
query-name To specify the name of the query with which the browse is associated.
expression To specify the field or expression for each column. You can include a
format phrase and LABEL option for each field reference.
format-phrase To override the database format string, include one using the
FORMAT "string" syntax. You can use the WIDTH option to
specify a column width.
options-phrase To specify the number of records to show in the browse with the
DOWN rows option after the WITH keyword. Otherwise, Progress
sets the size of the browse. Alternately, you can use the size-phrase
to determine a precise size, and Progress will determine the number
of rows it can display in the browse viewport. For a complete list of
options, see the Progress Language Reference.
This syntax mimics the true frame phrase.
8–55
Progress Language Tutorial for Windows
Read-only Browse
A read-only browse is a good mechanism for viewing records without allowing any changes.
When you click anywhere in a row, Progress selects that row.
Updatable Browse
An updatable browse is a good mechanism for applying changes to your data. You can add,
delete and update records with an updatable browse. The capabilities of the updatable browse
are very similar to those of a spreadsheet application. You can view and update records at the
same time.
To select a row in an updatable browse widget, click on the row marker on the left side of the
browse. When you click a cell in a row, Progress enters edit mode for that cell if you have
enabled the column for input. When the browse enters edit mode, Progress executes a
ROW-ENTRY event. When you move focus away from that row, Progress executes a
ROW-LEAVE event followed by a VALUE-CHANGED event, and writes any changes to the
database.
To define an updatable browse, use the browse-enable-phrase of the DEFINE BROWSE
statement. You can enable one to all the columns in a browse for input with the ENABLE
option. Remember not to allow changes to a unique index, such as Cust-Num or Item-Num.
8–56
Using Database Records
Common
Keyboard
Key Function
Mappings on Description
Windows
8–57
Progress Language Tutorial for Windows
Common
Keyboard
Key Function
Mappings on Description
Windows
8–58
Using Database Records
Common
Keyboard
Key Function
Mappings on Description
Windows
8–59
Progress Language Tutorial for Windows
Browse Events
An enabled browse widget accepts many events. The browse:
• Accepts input focus by way of the navigation key functions (such as TAB) or the mouse.
• Moves input focus among the records with the arrow keys.
• ENTRY — Occurs when the user enters the named column in the focused row.
• LEAVE — Occurs when the user leaves the named column in the focused row.
• START-SEARCH — Occurs when the user chooses a column label and enters search
mode.
• END-SEARCH — Occurs when the user selects a row or starts to edit a browse cell after
a START-SEARCH has occurred.
• ROW-LEAVE — Occurs when the user or system moves focus away from a row.
8–60
Using Database Records
Exercise 1 ♦ Open lt-08-07.p and run it. The Database Access Form appears.
2 ♦ Select an item using the row marker to the left of the row.
3 ♦ Click on a cell other than the Item Number. Make a change in the Item-Name, Price,
On-hand, or Cat-Description field.
4 ♦ Move focus to another row. Notice that Progress saved your changes to the updated field.
8–61
Progress Language Tutorial for Windows
lt-08-07a.p
These notes explain the highlights of the first part of the programming example:
1. To use a browse with a query, include the SCROLLING option on the DEFINE QUERY
statement.
2. This statement defines the browse widget, the fields it displays, and the number of rows it
shows at one time. The ENABLE option defines this as an updatable browse where all
fields except Item-Num can be changed.
3. These statements define the widgets and frames for the procedure.
8–62
Using Database Records
lt-08-07b.p
.
.
.
/*5*/ ON ROW-LEAVE OF BROWSE Item-Browse DO:
IF Item-Browse:NEW-ROW IN FRAME Frame1 THEN DO:
CREATE Item.
ASSIGN Item-Num = NEXT-VALUE(next-item-num)
/*6*/ INPUT BROWSE Item-Browse Item-Name Price On-hand
Cat-Description.
/*7*/ Method-Status = Item-Browse:CREATE-RESULT-LIST-ENTRY().
/*8*/ DISPLAY Item-Num WITH BROWSE Item-Browse.
END.
END.
These notes explain the highlights of the second half of the programming example.
1. This DO statement executes when changing focus from a row in browse Item-Browse. For
new records, the IF...THEN statement updates the browse.
2. The INPUT BROWSE option of the ASSIGN statement writes the new information to the
database.
4. This statement displays the Item-Num assigned to a new record by the database.
8–63
Progress Language Tutorial for Windows
Column Searching
Read-only browse widgets employ single-character searches on the first column of the browse.
That means that if the user presses an alphanumeric key, the browse moves focus to the next
row where the first column begins with that letter or number.
Updatable browse widgets employ the same kind of single-character search, but on any column.
When the user selects a column label, Progress enters search mode for that column. When the
user presses an alphanumeric key, the browse moves focus to the next row where the selected
column begins with that letter or number.
You can override the default searching behavior to implement incremental searching in
updatable browse widgets. See the browse widget chapter in the Progress Programming
Handbook for information on how to add this feature to your application.
• Moving columns
• Locking columns
• Calculated fields
• Searching
8–64
Using Database Records
8.11 Summary
Primarily, you work with three data locations:
• Databases
• Memory used to store records that the procedure is working with, called record buffers
• Memory used to store data that is visible on the screen, called screen buffers
Progress creates and maintains buffers for you, but you programmatically control the movement
of data between buffers. Some rules about data and buffers:
• Procedures cannot interact with data until the data is copied to the record buffer from the
database.
• End users cannot work with data until it is copied from the record buffer to the screen
buffer.
• Changes made to one buffer do not automatically affect the other buffer.
To make an unambiguous reference to a database field, specify the database name, table name,
and field name using this syntax: database.table.field
The following list summarizes the data handling statements:
• GET — Copies data from the database to the record buffer. You use GET with a defined
query. Progress has three statements that control defined queries:
• OPEN QUERY — Uses the record phrase to define the records that are part of the
query.
• DISPLAY — Moves data from the record buffer to the screen buffer.
• ASSIGN — Moves data from the screen buffer to the record buffer.
• RELEASE — Prematurely releases a record from the record buffer to the RDBMS.
8–65
Progress Language Tutorial for Windows
• CREATE — Adds a new record to the database and copies the empty record to the record
buffer.
• DELETE — Marks a record for deletion and releases the record to the RDBMS for
eventual removal from the database.
• PROMPT-FOR — Allows user input from the user to the screen buffer.
When working with records, your procedures should handle the basic error processing
associated with not finding a record. Using the NO-ERROR option suppresses the Progress
default error response. Use the AVAILABLE function to test the record buffer before
attempting to use the buffer.
The PROMPT-FOR, SET, UPDATE, and INSERT statements all have implied blocking
properties. These statements block execution until the user issues either a GO event or an
ENDKEY event. Because of this behavior, these statements must never be mixed with
WAIT-FOR statements.
To facilitate the GO and ENDKEY events more easily, you can associate buttons with the
events using the AUTO-GO and AUTO-ENDKEY options in a DEFINE BUTTON statement.
The length of time a record stays in the record buffer is called the scope of the record. As a very
general rule of thumb, a record’s scope ends when a new record is requested or the block in
which the buffer was created ends.
Alert boxes are extensions to the window widget that provide important information to users
and disable the rest of the interface until the user responds to the alert box.
A browse widget is a specialized selection list for displaying data from database tables:
• The most common event function for the browse widget is VALUE-CHANGED.
VALUE-CHANGED executes every time you change the “row focus” of the browse
widget from one row to another.
8–66
9
Selecting, Sorting, and Relating Records
This chapter describes the important options of the record phrase and how to use them in the
context of an interactive database form. The options contribute to your ability to select a record
or set of records, to sort records, and to relate records from different tables.
Specifically, the chapter covers:
For more information on the record phrase and database access techniques, see the Progress
Programming Handbook.
Progress Language Tutorial for Windows
• The FIND statement locates an individual record. The record phrase options help specify
the record.
• The FOR EACH block is most valuable in batch applications where records are processed
linearly. The options of the record phrase help select which records are executed with the
statements inside the block. You can also sort and relate records with the FOR EACH
block.
• The OPEN QUERY statement establishes a results list of records. Record phrase options
help select, sort, and relate the records to form the results list.
To continue the focus on interactive database applications, this chapter teaches record phrase
options in the context of a defined query. Notes along the way point out any significant
differences in the use of an option with FIND or FOR EACH.
SYNTAX
9–2
Selecting, Sorting, and Relating Records
This syntax diagram shows a partial syntax for the record phrase, listing the selection options.
SYNTAX
record-name
[ WHERE expression ]
[ USING [ FRAME frame ] field
[ AND [ FRAME frame ] field ] ...
]
Component Description
USING Specifies a screen value to use as the selection criteria. For example,
you can have the user enter a region name, and then use that data to
create a list of all the customers from that region.
9–3
Progress Language Tutorial for Windows
In addition to the expressions you learned about in Chapter 5, “Working with Expressions,”
WHERE supports operators that make working with CHARACTER data easier:
• BEGINS
• =
• MATCHES
• CONTAINS
This example of BEGINS finds any record where the field reference begins with the same letters
as specified in the option:
OPEN QUERY My-Query FOR EACH Customer WHERE Customer.Name BEGINS "Smith".
The output from this selection criteria includes Smith, Smithers, Smithy, and so on.
This example of MATCHES finds any record where there is an exact match between the
supplied string and the database field reference:
OPEN QUERY My-Query FOR EACH Customer WHERE Customer.Name MATCHES "Tim".
This example finds Tim. However, MATCHES is very slow compared to using BEGINS. In
most cases, substituting the = operator is far more efficient than using MATCHES.
You can use two wildcards with the MATCHES options, and this is the only use where
MATCHES has an advantage over the other comparison operators. Use asterisk (*) to take the
place of many characters and period (.) to take the place of a single character as shown in the
following example:
OPEN QUERY My-Query FOR EACH Customer WHERE Customer.Name MATCHES "T.m".
9–4
Selecting, Sorting, and Relating Records
This example finds Tam, Tim, and Tom. Remember, do not use MATCHES unless there is no
other way to write the expression with another operator. The most common use of MATCHES
is to search for an expression that begins with a wildcard. For example "*berry". This example
would find Strawberry, Blueberry, Raspberry, and so on in a list of fruits.
NOTE: You can use BEGINS and MATCHES in any CHARACTER expression.
When a field is defined as a word index in the database schema, you can use the CONTAINS
option. CONTAINS checks whether the supplied string is contained anywhere in the field
reference. Review the following code example that presents the CONTAINS option:
In this example, the new query will build a results list of Customer records that have the same
postal code and the same country name as the current screen value of Postal-Code and Country:
OPEN QUERY My-Query FOR EACH Customer USING Country AND Postal-Code.
The examples assume that a user has entered a value for Postal-Code and Country. Progress
attempts to match these values to database records.
You can code similar functionality by prompting the user to enter a value into a variable, then
using that variable in a WHERE clause, as shown below:
9–5
Progress Language Tutorial for Windows
4 ♦ Choose the fourth Query button. This example uses the USING option, so you have to
provide a value to search for. A dialog box appears to prompt you for the Item-Num.
5 ♦ Type an integer from 1 to 55, then choose OK. The browse widget displays the results.
9–6
Selecting, Sorting, and Relating Records
lt-09-01.p
9–7
Progress Language Tutorial for Windows
1. Even though the procedure makes several queries, each query uses the same table (Item)
and only one query is active at a time. Therefore, you need only one defined query.
2. Similarly, although the procedure uses the browse widget to display several queries, only
one is displayed at a time.
3. The first query uses a WHERE expression to display all the inventory items with item
numbers greater than 45.
4. The second query uses a WHERE BEGINS query to list all the items with names that
begin with "ski".
5. The third query uses a WHERE MATCHES query to see if any of the item names end with
"ball".
6. The fourth query uses the USING option to allow the user to define the query. The USING
item accepts a screen value for a table field, then finds the records that have that value.
9–8
Selecting, Sorting, and Relating Records
SYNTAX
Component Description
BY expression Specifies an expression to use as the basis for sorting the selected
records. The FIND statement does not support BY.
ASCENDING Ascending sorts begin with the lowest value and go to the highest
DESCENDING value (A, B, C, D). Descending sorts start with the highest value and
go toward the lowest value (Z, X, Y, W). By default, sorting is always
ascending, so you don’t need to specify the ASCENDING keyword.
To use descending order, you must specify the DESCENDING
keyword in the BY phrase.
USE-INDEX Forces Progress to sort the selected records using a defined index.
• BY field
• BY expression
9–9
Progress Language Tutorial for Windows
The simplest technique is to supply a database field name as this code example shows:
OPEN QUERY My-Query FOR EACH Customer WHERE Country = "USA" BY Postal-Code.
The first example selects all United States-based companies and sorts the records by postal
code, which is the ZIP code. This code could be used with an envelope-printing procedure to
meet the sorting requirements of the U. S. Postal Service.
You can use multiple BY phrases in the same query as this example shows:
The first BY option is the primary sort order, and the second is the secondary sort order, and so
on. In other words, this code first sorts the customers by their base country. Records within each
country group are then sorted by postal code. With just a little more code, you’ve
internationalized your envelope application.
9–10
Selecting, Sorting, and Relating Records
Exercise
As you can see, for each record, the procedure calculated the cost of shipping insurance.
Since this is a descending list, you can quickly pick out which items cost more than $1 to
insure.
9–11
Progress Language Tutorial for Windows
lt-09-02.p
1. In the widget definition statement, you include space for a calculated field (Price / 100),
which is a temporary new field based on the value of other fields.
2. In the OPEN QUERY statement, you use the expression that corresponds to the calculated
field in order to sort the calculated field. The descending option places those products with
higher insurance charges at the top of the list.
OPEN QUERY My-Query FOR EACH Item WHERE Price > 50 USE-INDEX Item-Name
In this example, the records for all items over $50 are sorted by product name.
9–12
Selecting, Sorting, and Relating Records
2 ♦ Choose the BY ASCENDING Price button. A browse widget appears with the results of
the query. In the status area, notice the message that shows the selection and sorting syntax
used in the OPEN QUERY statement.
9–13
Progress Language Tutorial for Windows
lt-09-03.p
9–14
Selecting, Sorting, and Relating Records
These notes describe querying and sorting to help explain the code:
1. The BY phrase sorts the selected records by a non-indexed field, Price. The sort is
ascending by default.
2. This BY phrase also sorts the selected records by Price, but the DESCENDING option
forces a descending sort.
3. The USE-INDEX option makes clear to the query which of the defined indexes to use for
the sort order. Again, this sort is ascending by default.
Practice Problems
Problem 9-1:
The code for the first example, lt-09-01.p, provides a nice shell for creating your own queries. Make a
copy of the procedure and use it to experiment with querying. Use the different selection and sorting
techniques. Also try using a different database table.
In a paper system, finding related data in different tables would be a tedious manual task. In
some databases, you’d also have a hard time accomplishing this task. You need to use a
relational database to put together data from related files, and you’ve got one with Progress.
This process is also called joining tables or creating a join. For more information on joins, see
the section on inner and outer joins later in this chapter.
9–15
Progress Language Tutorial for Windows
9–16
Selecting, Sorting, and Relating Records
Table records can have several types of relations, but for the most part, programmers work with
two: one-to-one relationships and one-to-many relationships. Relationship types describe the
way a particular record in one table can relate to one or more records in another table.
The first relationship type is called a one-to-one relationship and occurs when one record can
relate to only one instance of a record in another table. For example, each customer order
contains one or more order lines. An order line is a request for a quantity of a particular item.
Therefore for each order line, there is only one inventory item, as shown in Figure 9–2.
Order-Line Item
Customer Order
9–17
Progress Language Tutorial for Windows
SYNTAX
SYNTAX
SYNTAX
9–18
Selecting, Sorting, and Relating Records
Component Description
OF table Allows you to relate two tables. You can use OF only when the two
tables share an identical field and that field is indexed in at least one
of the tables.
FOR EACH Customer:
FOR EACH Order OF Customer
WHERE Relates two tables in the same way OF does. With WHERE, however,
expression the fields do not need to be indexed and they don’t have to have the
same name.
FOR EACH Customer:
FOR EACH Order WHERE Order.Cust-Num = Customer.Cust-Num
EACH Allows you to build compound FOR EACH and OPEN QUERY
record-phrase statements. For example, you can simplify this code:
9–19
Progress Language Tutorial for Windows
Both the tables have a Cust-Num field, so a key does exist. If the key has the same name in both
tables and is indexed in at least one, you can use the easiest method for relating the records, the
OF option.
NOTE: For the OF keyword to properly detect a relationship between two tables, only one
such relationship is allowed. If there are two or more fields in two tables with the
same name and at least one of each is indexed, a relationship will not be detected.
The OPEN QUERY statements you’ve seen so far search through one table. You need to search
through two. So, it makes sense that you need two search phrases as the following code example
shows:
This is where you use the EACH phrase. Each EACH searches a different table. But, this syntax
still doesn’t relate the tables. You have to use OF as the following code example shows:
OF relates the second EACH back to the first EACH. The result is that the first Customer record
is found. Next, Progress finds every Order record that has the same Cust-Num as the first
Customer record.
9–20
Selecting, Sorting, and Relating Records
Follow these steps for a demonstration that implements the above scenario:
Exercise
2 ♦ Scroll through the records. The browse lists only Customers with current orders, and lists
every order number for customers with multiple orders.
9–21
Progress Language Tutorial for Windows
lt-09-04.p
1. Since you need to work with more than one table, you have to list the tables in the DEFINE
QUERY statement.
2. This code searches for and does an implicit comparison on the Cust-Num key field.
In both of these cases, you may want to reconsider your design. Consider adding an index or
changing the name of the field.
9–22
Selecting, Sorting, and Relating Records
You can also use WHERE to do any relation that OF can do. The following example uses OF:
OF implicitly compares the keys, while WHERE explicitly compares the keys. At compile time,
Progress turns an OF into a WHERE expression. For that reason, you should consider OF a
shortcut and use WHERE most of the time.
Follow these steps for a demonstration of the last exercise reworked to use WHERE:
1 ♦ Open lt-09-05.p and run it. The same display as in the last exercise appears:
Exercise
9–23
Progress Language Tutorial for Windows
2 ♦ Scroll through the records. As you can see, the same data is present.
lt-09-05.p
As shown at point 1, you still need the additional EACH to search through the second table. The
WHERE expression causes an explicit mathematical comparison between key values.
9–24
Selecting, Sorting, and Relating Records
• Inner join — Supported in all statements capable of reading multiple tables, including the
FOR, DO, REPEAT, and OPEN QUERY statements. An inner join returns the records
selected for the table (or join) on the left side of the join with the related records selected
from the table on the right side of the join. If a value in the left table does not have a
corresponding value in the right table, Progress does not return that value or a result for
the results list. This is an example of an inner join with the FOR statemen:.
In this join, Table1 is on the left side of the join and Table2 is on the right, and
Field1 = Field3 is a join condition. For any records not selected from Table2, the join
returns no records from either the Table1 or Table2. Only records that are selected from
both tables are returned for an inner join.
• Left outer join — Supported only in the OPEN QUERY statement. An outer join returns
the same set of records selected for an inner join. However, outer joins also return all the
records from the left table. When a value from the left table does not have a corresponding
value in the right table, Progress returns the left-table value with an unknown value (?)
from the right table. This is an example of a left outer join with the OPEN QUERY
statement:
In this join, Table1 is on the left side and Table2 is on the right, and Field1 = Field3 is a
join condition.
9–25
Progress Language Tutorial for Windows
Figure 9–4 illustrates the results of an inner join. Note that the only values included from Table1
are the values that match the join conditions. Also, the value where Field1 = 2 appears twice in
the join because there are two instances where Field3 = 2 in Table2. For any values in Field1
that do not match a value in Field3, the entire Table1 record is excluded from the join. Likewise,
for any values in Field3 that do not match any value in Field1, the entire Table2 record is
excluded from the join.
Join12
Field1 Field2 Field3 Field4
1 2 1 6
2 4 2 2
2 4 2 5
9–26
Selecting, Sorting, and Relating Records
Figure 9–5 illustrates the results of a left outer join. Note that all values in Table1 are included
in the join, even where they do not have a corresponding value in Table2. The unknown value
is used in Field3 and Field4 where there is no value in Field3 corresponding to the value of
Field1. Thus, the values of Field3 that do not match any values in Field1 are still excluded from
the join.
Join12
Field1 Field2 Field3 Field4
1 2 1 6
2 4 2 2
2 4 2 5
5 7 ? ?
6 9 ? ?
9–27
Progress Language Tutorial for Windows
Practice Problems
Using a copy of procedure lt-09-04.p as a starting point, figure out the correct syntax for these queries:
Display the customer name and the sales representative for each customer. What kind of relationship is
this?
For each customer, list all the product names currently on order. What type of relationship is this?
9.5 Summary
This chapter explained how to select, sort, and relate records from different tables.
Selection Options
These options allow you to specify which records to retrieve:
• The WHERE option uses any valid Progress expression to select records. WHERE
supports options that allow you to specify how to select CHARACTER data:
– BEGINS finds records where the field begins with a particular string.
– MATCHES finds records where the field matches a string, but should only be used
with wildcards, since the = operator is much more efficient for full string matches.
9–28
Selecting, Sorting, and Relating Records
Sorting Options
These options allow you to specify how to sort the records:
• The BY phrase allows you to sort by one or more fields (these don’t have to be indexed)
or by expressions based on fields.
Relating Records
Database tables have a relationship if they have a field with identical data in common. There are
two kinds of relationships between tables:
• A one-to-one relationship occurs when one record in a table relates to only one record in
another table.
• A one-to-many relationship occurs when one record can relate to many records in another
table.
The field with identical data that is held in common between two tables is called the key.
Three options allow you to establish relationships between database tables:
• The OF option allows you to relate tables in a search by specifying the key field. The key
must be an indexed field in at least one of the tables.
• The WHERE option relates tables in which the key is not an indexed field, or the key field
doesn’t have the same name in both tables.
9–29
Progress Language Tutorial for Windows
9–30
10
Creating Reports
A database management system provides information that helps an organization run efficiently.
A report—whether printed on paper, viewed on a workstation, or stored on media—is a
common tool for distributing database information.
This chapter introduces you to the 4GL statements that you can use to generate reports, both
simple and complex. Specifically, it discusses these topics:
• Report basics
• A special type of frame, called a down frame, that can hold more than one iteration of data
• Text widgets
• An output statement
10–2
Creating Reports
The default frame of an iterating control block, like FOR EACH, is a down frame. You can also
specify a down frame with the DOWN keyword of the frame phrase. DOWN used alone
indicates that you want Progress to fit as many iterations in the frame as the screen can hold.
Here is an example:
Specifying an integer before DOWN indicates the maximum number of iterations the frame can
hold. Here is an example:
If the default data widget is anything other than a fill-in field or text widget, you need to use the
VIEW-AS TEXT option of the format phrase on each widget to convert the widget to a text
widget. Here is an example:
10–3
Progress Language Tutorial for Windows
Remember that the default data representation for a field comes from the schema of the
database, while the default for a variable comes from the DEFINE VARIABLE statement.
10–4
Creating Reports
1 ♦ Open lt-10-01.p and run it. Progress creates a down frame that occupies all the vertical
Exercise
space it can and fills the frame with iterations of data, as shown below:
Notice the message at the bottom of the screen. Progress pauses to allow you to view the
first frame of data.
2 ♦ Press SPACEBAR. Progress clears the down frame and fills it with a new set of iterations.
10–5
Progress Language Tutorial for Windows
lt-10-01.p
/*3*/ FOR EACH Customer FIELDS (Name Balance) WITH FRAME Frame1:
IF BALANCE > 0 THEN Bal-due = YES.
ELSE Bal-due = NO.
/*4*/ DISPLAY Name Bal-due.
END.
1. The default data widget for this LOGICAL variable is a toggle box, making the VIEW-AS
TEXT phrase necessary to convert it to a text widget.
2. The frame phrase of the DEFINE FRAME statement contains two key options: DOWN
and USE-TEXT. The DOWN keyword specifies a down frame that automatically expands
to fit as many iterations as the screen can hold. Specifying an integer before DOWN sets
the maximum number of iterations the frame can hold. USE-TEXT converts all fill-in
fields into text widgets for a compact display.
3. Since the great majority of reports compile and manipulate table data, the FOR EACH
statement is the most common control block used for report procedures. The frame phrase
here replaces the default down frame with the named down frame defined earlier.
4. The DISPLAY statement is the most commonly used output statement. As you’ll see later,
DISPLAY can output to terminals, printers, or files.
10–6
Creating Reports
The type of report display created by procedure lt-10-01.p does not fit well with the
event-driven model because the user:
The next section describes a technique for viewing reports that better suits the event-driven
model.
1. A dialog box to contain the output. Therefore, you won’t need to leave room on your main
display for the report data.
2. An OK button in the dialog box to let the user dismiss the report.
3. A temporary file to contain the report data. Having the control block output to a temporary
file eliminates the pausing behavior.
4. An editor widget with scrollbars to read the file into. The scrollbars let the user navigate
the report in two directions.
10–7
Progress Language Tutorial for Windows
The next example creates a dialog box interface for the same report you saw in the last example.
The notes that follow the exercise explain the new code techniques you need to make this
interface work.
Exercise 1 ♦ Open lt-10-02.p and run it. The following screen displays:
10–8
Creating Reports
The report data appears in an editor that you can scroll through.
4 ♦ Choose Exit and then press SPACEBAR to return to the Procedure Editor.
10–9
Progress Language Tutorial for Windows
lt-10-02.p
10–10
Creating Reports
These notes explain the new code techniques used in this example:
2. The OUTPUT TO statement is your tool for directing output. This example directs output
to the named file. This chapter covers directing output more fully in a later section.
3. This FOR EACH uses the default down frame, and the STREAM-IO option reduces all
widgets to textual data without decorations. Using the STREAM-IO option is a
requirement when outputting to any destination other than the screen.
4. Once you direct output to a destination, you need to close the output stream to return
output to the default destination, which is the screen.
5. This ASSIGN statement manipulates three editor attributes and one method to set up the
dialog box. The READ-ONLY attribute prevents changes to the report content. The
SENSITIVE attribute enables the editor, making the scrolling functions available. The
TITLE attribute contains the dialog box title text. The READ-FILE method takes a valid
filename and returns YES or NO to indicate if Progress successfully read the file contents
into the editor.
6. You only want to bring up the dialog box if the logical variable stat equals YES, which
means that Progress successfully read the file into the editor.
7. If you use a WAIT-FOR statement in a dialog box, you must use the HIDE statement to
dismiss the dialog box.
8. On all platforms that Progress supports, the output font designated by 3 is always a
monospaced font, which are frequently used in printed reports. Assigning this font makes
the editor contents mimic a printed report.
10–11
Progress Language Tutorial for Windows
• Using the STREAM-IO option of the frame phrase to convert all data widgets in a frame
to text widgets
• Using the editor for formatting long text strings as blocks of text
You must use the STREAM-IO option on every output frame intended for a destination other
than the screen.
Although primarily a tool for sending data to files and reports, the STREAM-IO option also
reduces all widgets to textual data for screen output. This exercise demonstrates the effects of
the STREAM-IO option on screen data. Perform the following steps:
Exercise
1 ♦ Open lt-10-03.p and run it. This report is the same as the one from the last exercise, but
without the special interface.
10–12
Creating Reports
3 ♦ Remove STREAM-IO from the frame phrase and run the procedure again.
Note that the Bal-Due variable displays as a disabled toggle box in the iterations.
If you scroll through the text of the procedure, you can see that the STREAM-IO option on the
frame phrase of the iterating block is the only change.
10–13
Progress Language Tutorial for Windows
Exercise 2 ♦ Choose Report. The report dialog box appears as shown in the following screen:
As you scroll through the editor, notice the blocks of Comments text.
3 ♦ Choose OK, then Exit, and then press SPACEBAR to return to the Procedure Editor.
10–14
Creating Reports
lt-10-04.p
INNER-LINES reserves at least three lines per iteration of the report. INNER-CHARS sets the
length of the text block at 25 characters.
INNER-LINES reserves at least three lines per iteration of the report. INNER-CHARS sets the
length of the text block at 20 characters.
This section concludes the basic discussion on creating a reporting procedure. The next few
sections concentrate on the techniques for populating reports with more complex data.
10–15
Progress Language Tutorial for Windows
A control break separates sorted data into meaningful groups. Breaking sorted data by Sales-rep
separates each sales rep’s customers into a separate break group. Break groups allow you to
calculate summary data on subsets of data. For example, you could total the number of
customers that each sales rep serves.
The BREAK option of the record phrase sets up your data for control breaks, as shown in this
block header statement:
Once you’ve set up the control break, you can use the aggregate phrase on an output statement
item to calculate summary information. The diagram below shows the syntax of the aggregate
phrase.
SYNTAX
10–16
Creating Reports
SUB-COUNT Counts the number of items in the break group, but does not
calculate the overall count.
SUB-TOTAL Calculates the total of all the expression’s values, but does
not calculate the overall total for the break groups.
For example, in the code below, Sales-rep is the control break, Balance is the expression, and
the aggregate phrase with the TOTAL option appears in parenthesis immediately after the
expression in the DISPLAY statement:
The TOTAL aggregate option totals the balances for each break group. Each time the value of
Sales-rep changes in the sorted data, Progress creates another break group, and the TOTAL BY
aggregate function calculates and outputs the total of customer balances for that sales rep’s
customers. Finally, at the end of the report, the TOTAL option calculates and outputs the total
balances of all the break groups.
10–17
Progress Language Tutorial for Windows
Exercise 2 ♦ Choose Report. The report dialog box appears as shown in the following screen:
The members of each break group all have the same Sales-rep value. Notice that the report
separates each break group with white space and outputs the result of the aggregate phrase
options immediately following the break groups.
If you scroll to the bottom of the report, you can see the aggregate values for all the break
groups.
3 ♦ Choose OK, then Exit, and then press SPACEBAR to return to the Procedure Editor.
10–18
Creating Reports
lt-10-05.p
1. The BREAK option of the record phrase sets up the control break.
2. The aggregate phrase after the Balance expression contains three aggregate options.
10–19
Progress Language Tutorial for Windows
• Sort information
The reports you have seen so far display data from a single table (the Customer table) and
demonstrate one or two reporting features. Real world reports, however, frequently do a little
bit of everything as they strive to organize lots of information and calculate useful summary
information.
For example, suppose the All Around Sports accounting department needs to analyze
delinquent accounts. To do their jobs, the accountants need information on customers, orders,
and inventory. To get all the data they need, the report requires information from four tables:
the Customer, Order, Order-line, and Item tables. The rest of this section builds a report that
gathers and organizes information from these four tables and performs some summary
calculations on the data.
lt-10-06.p
.
.
.
FOR EACH Customer FIELDS (Balance Credit-Limit Name Contact)
WHERE Balance >= (Credit-Limit * .85)
WITH STREAM-IO:
DISPLAY Name FORMAT "x(20)" Contact FORMAT "x(15)"
Balance Credit-Limit WITH NO-BOX.
END.
.
.
.
10–20
Creating Reports
The WHERE clause selects just the customers over the 85 percent threshold, and the DISPLAY
statement outputs the key information about these customers. Running this procedure yields the
output shown below:
10–21
Progress Language Tutorial for Windows
The code below from lt-10-07.p shows the nested FOR EACH blocks:
lt-10-07.p
.
.
.
FOR EACH Customer FIELDS (Balance Credit-Limit Name Contact Cust-Num)
WHERE Balance >= (Credit-Limit * .85)
WITH STREAM-IO:
DISPLAY Name FORMAT "x(20)" Contact FORMAT "x(15)"
Balance Credit-Limit WITH NO-BOX.
The output from this procedure (following) shows how the related information ends up grouped
together:
Notice that for a single iteration of the Customer data, there may be several iterations of Order
data. Earlier you learned that the default frame of an iterating control block is a down frame.
When you nest control blocks, only the innermost block uses a down frame. The other blocks
10–22
Creating Reports
execute one iteration at a time. This default behavior lets the related information group together
naturally with the iteration of the blocks.
10–23
Progress Language Tutorial for Windows
lt-10-08.p
.
.
.
FOR EACH Customer FIELDS (Balance Credit-Limit Contact Cust-Num)
WHERE Balance >= (Credit-Limit * .85)
WITH STREAM-IO:
DISPLAY Name FORMAT "x(20)" Contact FORMAT "x(15)"
Balance Credit-Limit WITH NO-BOX.
10–24
Creating Reports
1. The WHERE clause of the third FOR EACH relates the Order-Line table back to the Order
table.
2. For each Order-Line, there is a single Item record that contains information about the
ordered item. A simple FIND statement retrieves this information.
3. Here, the report totals the result of an expression. Notice the absence of the BY break
group syntax.
4. The FORMAT option here specifies a fairly complex format string. The result displays a
leading dollar sign ($), suppresses the leading zeroes (z), and displays the credit symbol
(CR) when the result is a negative value.
10–25
Progress Language Tutorial for Windows
SYNTAX
SYNTAX
10–26
Creating Reports
Component Description
STREAM Specifies a named output stream. Omit this syntax when using the
default stream.
opsys-file Specifies a legal file name enclosed in quotes for a text file.
PAGED Directs Progress to break the output into pages. Progress sends a
page break control character after every 56 lines. Without this
option, Progress sends output in a continuos stream. This option
is most often used with printed reports, especially where you
want to use page headers and footers (covered later).
10–27
Progress Language Tutorial for Windows
lt-10-09.p
You can see from the highlighted points that the OUTPUT TO and OUTPUT CLOSE
statements control the stream. Also note that the STREAM-IO option must appear in each
output frame phrase.
10–28
Creating Reports
Try running lt-10-09.p and then opening tut-temp.txt in the procedure editor; as you can
see from the figure below, the content of the file matches what the interface showed in the last
exercise:
10–29
Progress Language Tutorial for Windows
SYNTAX
To output to the stream, you reference it in your output statement with the keyword STREAM,
as shown in the following example:
1. When the procedure starts, it has a default unnamed stream that outputs to the screen by
default. This statement establishes a second stream that also outputs to the screen by
default. Both streams are now available for the life of the procedure.
2. This OUTPUT TO statement redirects the unnamed stream to the the default printer.
6. This OUTPUT CLOSE statement redirects the default stream back to the screen.
7. This OUTPUT CLOSE statement redirects the named stream back to the screen.
10–30
Creating Reports
10–31
Progress Language Tutorial for Windows
Here is an example:
The example above compiles a phone list of customer and contact names. If no contact is on
file, “No Contact” appears in the report.
HEADER
header-item1 /* Can be field, variable, constant, EXPRESSION,
header-item2 image, or rectangle. */
header-item3
BACKGROUND
background-item1 /* Can be field, variable, constant, EXPRESSION,
background-item2 image, or rectangle. */
background-item3
WITH SIDE-LABELS.
10–32
Creating Reports
Frame backgrounds are typically used for placing a logo (image) or other graphic device in the
background of a display frame. However, you cannot print graphics from the Progress 4GL. For
more information, see the Progress Language Reference and the Progress Report Builder
User’s Guide. The rest of this section concentrates on the HEADER part of the frame.
The HEADER has a couple of special properties that allow you to implement running page
heads and footers:
• Progress suppresses field and variable labels in a header frame. If you want labels, you
supply text strings in the frame definition.
If a HEADER frame contains an expression, field, or variable, the frame definition must take
place in the context where Progress can provide new values. In other words, for an iterating
report procedure, move the DEFINE FRAME statement from the top of your procedure into the
FOR EACH block. Think of a HEADER frame as an executable statement. Just like a
DISPLAY statement inside a FOR EACH block, the HEADER section of the DEFINE FRAME
statement executes on every iteration of the FOR EACH block.
Also, note that a frame does not have to have a body—it can consist of a header only. You can
modularize your report design with three frames: one each for page header, body, and page
footer. This approach lets you adopt standard headers and footers.
Assume that All Around Sports wants a standard page header on every page of its reports. This
is the information they want to include in the page header:
This code defines the first part of a procedure that implements the three-frame design:
10–33
Progress Language Tutorial for Windows
This part of the procedure contains the following language elements and points of interest:
1. The PAGE-SIZE option of the OUTPUT statement sets the default size for a report page.
2. The HEADER option tells Progress to place the specified items in the header section at the
top of the frame.
3. The TODAY function returns the current system date, and constitutes an expression.
4. The Sales-rep initials come from the database and represent another part of the HEADER
that Progress must evaluate.
6. The PAGE-TOP FRAME f-hdr further defines what kind of HEADER the frame is.
PAGE-TOP specifies where to place the frame and makes the frame a running page head.
Once again, the report needs a DEFINE FRAME statement with the HEADER option as this
code shows:
The PAGE-BOTTOM option tells Progress to display the frame at the bottom of each page.
PAGE-TOP and PAGE-BOTTOM frames are activated based on DISPLAY or VIEW
statements. They are deactivated when the block to which the frames are scoped iterates or ends,
which is why they have to be viewed in every iteration.
10–34
Creating Reports
Notice the header info at the top of each page. As you scroll through, you can see footers
as well.
3 ♦ Choose OK, then Exit, and then press SPACEBAR to return to the Procedure Editor.
10–35
Progress Language Tutorial for Windows
The following code fragment shows the report generating code for this procedure:
lt-10-10.p
.
.
.
/*1*/ DEFINE FRAME f-body
Name NO-LABEL
Balance AT 40 FORMAT "$zzz,zz9.99 CR" SKIP
Contact
Credit-Limit AT 40 FORMAT "$zzz,zz9.99 CR" SKIP
Address NO-LABEL SKIP
Holder NO-LABEL SKIP
Phone SKIP(2)
WITH SIDE-LABELS STREAM-IO.
/*2*/ OUTPUT TO "tut-temp.txt" PAGE-SIZE 25.
/*3*/ FOR EACH Customer FIELDS (balance Sales-Rep name
Contact Credit-Limit Address City State Postal-Code Phone)
WHERE Balance >= 1400 BREAK BY Sales-Rep:
/*4*/ DEFINE FRAME f-hdr
HEADER
"Date:" TODAY "Customer Report" AT 25
sales-rep AT 55
"Page" AT 65
PAGE-NUMBER FORMAT ">>9" SKIP(1)
/*5*/ WITH PAGE-TOP FRAME f-hdr STREAM-IO.
/*6*/ DEFINE FRAME f-ftr
HEADER
"Customer Report"
"continued next page"
/*7*/ WITH FRAME f-ftr PAGE-BOTTOM CENTERED STREAM-IO.
/*8*/ VIEW FRAME f-hdr.
VIEW FRAME f-ftr.
DISPLAY Name Balance Contact Credit-Limit Address
/*9*/ (City + ", " + St + ", " + Postal-Code) @ Holder Phone
WITH FRAME f-body.
/*10*/ IF LAST-OF(Sales-Rep) THEN DO:
HIDE FRAME f-ftr.
PAGE. END. END.
OUTPUT CLOSE.
.
.
.
10–36
Creating Reports
1. The body frame, which has no HEADER section, appears in its normal position, at the top
of the file with other definitions.
3. The use of the control break changes the report output from one report into a series of
smaller reports-one for each sales rep.
8. The VIEW statements force Progress to evaluate the two HEADER frames on each
iteration of the block.
9. Here, the report creates an address string and uses the @ option to place the result at the
Holder variable.
10. The LAST-OF function is for checking for the end of a break group, allowing you to
perform special tasks. In this case, the procedure suppresses the page footer because this
break group report is complete. It also uses the PAGE statement to start a new page for the
next break group report.
10–37
Progress Language Tutorial for Windows
SYNTAX
PUT [ ] [ UNFORMATTED ]
STREAM stream
[ expression [ FORMAT string ]
[ AT expression | TO expression ]
| SKIP [ ( expression ) ]
| SPACE [ ( expression ) ]
] ...
One common task that the PUT statement can help with is mailing labels. Since mailing labels
must conform to a compact physical layout and be uniform, using PUT is a good idea. Suppose
that the All Around Sports accounting department wants to send notices to customers with large
balances. They need a procedure that creates mailing labels for the notices.
10–38
Creating Reports
Exercise 2 ♦ Choose Report. The report dialog box appears as shown below:
The editor shows the mailing list as it appears in a text file. Note that the output is not
perfect:
• For simple addresses, there is a blank line between the street address line and the city,
state, postal-code line. Some addresses need this blank line for extra information.
• There is too much space between the state and postal code.
3 ♦ Choose OK, then Exit, and then press SPACEBAR to return to the Procedure Editor.
10–39
Progress Language Tutorial for Windows
lt-10-11.p
1. The OUTPUT TO statement directs the output from this procedure to a text file named
tut-temp.txt.
2. You can use the PUT statement in addition to the DISPLAY statement when sending data
to a file or to a printer (any destination other than the screen).
10–40
Creating Reports
• Remove the blank line from simple addresses that do not use the extra space
If you run lt-10-12.p, you can see the modified version of this procedure. Here is the code for
that version:
lt-10-12.p
10–41
Progress Language Tutorial for Windows
The following notes help explain the techniques used in the procedure:
1. The first PUT statement outputs and formats the part of the mailing label that is common
to all labels.
2. The first IF statement determines whether the second address line has data. If it does, it
outputs the data.
3. When you create a character expression, like the one in this PUT statement, Progress
removes trailing blanks from the fields. So this output tightens up the extra white space
that showed up in the first mailing list example.
4. Finally, the second IF statement determines whether there is second address line data. If
not, the PUT statement sends a blank line at the end of the address. This statement keeps
the label data together and keeps the individual labels correctly spaced from each other.
10–42
Creating Reports
SYNTAX
The control sequences you send to the printer have no effect on the current line, page counters,
and positions maintained within Progress. Assume you want to print a report on your Brand X
printer, using compressed-print mode.
10–43
Progress Language Tutorial for Windows
lt-10-13.p
NOTE: This procedure works only if you have a printer connected to your system. Not all
printers support compressed printing.
10–44
Creating Reports
1. The start-compress variable contains the four-character sequence that puts the printer into
compressed-print mode. These four characters are octal 033 (decimal 27) followed by left
bracket ([), 3, and w.
2. The variable stop-compress takes the printer out of compressed print mode.
3. When the user selects btn-normal, Progress runs the report in normal mode.
4. When the user selects btn-compressed, Progress runs the report in compressed mode.
10–45
Progress Language Tutorial for Windows
10.9 Summary
This chapter showed how to write Progress procedures that produce both simple and
sophisticated reports.
Redirecting Output
The STREAM-IO option allows you to redirect the output of a report-generating procedure to
a printer or text file. This option removes the graphical components of your data. You can also
redirect output to multiple destinations, and you can define multiple streams.
• Use the PUT statement instead of DISPLAY. PUT suspends default frame-based
formatting.
Customizing Reports
You can customize your reports by:
10–46
11
Building Menus
Menus add flexibility to an interface. A menu provides choices and options for end users that
give them more control over how they use an application. Through menus, users can access the
different functions of an application in the order that best suits them.
In this chapter, you learn about building and customizing menus. Specifically, you learn about:
• Menu basics
• Menu attributes
• Design conventions
Progress Language Tutorial for Windows
• Menu widget
The widgets that make up the complete menu bar are related to each other. For example,
submenus on the menu bar are children of the parent menu bar. Each of the menu bar
submenus are siblings to each other. Similarly, menu items are children of a parent submenu,
and so on. When you code a complete menu bar, you build it from the bottom up. The
lower-level widgets must exist before you can relate them to the higher-level widgets.
The menu widget itself does not have a parent—a menu is always owned by one widget. In the
case of the menu bar, the window widget owns it. Each Progress window can own one menu bar.
11–2
Building Menus
Figure 11–1 shows a menu bar with two menu titles, File and Edit. When you choose Edit, a
pull-down menu with three menu items appears below Edit. When you choose the menu item
Add, a pull-down menu with four menu items appears to the side of Add. The arrow to the right
of Add indicates that there is a nested submenu.
Menu titles
Menu bar
Submenu with
menu items
Nested
submenu
The following sections explain how to define submenus and menu items, how to add them to a
menu bar, and how to assign the menu bar to a window.
11–3
Progress Language Tutorial for Windows
SYNTAX
The LIKE menu option is useful when you want to duplicate an already existing menu. The
menu-element-descriptor allows you to customize the submenu. This is the syntax for the
menu-element-descriptor phrase.
SYNTAX
{ SUB-MENU submenu-name
[ DISABLED ][ LABEL label ]
| RULE
| SKIP
| menu-item-phrase
}
Component Description
SUB-MENU Names a submenu that displays when the user chooses this menu item.
The specified submenu must already be defined.
DISABLED Disables the menu item initially. When you use this option, the user
can’t choose the menu item.
LABEL Defines the text descriptor that the user sees on the menu. If you omit
LABEL, Progress displays the submenu name by default.
RULE Inserts a rule (line) at this point on the menu. Use rules to visually
group related commands.
11–4
Building Menus
Component Description
menu-item-phrase Names a menu-item widget and specifies details about the item. See
the following table for more information.
The menu-item-phrase lets you customize both how the menu item displays and how the user
can access it. This is the syntax for the menu-item-phrase.
SYNTAX
MENU-ITEM item-name
[ ACCELERATOR keylabel ]
[ TOGGLE-BOX ]
[ DISABLED ]
[ LABEL label ]
Component Description
MENU-ITEM Specifies a unique name for the menu item. This name doesn’t have
to be previously defined.
ACCELERATOR Specifies the keyboard accelerator for this menu item. A keyboard
accelerator is a key that chooses a menu item even if the menu item is
not displayed. This option is available only in graphical windowing
environments.
TOGGLE-BOX Displays the menu item with a toggle box that the user can toggle on
or off.
11–5
Progress Language Tutorial for Windows
Component Description
DISABLED Disables the menu item. This means that the user cannot choose this
item.
LABEL Specifies the text descriptor that the user sees in the submenu. If you
omit LABEL, Progress displays the item name by default.
You can include an ampersand (&) within the label to indicate that the
following letter acts as a mnemonic (shortcut key) for the menu item.
For example, "E&xit" specifies “x” as the mnemonic.
Note that in this code fragment, which is an example of a complete submenu definition, only the
final MENU-ITEM phrase has a period:
The next step in building a menu is to define a menu bar and add submenus and items to it.
SYNTAX
DEFINE
[ [ NEW ] SHARED ] MENU menu-name
[ MENUBAR ]
{ LIKE menu-name
| menu-element-descriptor ...
}
11–6
Building Menus
Component Description
NEW SHARED Defines a menu that you can share among procedures.
First, the DEFINE MENU statement creates the menu bar and names it mbar. Then it assigns
each of the previously defined submenus to it. The LABEL option once again lets you provide
titles for the menu items. The order in which you list the submenus is important—Progress
places the menu titles of the submenus on the menu bar starting with the first listed submenu.
11–7
Progress Language Tutorial for Windows
In graphical systems, you can create multiple windows. So, to assign a menubar to a window
other than the default window, use the widget handle variable you use in the CREATE
WINDOW statement, as shown in the following example:
Another typical function found on a menu is the Exit command. Throughout the tutorial, you’ve
used a button labeled “Exit” and used the CHOOSE event of the Exit button as the condition
that satisfies the WAIT-FOR statement. When the user chooses Exit, the flow of control goes
past the WAIT-FOR. If the WAIT-FOR is the last statement in the procedure, the procedure
ends.
11–8
Building Menus
You can easily replace this functionality with an Exit command on the menu bar. By
convention, the Exit command is always the last menu item on the first submenu of a menu bar.
If you add this menu item to your menu bar, then you could use the following WAIT-FOR
statement to block the application:
In reality, closing down an application often requires some clean up. While still using the
CHOOSE event of the Exit command as your WAIT-FOR condition, you can write a trigger for
the same event to do your clean-up. Then, as a last step, you could close the window and end
the application, as shown in the following example:
CLOSE WINDOW is a Progress event function that executes for any event that equates to
dismissing a window.
For a complete discussion of triggers and trigger programming techniques, see the Progress
Programming Handbook.
Referencing Menus
Each menu and submenu must have a unique name. To reference the menu or submenu, precede
the reference with the keyword MENU. To reference a menu item, precede the reference with
the keyword MENU-ITEM. Menu items do not have to have unique names. In situations where
ambiguity arises, you must extend the menu item reference to include the IN MENU option.
11–9
Progress Language Tutorial for Windows
2 ♦ Choose Tables from the menu bar and browse through the submenu and the nested
submenu.
3 ♦ Choose the Reports and Help submenus and browse through them.
4 ♦ Choose Reports→ Mailing Labels. The editor in the window displays the list of customer
mailing labels.
11–10
Building Menus
lt-11-mn.i
11–11
Progress Language Tutorial for Windows
1. The DEFINE SUB-MENU statement defines one pull-down menu and the menu items of
that pull-down menu. The ampersand (&) in the label, establishes the mnemonic for the
menu item (covered later).
2. This submenu appears as a menu item in the next DEFINE SUB-MENU statement, so its
definition must come first.
3. The Exit menu item is always the last menu item of the first submenu on the menu bar.
4. Use RULE to provide a graphic divider between groups of menu items. Use SKIP to add
space between menu items.
5. The DISABLED option disables this menu item on startup (covered later).
6. The TOGGLE-BOX option makes the menu item a toggle (covered later).
7. The DEFINE MENU statement defines a Progress menu. The MENUBAR phrase makes
the menu a menu bar and associates submenus with it.
8. This critical step makes the window the owner of the menu bar. In this case, the owner is
the default window.
11–12
Building Menus
Next, look at the following code, which uses the previous menu structure to implement the
mailing list report you saw in the last section:
lt-11-01.p
11–13
Progress Language Tutorial for Windows
2. Choosing the Exit menu item ends the application by closing the window.
3. Like most menu items, choosing this item executes a RUN statement to an internal or
external procedure. Here, the internal procedure runs a report.
4. The Exit command of the menu bar satisfies the WAIT-FOR condition by closing the
application window.
• Toggle boxes
• Mnemonics
• Accelerators
SYNTAX
11–14
Building Menus
SYNTAX
11.3.3 Mnemonics
A mnemonic provides a way to access menu items from the keyboard. The user can use
mnemonics to navigate through a menu by first activating the menu bar, then typing the
mnemonic character. Progress indicates the mnemonic character by underlining it in the menu.
For example, suppose the menu bar contained these elements: File, Edit, and Reports. Once the
menu bar is active, the mnemonic to access the File menu is f, the Edit menu is e, and the
Reports menu is r. By default, Progress assigns the first character in the item label as the
mnemonic. However, you can also define it yourself by inserting an ampersand (&) before the
letter in the label.
This code fragment defines the mnemonic for the Exit menu item:
11–15
Progress Language Tutorial for Windows
11.3.4 Accelerators
An accelerator is a key or key combination that executes an item from a pull-down menu
without the user having to pull down the menu. You can define an accelerator for a menu item
with the ACCELERATOR option in the menu-item description. This is the syntax for the
ACCELERATOR option.
SYNTAX
ACCELERATOR keylabel
In this syntax, the value keylabel must be a character-string constant that evaluates to a valid
Progress key label. You can modify the keylabel by specifying one or more of these
keys-SHIFT, CONTROL, ALT. For example, you can specify "ALT-F8", "PAGE-UP", etc.
Progress automatically displays the specified accelerator key label next to the menu item label,
so the user knows what key is the accelerator. The user can then choose a menu item by pressing
the specified keys.
For more information on key labels, terminals, and how they are specified in the
PROTERMCAP file, see the Progress Client Deployment Guide.
For more information on keyboard events and keyboard event precedence, see the chapter on
handling user input in the Progress Programming Handbook.
11–16
Building Menus
1 ♦ Open lt-11-02.p and run it. The display shown below appears:
Exercise
2 ♦ Display the Reports pull-down menu. The third and fourth items are disabled, so you can’t
choose them.
5 ♦ Choose Mailing Labels again. An alert box appears informing you that the report printed.
Choose OK to dismiss the alert box.
6 ♦ Browse through the various submenus. Notice that a letter in each submenu or menu item
is underlined. The underlined letter is a mnemonic.
7 ♦ Choose Tables→ Exit, then press SPACEBAR to return to the Procedure Editor.
11–17
Progress Language Tutorial for Windows
lt-11-02.p
11–18
Building Menus
1. The CHECKED attribute applies only to toggle boxes and toggle box menu items. You
can check it at any time to determine the on screen state of the menu item. If you wanted
to write a trigger for the toggle box menu item, you would normally use the
VALUE-CHANGED event function.
2. Here, the CHECKED attribute determines whether to read the report output file into the
editor or to let the user know that the output went to the default printer.
FIRST-CHILD WIDGET-HANDLE – √ –
LAST-CHILD WIDGET-HANDLE – √ –
OWNER WIDGET-HANDLE – √ –
TITLE CHARACTER – √ –
FIRST-CHILD WIDGET-HANDLE – √ –
LAST-CHILD WIDGET-HANDLE – √ –
PARENT WIDGET-HANDLE – √ √
11–19
Progress Language Tutorial for Windows
CHECKED LOGICAL ? √ √
LABEL CHARACTER – √ √
SUBTYPE CHARACTER – √ √
• Group menu items in submenus by task. Order the tasks by frequency of use, as well as
the order in which they are used. Place the most frequently used menu items where users
can easily access them—in general on the left and close to the top.
• Keep any destructive menu item (like delete) away from frequently used menu items.
• When possible, provide alternate methods for accessing menus, like mnemonics and
accelerator keys.
• Use an ellipsis (...) to indicate menu items that require further user input.
• Each menu bar should contain at minimum these three items: File, Edit, and Help.
11–20
Building Menus
• Place the Exit option as the last menu item on the first menu.
• Limit submenus to three levels or less, because multiple levels of submenus clutter the
screen and make the menu difficult to use.
Practice Problems
To practice defining menu bars, submenus, and menu items, design a basic menu system for an application you
plan to develop.
Now that you have a basic menu worked out, experiment by adding some advanced features, such as disabled
menu items, mnemonics, and toggle boxes.
11.6 Summary
Menus create an interface that allows your application to take full advantage of the event-driven
programming model. The user controls which tasks are accomplished and the order in which
they’re accomplished.
A menu consists of three parts:
• A menu bar at the top of the window is the highest level of the menu.
• Submenus open below the menu bar and offer the user additional submenus or items to
choose from.
11–21
Progress Language Tutorial for Windows
When you build a menu, you start with the lowest-level components. Building a menu involves
three steps:
Once you’ve assembled the menu, you can assign functionality to it by adding triggers that
execute when the user chooses the menu items.
• Disabled menu items let the user know which options are not available to them at certain
points in the application.
• Toggle boxes can keep track of the user’s decision regarding a certain option.
• Mnemonics provide keys that the user can use as shortcuts to choosing a menu item.
Accelerator keys allow users to select items from a menu that is not displayed.
11–22
12
Managing Your Application
When you begin your own application development cycle, you’ll reach a point where you have
all your functionality and interface code stored in procedure files. Together, these procedure
files make up the complete application. Your final task will be to make sure it all works
smoothly together.
This chapter discusses the issues that arise when putting together a large-scale application. It
summarizes many techniques you already know about in the context of application
management. The chapter also covers several new techniques and language elements that are
important in managing your application.
Specifically, the chapter covers:
• Sharing resources
• Managing interfaces
• Triggers
• Internal procedures that represent functions—pieces of common code that more than one
external procedure relies on.
External External
Procedures Procedures
Main Procedure (.p)
.p .p
.p .p .p .p .p .p
12–2
Managing Your Application
Because the event-driven model promotes giving the user access to most functionality at the top
level of an application’s interface, as opposed to a tree structure of screen menus, the main
procedure that defines the top level of the application can get very large.
The tendency to grow the main procedure and keep the external procedures atomic modules can
lead to problems. While you achieve modularity and ease of maintenance in the external
procedures, the main procedure can become difficult to read and may tax the execution limits
of your system.
One way to more easily maintain the main procedure might be to use include files to group
related code. This may make the code easier to understand, but does not reduce the resource
burden of having an overly large module of executable code.
12–3
Progress Language Tutorial for Windows
The Progress SESSION handle contains two attributes named FIRST-PROCEDURE and
LAST-PROCEDURE. These two attributes allow you to access the beginning and end of the
chain of persistent procedures. Together with the NEXT-SIBLING and PREV-SIBLING
attributes of the procedure HANDLE variable, you can move through the chain of persistent
contexts.
The DELETE PROCEDURE statement lets you delete persistent contexts.
Finally, you should know that you can run each procedure persistently many times. Each
separate call with the RUN statement creates a separate context. For situations where you
choose to use this technique, you’ll need to create a management system so that you can
differentiate between the different instances of the same procedure.
12–4
Managing Your Application
The next step is to run an external procedure with the PERSISTENT option of the RUN
statement. The diagram below shows the relevant RUN statement syntax.
SYNTAX
RUN extern-procedure
[ PERSISTENT [ SET handle ]] [ runtime-parameters ]
Progress sets the HANDLE variable you supply to the handle for the procedure context.
12–5
Progress Language Tutorial for Windows
When you are through with a procedure, you need to delete it. This is the syntax for the
DELETE PROCEDURE statement.
SYNTAX
There are some other 4GL language elements that help you manage persistent procedures. Table
12–1 describes them.
Element Description
12–6
Managing Your Application
Element Description
12–7
Progress Language Tutorial for Windows
1 ♦ Open lt-12-01.p and run it. The display shown below appears:
Exercise
2 ♦ Choose Run Procedure 2. An alert box appears informing you that the context for
procedure 2 is available. This alert box represents the body of an internal procedure stored
in an external procedure file. The internal procedure was accessed and run from the main
procedure after the execution of the external procedure was already complete.
3 ♦ Choose Check Contexts. The filenames of all persistent procedures appear in the display.
4 ♦ Choose Delete Context 2 and then choose Check Contexts again. The deleted context
disappears from the list.
5 ♦ Choose Exit, and then press SPACEBAR to return to the Procedure Editor.
12–8
Managing Your Application
The code for the main procedure is on the next page. The two external procedures are simply
MESSAGE statements inside internal procedures:
lt-12-01.p
12–9
Progress Language Tutorial for Windows
2. This IF statement prevents the user from establishing many separate contexts for each
procedure.
3. The PERSISTENT option asks Progress to save the procedure, and the SET option
provides the handle to the procedure.
5. This RUN statement uses the IN handle syntax to access and run an internal procedure in
the persistent procedure context.
7. This trigger runs through the current chain of persistent procedures and records the
filenames of each in a string.
8. The exit trigger makes sure the procedures are destroyed before exiting the procedure.
Because you stored the procedure HANDLE when you ran the procedure, you have
programmatic control of that procedure. In this example, you use that HANDLE to
explicitly delete any surviving procedure contexts before exiting the main procedure.
• Single-frame interfaces
• Multi-frame interfaces
• Dialog boxes
• Alert boxes
• Multi-window interfaces
12–10
Managing Your Application
• Defining all the frames as independent siblings that are child widgets of the window.
• Defining frame families (see Chapter 3, “Programming the Progress Way”), where at least
one frame is a parent that contains all the other frames as its child widgets.
In general, frame families solve a number of problems related to navigation and control in
multiple frame interfaces. Among these are tabbing and conditional display. However, some
code management is equally necessary for frame families and independent frames.
12–11
Progress Language Tutorial for Windows
One way to avoid this problem is to write a trigger that simulates the response the user expects.
When the user presses TAB in the last widget of a frame, you can suppress the default behavior
and apply the NEXT-FRAME event function to the frame. This moves input focus to the first
widget of the next frame. Here is an example:
However, a simpler method is to include all the frames in a single frame family. With this
approach, all tabbing behavior is built in. The user can tab among all the frames contained by
the parent frame. Focus automatically moves to the first or last field-level widget in the next or
previous frame, respectively.
Frame Scoping
Just like records, frames have a life span, and that life span is referred to as the frame scope. The
general rules for frame scope are:
• Frame scope ends when the block that contained the first reference to the frame ends.
• Frames are available to any nested blocks within the block that contained the first
reference.
If you violate these rules, Progress will notify you at compile time. In general, you won’t need
to worry too much about frame scope because the code techniques used with the event-driven
programming model tend to scope all frames to a procedure block. Because the frames are
scoped to the procedure block, all references to the frame within the procedure block are legal.
12–12
Managing Your Application
One of the more common scoping problems involves trying to reference a frame used by a
control block from the main procedure. Here’s an example:
This is invalid code because of the attempt to reference Frame2, which is scoped to the FOR
EACH block, outside of that block. If you need to reference the frame in both blocks, you have
to make sure that the first reference is in the block that contains the FOR EACH block. The
DEFINE FRAME statement is not considered a reference.
For more information on frame scoping, see the Progress Programming Handbook.
SYNTAX
widget-name:attribute-name
SYNTAX
FRAME frame-name:attribute-name
12–13
Progress Language Tutorial for Windows
Table 12–2 describes some of the basic frame attributes that you may want to reference.
Attribute Description
COLUMN For frames, the COLUMN attribute holds the column position of
the frame within the window.
ROW For frames, the ROW attribute holds the row position of the
frame within the window.
Hiding Frames
In Chapter 3, “Programming the Progress Way,” you learned about using the VIEW and HIDE
statements. These two statements operate on the VISIBLE attribute, which all widgets have.
The VISIBLE attribute is TRUE if the widget is currently visible in the display, and FALSE if
it is not. It is sometimes useful to access the VISIBLE attribute directly to make widgets appear
and disappear. VISIBLE does not give you complete control over a widget visibility, however,
because Progress has default behaviors that can make a widget visible, even if you made it
invisible. For example, displaying a frame makes all the widgets in that frame visible, including
any child frames.
Progress provides the HIDDEN attribute to allow you to suppress implicit viewing of a widget.
So to make a widget completely invisible, set VISIBLE to FALSE and HIDDEN to TRUE.
12–14
Managing Your Application
The HIDDEN attribute can be used to give your application a significant performance boost.
When you start an application, or switch to a new interface within an application, the computer
periodically redraws the screen. If the computer redraws the screen several times while you are
still setting up the interface, you slow down the appearance of that interface to the user.
Use the HIDDEN attribute on a frame (or window) to make the frame immune to Progress
implicit viewing behaviors. If the frame is invisible, so are all the widgets in the frame. With
HIDDEN set to TRUE, you can populate a frame with widgets, display data in the frame, and
enable the widgets without the frame becoming visible. Then when the frame is ready, use the
VIEW FRAME statement to make the interface visible.
Here is an example of the HIDDEN attribute:
In the first case, if the frames are stored separately as include files, then those frames need to be
scoped to the main procedure so they are available. As mentioned earlier, in large applications
this can make the main procedure overly large.
For runnable code modules, you can use external procedures that use the main interface (as
opposed to a dialog box).
12–15
Progress Language Tutorial for Windows
However, if this frame contains child frames that own some of the input widgets you want
enabled, these input widgets do not become enabled by this single statement. You must enable
input for each frame separately, even though they are in a single frame family:
While this might seem like unnecessarily redundant code, it does afford a measure of control
where you choose to group input fields within child frames by common function. You might
then enable and disable each child frame (group of fields) under the parent frame according to
input received by fields owned by the parent frame itself.
12–16
Managing Your Application
This example illustrates the concept behind a dialog box: a dialog box is an event-driven tool
for implementing modes. Normally, event-driven programming strives to let users work with an
application in any way that suits them. They can begin one task, start another, go back to the
first, start a third—whatever makes sense to them. Event-driven programming attempts to be
modeless, which means that a user can work with several parts (modes) of an application
simultaneously.
In many instances, however, it is clearly desirable, or even necessary, to have a user start and
complete a particular task before starting another. That’s where the dialog box comes in. When
you use a dialog box, you are defining a mode—you are being modal. To go back to the
UPDATE example, that technique for working with data had two clearly defined modes:
viewing data and changing data. By using the dialog box, you enforced the distinction between
the two modes. In event-driven programming, it’s also possible to use the same interface to view
data and allow changes to the data. This technique is a modeless one.
Figure 12–2 illustrates a modeless technique.
12–17
Progress Language Tutorial for Windows
• A user who chooses the OK button is saying “dismiss the dialog box and save any
changes made to data in the dialog box.”
• A user who chooses the Cancel button is saying “dismiss the dialog box and discard any
changes made to the data.”
12–18
Managing Your Application
Fortunately, the Progress programming model contains these two concepts, which apply to all
Progress interfaces, not just dialog boxes. The GO event function maps to the idea of “dismiss
and save,” while the ENDKEY event function maps to the idea of “dismiss and discard.” Using
the AUTO-GO and AUTO-ENDKEY options on the DEFINE BUTTON statement for OK and
Cancel maps the GO and END-ERROR event functions to the buttons.
SYNTAX
12–19
Progress Language Tutorial for Windows
Component Description
alert-type Different environments define different types of alert boxes for use in
certain circumstances. This ensures that all applications running in the
environment use the same graphical cues for similar situations. This kind
of uniformity helps the user recognize the seriousness of the message. The
three most common types are:
button-set While the alert-type syntax lets you specify the type of message to send,
the BUTTON-SET syntax lets you choose the method for user response to
the alert box. The most common button sets are:
• YES-NO — Use this button set with the QUESTION alert box type.
The alert box will return the logical value YES or NO depending on
the choice of the user to a LOGICAL field specified in the
MESSAGE statement. See below for a description of this technique.
TITLE Like a frame or dialog box, an alert box can have a title. Good style
dictates that you always include a descriptive title.
12–20
Managing Your Application
.
.
.
/*1*/ DEFINE VARIABLE Answer AS LOGICAL.
.
.
.
ON CHOOSE OF btn-Delete
DO:
/*2*/ MESSAGE "Do you really want to delete" Customer.Name "?"
VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO
/*3*/ UPDATE Answer.
/*4*/ IF Answer THEN DO:
DELETE Customer.
GET NEXT Cust-Query.
IF NOT AVAILABLE(Customer) THEN GET FIRST Cust-Query.
DISPLAY Customer.Cust-Num Customer.Name WITH FRAME Frame1.
END. /* IF Answer */
END. /* ON CHOOSE OF btn-Delete */
.
.
.
12–21
Progress Language Tutorial for Windows
1. You need to define a variable before you use the alert box to store the user’s response.
2. The special VIEW-AS syntax on a MESSAGE statement re-routes a message from the
status area to an alert box.
3. This UPDATE is an option of the MESSAGE statement (note that there is no period on
the line before). Use this option to specify the variable that will hold the user’s response.
Window Attributes
The design of multi-window applications is outside the scope of this tutorial, but the tutorial
does show you how to create a second window. When working with windows, three attributes
are important to know about:
• MENU-BAR — Use this WIDGET-HANDLE attribute to supply the widget handle of the
menu bar that belongs to the window. Chapter 11, “Building Menus,” discusses menus and
the menu-bar widget.
• STATUS-AREA — Use this LOGICAL attribute to specify whether you want a status
area in your window.
12–22
Managing Your Application
SYNTAX
For the most part, you need to assign attributes to window widgets as you create them, as in the
following example:
Referencing Windows
Progress defines a window widget as the workspace of your application. Each time you start a
Progress session, it automatically creates a default window. In graphical environments, you start
with the default window, but you can create other, overlapping windows dynamically within
your application.
When you are working with the default window, you reference it by using the
DEFAULT-WINDOW system handle. This system handle holds the widget handle of the
default window.
When you are working with more than one window, the CURRENT-WINDOW system handle
holds the widget handle of the window that has input focus. For single-window applications,
DEFAULT-WINDOW and CURRENT-WINDOW are equal, but referring to
DEFAULT-WINDOW is a little clearer.
When you have two or more windows, only the current window has input focus.
12–23
Progress Language Tutorial for Windows
Finally, to clarify ambiguous references to widgets in different windows, use the IN WINDOW
syntax. For example, an application may have several Delete buttons. The following code
fragment uses the IN WINDOW syntax to specify the Delete button in the window, Mywindow:
Window Events
When you are working with windows, there are four event functions that you’ll frequently use
to add functionality to the window.
12–24
Managing Your Application
Each window in a window family functions much the same as an individual window. That is,
you can individually move, resize, and interact with a member of a window family like an
individual window. However, window families share a number of additional properties that
make them convenient for both applications and users to manage. For example, window
families make it easier for you to coordinate:
• Viewing and hiding — When you view any member of a window family, all family
members are viewed unless one or more of them have their HIDDEN attributes set to
TRUE. Progress also hides all descendant windows that are minimized when you hide a
parent.
• Minimizing and restoring — You can minimize and restore all members of a window
family individually. When you minimize (iconify) a window, Progress hides all of its
descendants. When you restore a parent window, Progress redisplays any hidden
descendants.
The relationships created by window families can be very useful because you can use them to
manage your interface more effectively, and with less code. If you define a window family, you
can control all the windows for an application as a single set, or as individual windows. For
example, you can ensure that Progress closes all windows in an application when the user closes
the root window. You can ensure that when a parent window is minimized, all the descendant
windows of that window are also closed. This is useful in applications that use persistent
procedures.
12–25
Progress Language Tutorial for Windows
To define a window family, set the PARENT attribute of the child window to the widget handle
of the parent window, as shown below. In lt-12-04.p, window child1 is a child window of
window parent1, and window grandchild1 is a child window of window child1. You can use
this example to investigate the minimizing properties of window families:
lt-12-04.p
12–26
Managing Your Application
For a discussion of windows and window programming techniques, see the Progress
Programming Handbook.
12–27
Progress Language Tutorial for Windows
It is also true that the implied execution blocking that comes with the UPDATE statement and
related statements should not be mixed with a WAIT-FOR in the same interface, for the same
reasons. UPDATE statements with dialog boxes work well together because the disabling of the
main interface by the dialog box allows the UPDATE to function without interference from the
main WAIT-FOR.
In most cases, an application should have only a single active WAIT-FOR. Secondary interfaces
should use another technique to block execution.
• The dialog box has no updatable widgets and therefore has no need for an UPDATE
statement.
• The dialog box disables the main interface, avoiding conflict with the main WAIT-FOR.
• The code took care of explicitly dismissing the dialog box. Without the HIDE statement
immediately following the WAIT-FOR, the code would yield an error message.
12–28
Managing Your Application
12.5 Summary
Event-driven programs strive to make as much functionality available from the top-level of an
application as possible. This leads to a characteristic flat application structure consisting of one
large main procedure and several atomic modules that reside in separate procedure files. Having
a large main procedure may tax the execution limits of your system. To alleviate this problem,
you can use persistent procedures to create loadable and unloadable modules of resources.
SHARED resources, including variables, frames, buffers, queries, and streams, allow you to
create individual resources that can be available to many procedures.
Persistent procedures create resources that do not disappear when the creating procedure ends.
Persistent procedure contexts must be destroyed programmatically when the application no
longer needs them.
Progress supports a variety of interface designs, including:
• Single-frame interfaces
• Multi-frame interfaces
• Dialog boxes
• Multi-window applications
Like other widgets, frames and windows have attributes that you can manipulate to fine tune
your interface.
A successful application that mingles more than one interface needs to manage application
control by using WAIT-FOR statements, implied application blocking, and persistent
procedures in such a way as to give the user freedom to move through the application without
conflict.
12–29
Progress Language Tutorial for Windows
12–30
13
Where to Go from Here
The tutorial introduced and developed several broad programming themes. The themes and
coverage were chosen to give you a solid foundation in the Progress 4GL. With what you’ve
learned, you could certainly begin to develop Progress applications. However, Progress
contains so many features and language options that there’s a lot more to learn. This chapter
provides a conceptual map for learning more about the programming areas that are important to
you. The topics covered are:
• Progress Tools
• Multi-user programming
• Data integrity
• Record reading
• Menus
• Graphical features
Progress Language Tutorial for Windows
AppBuilder
The AppBuilder is a tool for graphical environments that allows you to draw an interface and
the AppBuilder codes the interface for you. Of course, this is only the beginning of what the
AppBuilder can do. The tool takes full advantage of the graphical features of a GUI to make
creating Progress applications easier. The tool includes a section editor where you can write
code, including triggers.
The AppBuilder includes an implementation of encapsulated objects called SmartObjects.
These contain a variety of objects that you can combine to quickly build graphical applications.
When you use SmartObjects to build your application, you create an easily maintainable body
of code based on reusable objects. You can change a SmartObject and affect that change for
every instance of that SmartObject.
If you program in a graphical environment, the AppBuilder could easily become the hub of your
development environment. However, keep in mind that the AppBuilder can also be used to
design character environments, and that SmartObjects can be used in character environments.
For an introduction to the the AppBuilder and to SmartObjects, see the Progress Application
Development Environment — Getting Started manual. For an in-depth treatment of the
AppBuilder, see the Progress AppBuilder Developer’s Guide. For information on porting
Progress applications, especially those containing SmartObjects, between Windows and
character interfaces, see the Progress Portability Guide.
Debugger
When your application grows and consists of many procedure files, debugging may take up
more of your time. The Progress Debugger can reduce that burden. The Debugger is
documented in the Progress Debugger Guide.
Other Tools
Progress has a number of other tools that serve very specific purposes. If you need to use one of
these tools, the Progress documentation set will point you towards it.
13–2
Where to Go from Here
13–3
Progress Language Tutorial for Windows
13–4
Where to Go from Here
You also learned about buffers and how Progress manages them for you. However, Progress
also has the following features:
You can find information on these language statements in the Progress Language Reference.
13.9 Menus
You learned how to define the menu-bar type of menu in the tutorial. Another type of menu that
you might want to use is known as a pop-up menu. A popup menu is associated with a widget
and provides options that affect that widget. For example, you might want to have a pop-up
widget on a frame. See the Progress Programming Handbook section on menus for a complete
description of pop-up menus.
13–5
Progress Language Tutorial for Windows
• Graphical images
• Colors
• Fonts
Once you’ve created a functionally sound application that offers an intuitive interface, you can
begin to add images, colors, and fonts to create a unique and pleasant style.
The image widget allows you to place graphic files into your application. The image widget also
has syntax options that allow some interesting uses.
Most interface components support syntax options that give you some, or total, control over
color. Interface components that include text may also have options for specifying font choices
and font styles.
For pursuing any of these programming issues, your best bet is to look up the specific syntax in
the Progress Language Reference.
However, the Progress Programming Handbook is also a good resource for you to check
concerning graphical images, colors, and fonts.
13–6
Where to Go from Here
• Internationalization (I18N) is the process by which you design and program for a
non-specific linguistic and cultural user base.
A localized application is an application that you have customized for a specific region. The
region need not be another country; it can be a region characterized by a language, such as the
French-speaking part of Switzerland, or a region characterized by different business practices,
such as a province that has a different tax structure.
For more information about either of these types of applications, see the Progress
Internationalization Guide.
13–7
Progress Language Tutorial for Windows
13–8
Glossary
Abbreviated Index
Uses just the first few characters of a field, if the field is a character data field. Indexes not
comprised of character data require an exact match.
Accelerator Keys
Function and special key combinations that you can press to choose a menu option.
Active Database
The database that is currently in use. If you have more than one database, the Data
Dictionary requires you to select an active, working database.
Aggregate Functions
A set of functions that allow you to evaluate groups of values.
Aggregate Phrase
A Progress language element that identifies one or more values to be calculated based on
a change in a break group.
Alert Box
A window that appears on the screen requesting user response. The user must dismiss the
alert box before the application can continue.
Application
A set of programming language instructions that accomplishes a specific task. An
application can be created from Progress procedures.
Argument
A piece of data that a calling procedure gives to a called procedure. Progress evaluates the
passed data at compilation time.
Progress Language Tutorial for Windows
Array
A field or variable with multiple elements. Each element in an array has the same data
type.
Array Extent
The number of elements contained in the array.
Assignment Operator
The equal sign (=).
Attribute
A value associated with a widget or system handle. The value represents an aspect (e.g.
size or color), state (e.g. visibility), or capability (e.g. to allow scrolling).
Block
A series of statements that Progress treats as a single unit. Typically, each block begins
with a block header statement and concludes with an END statement.
Block Header
The statement that begins a block. It is different from other kinds of statements in two
ways: it ends with a colon (:) (all other statements end with a period) and it can have a label
(the label also ends with a colon).
Block Label
Text in a procedure block that identifies the block.
Box
In a frame, the four lines around the outside of the frame that designate its boundary. By
default, frames have boxes; however, an application can turn off the box.
Break Group
A set of records having a common value in a certain database field. Break groups are used
in reports to display file and record relationships.
Browse Widget
A widget that displays the results of a database query. There are two types of browse
widget: updateable and read-only. An updateable browse lets the user view, update, add,
and delete data in records. A read-only browse is used for display only. It shares properties
of a container and field-level widget.
Glossary–2
Glossary
Buffer
A small amount of memory used as a temporary storage area for data during input or
output operations. See also data buffer, record buffer, screen buffer. See also edit
buffer.
Button Widget
A field-level widget that the user can choose to direct an application to execute a trigger
or control the interface.
Character Client
A combination of hardware and software components that support a character-based
interface. The following platforms support Progress running in character mode: UNIX,
Windows NT, and Windows 95. Windows NT and Windows 95 only support the
character mode by enabling a character client to run in DOS only when DOS is running
under one of these 32-bit Windows operating systems.
Character Constant
A value made up of non-numeric or character data, or a combination of numeric and
non-numeric data that remains unchanged during a procedure. Character constants must
be enclosed in quotation marks when used in a procedure.
Character Data Type
A property of a field or variable that determines that the data stored there can be of the
character data type.
Character Field
A field having a character data type.
Child Frame
A frame parented to (contained by) another frame. See also parent frame.
Child Window
A window parented to (owned by) another window. See also parent window.
Child Window Family
A child window and all of its descendant windows.
Column
1.) A component of a record, a field. 2.) A vertically aligned set of character cells in the
character coordinate system.
Glossary–3
Progress Language Tutorial for Windows
Column Label
A label displayed above a column of data (field values). This label is useful for creating
lists of values, like columnar reports. See also side labels.
Combo Box Widget
A field-level widget that presents a scrolling list of character strings. The list is only visible
when the user chooses the button next to the combo box. When the user selects a value,
the combo box closes and displays only the selected value.
Comparison Expression
A combination of constants, variables, operators, and parentheses used to compare values.
Concatenation Operator
The plus sign (+) used to link or join two or more character strings into a single character
string.
Conditional Processing
A means of processing based on one or more logical expressions.
Connected Database
A database that is accessible and can be worked on in the Data Dictionary.
Constant
A value that remains unchanged during the execution of a program. A constant can be of
any data type: character, date, decimal, integer or logical.
Container Widget
A widget that can contain other widgets. For example, a frame is a container widget.
Current Buffer
The contents displayed in the procedure area of the Procedure Editor.
Current Window
1.) The window in which one is working and so indicated by a filled-in window title bar.
2.) The window that contains the current widget.
Current Widget
The widget that has input focus.
Cycling Sequence
A sequence that begins at an initial value and increments in one direction until it reaches
the designated limit.
Glossary–4
Glossary
Database
A collection of data organized in logically related tables or fields that can be accessed or
retrieved.
Database Event
An action performed against a database, such as finding or writing to a record.
Database Object
A component of the database that is defined in the database schema such as a field or a
table.
Database Properties
The schema definitions that define the database, such as the database name, the database
type, and so on.
Database Trigger
A piece of code that an application associates with a component of a database and a
database action (such as writing a record). When the action occurs on the component,
Progress locates this piece of code and executes it on behalf of the application.
Data Dictionary
An interactive tool that enables you to create, modify, and delete Progress database
objects. You can also use it to generate database reports.
Data Type
A property of a field or variable that determines the nature of data that can be stored there
(integers as opposed to characters, for example). Progress supports five data types:
character, integer, decimal, date, and logical.
DATE Data Type
A property of a field or variable that determines that the data stored there can be a date. In
Progress, a date data type may contain a date and time from 1/1/32768 B.C. through
12/31/32767 A.D.
Date Field
A field having a date data type. You can specify dates in this century with either a two-digit
year, such as 8/9/90, or a four-digit year (8/9/1990). Dates in other centuries require a
four-digit year.
Decimal Data Type
A property of a field or variable that determines that the data stored there can be a decimal.
Glossary–5
Progress Language Tutorial for Windows
Decimal Field
A field having a decimal data type. A decimal field can contain decimal numbers up to 50
digits in length. Progress allows up to 10 digits to the right of the decimal point.
Dialog Box Widget
A container widget that either notifies the user of important information or requests more
information. The main interface is disabled until the user is done working with the dialog
box. A dialog box is a frame, but it has some properties of a window. Dialog boxes have
modal properties.
Directory
A file-system object that lists or contains files and, possibly, other directories.
Display Format
The way data appears on screen and in printed reports. Progress automatically supplies a
default display format for each data type, but you can change that default format.
Down Frame
A frame that displays multiple records, one per line, one after another. See also frame.
Edit Buffer
A temporary work area for procedures under construction in the Procedure Editor. The
Procedure Editor allows you to open several buffers simultaneously. If a buffer has no
name assigned, it appears as “Untitled” plus a number that makes it unique (Untitled:1).
Editor Widget
A field-level widget that allows editing of large character variables or database fields. By
default, editor widgets support features such as cut, copy, paste, and word-wrap.
Event Action
Any simple user interaction, like a single keystroke.
Event Function
An abstraction of one or more event actions.
Event-driven Programming
Think of event-driven programming as bottom-up programming, because you define the
smaller components before you define the larger components.
Expression
In a program, a combination of constants, variables, operations, and parentheses used to
perform a desired computation.
Glossary–6
Glossary
External Procedure
A group of Progress 4GL statements that you store as an operating-system file.
Field
1.) The “atomic particle” of a database-that is, the smallest unit of useful information.
2.) A component of a record that holds a data value. Also called a column.
Field-level Widget
Any widget that can be placed in a frame.
Field Label
A label on the screen or printed reports that identifies the field. If you do not supply a label,
Progress uses the field name as the label.
Field Properties
The schema definitions that define the field, such as the field name, the field type, and so
on.
Fill-in Field Widget
A field-level widget that handles text entry and display. The fill-in field is the default
widget for displaying a variable or database field. Also known as a fill-in.
Footer
Text, such as a page number, placed at the bottom of each page of a report.
Format Phrase
A Progress language description of the display characteristics for a field, variable, or
expression.
Frame
A container widget composed of a display area within a window that Progress uses to
display field-level widgets.
Frame Family
A related collection of parent and child frames.
Frame Scope
The range or extent of a frame’s availability within a procedure.
Glossary–7
Progress Language Tutorial for Windows
Function
A prepackaged solution to a task that can be used in an expression-a “shortcut” to handling
tasks. Progress supports two types of functions: pre-defined function that the Progress
4GL supplies, and user-defined function that allows you to create functions based on
specific programming tasks you want to solve.
Function Keys
Special keys to which Progress assigns certain actions. In procedures, you can reassign
these actions to different keys.
Graphical User Interface (GUI)
Features high-resolution graphics and an additional user input device called a mouse.
Handle
An internal identifier for a widget. See also system handle and widget handle.
Header
Text, such as a page number, title, or date, placed at the top of each page of a report.
Icon
A small, rectangular graphic image that represents a window when the user has
“minimized” (or “iconified”) it.
Image
A field-level widget used to display an image from a bitmap file.
Include File
A separate file containing Progress code that you can call from other procedures by
placing the filename in braces within the procedure. Include files have a .i extension.
Index
A directory or table containing 1) the field or fields identifying the records in a file, and 2)
the locations where the records are stored.
Index Properties
The schema definitions that define the index, such as the index name, the fields it
comprises, and so on.
Initial Value
The value to which a field is set when it’s created.
Glossary–8
Glossary
Inner Join
A join where records from the first (left-hand) table (or join) are only returned to the results
list that also return a corresponding record from the second (right-hand) table.
Input Focus
The ability for a widget to receive user-interface events.
Integer Data Type
A property of a field or variable that determines that the data stored there can be an integer.
Integer Field
A field having an integer data type.
Internal Procedure
Code blocks that you write and compile as part of a larger containing procedure.
Iteration
A repetition of a procedure block.
Join
A type of query operation that requests information from two tables or joins at a time. The
output is a results list where each row contains a record from each joined table. A join can
only occur when the two queried tables or joins have a common field.
Join Condition
The criteria used to relate the fields of one table in a join with those of another.
Key Functions
Tool functions that map to a keystroke.
Key Index
A primary, unique index field in a table.
Label
Text that appears with a field or variable when it is displayed.
Left Outer Join
A join that returns all the records of the first (left-hand) table, including the records from
the second (right-hand) table for an inner join and null field values for all records in the
right-hand table that have no corresponding records in the left-hand table.
Glossary–9
Progress Language Tutorial for Windows
Local Variable
A variable that you can use only within the procedure in which you defined it. The data in
the variable is no longer available when you exit the procedure.
Literal
An alphanumeric constant. Literals can be character strings, numerics, dates, or logical
data.
Logical Data Type
Can be one of two values consisting of yes/no, true/false, or a logical value pair.
Logical Database Name
The name of a physically connected database. The logical database name is used to resolve
ambiguous database references.
Logical Expression
An expression that, when evaluated, yields true or false.
Logical Field
A field having a logical data type.
Logical Operator
An operator such as AND, OR, or NOT used in an expression that yields a true or false
value.
Menu
A widget containing a list of commands that users frequently use. The two kinds of menu
widgets available are menu bars and submenus.
Menu Accelerator Keys
A key or key combination which when pressed invokes an associated menu item. See also
accelerator key.
Menu Bar
A horizontal bar displayed at the top of a window. The menu bar contains menu labels
arranged horizontally. When you select a menu label, a pull-down menu containing a
vertically arranged list of items is displayed.
Menu Item
A menu component that the user can choose to direct an application to perform some
action or task.
Glossary–10
Glossary
Menu Titles
The text strings in a menu bar.
Menu Owner
The widget a menu is associated with. For menu bars, the owner is always a window.
Message Area of Screen
Three lines at the bottom of a Progress screen. The first two lines are for
procedure-specific messages. The third line is for Progress system and help messages.
Method
A function associated with a widget or system handle that performs a specific action and
returns a value (like a function) representing the result of that action.
Mnemonic
A single letter that you can press to choose a menu option. The mnemonic for each option
is underlined when it is displayed.
Modal Application
An application or part of an application that forces you to perform a specific action before
you can go on to other tasks.
Modeless Application
An application that gives you control over which tasks you perform when. It allows you a
number of processing choices and then reacts depending on the event you trigger.
Mouse
A device for communicating with a user interface.
Nonterminating Sequence
A sequence that begins at an initial value and increments in one direction with no limit.
See also terminating sequence.
One-to-one Relationship
Occurs when one record can relate to only one instance of a record in another table.
One-to-many Relationship
Occurs when one record can relate to many records in another table.
Operating System
Software that controls and manages the execution of computer programs and services.
Glossary–11
Progress Language Tutorial for Windows
Operator
The symbol you use to perform numeric calculations, date calculations, character string
manipulations, or data comparisons (+, /, and GT, for example).
Options
Similar to a phrase, only smaller. Options also modify the way Progress executes a
statement. Options usually consist of a single keyword and a possible accompanying
value.
Output Destination
A file or device to which a program sends output. Output destinations can include a
terminal, a printer, an ASCII file, or a printer queue.
Outer Join
See left outer join.
Parameter
A variable or constant passed between a subroutine and the main program. Also, a
Progress startup option.
Parent
The widget that contains or owns other widgets.
Parent Frame
A frame that contains another frame. See also root frame, child frame.
Parent Window
A window that owns another window. See also root window, child window.
Pathname
Specifies the complete name of a directory or file by starting at the root directory or disk
volume and tracing the hierarchy of the file.
Phrase
A collection of keywords and values that modifies the way Progress executes a statement.
Physical Database Name
The actual name of the database on a disk.
Predefined Function
A Progress-supplied function that provides short cuts for accomplishing common
programming tasks. See also Function.
Glossary–12
Glossary
Primary Index
Usually the most frequently used index. Progress allows you to set one index as primary
and uses it by default when searching for a record.
Procedure
The largest Progress unit of execution, consisting of one or more Progress source or r-code
statements in a single, outer block.
Procedure Area
The visible part of the current edit buffer. This is where you type and edit Progress
procedures. It is also called a text pane.
Procedure Block
A series of statements that Progress treats as a single unit.
Procedure Editor
An interactive utility that provides operations for editing code. You can use it to create,
compile, and run Progress procedure files.
Procedure File (.p file)
A source file containing Progress 4GL code which can be compiled into r-code. Procedure
files normally have a .p or .w (window procedure files) file extension.
Progress 4GL
An application development language which has a highly readable syntax employing a
default behavior while performing the work of multiple 3GL statements.
Pull-down Menu
A vertically displayed list of menu elements (menu items and submenus) appearing when
the user selects a menu title in a menu bar.
Query
1. ) A request for information from a database. 2.) A set of database records that you create
with your procedures. A query can involve one or more tables and can consist of all the
records in a particular table or just a subset. The browse widget is a ready-made interface
to a query.
Radio Button
One of the components of a radio set; it represents one of the possible values that the radio
set can take on.
Glossary–13
Progress Language Tutorial for Windows
Radio-set Widget
A field-level widget composed of a series of buttons that represent a single field or
variable, with each button representing a different possible value. Derived from the preset
tuning buttons on many automobile radios-when one button is selected, any previously
selected button is deselected.
Readable
Means that your application can read the current value and assign that value to a variable.
Record
A single occurrence of the data contained in a table. Records are treated as single units.
Records are made up of fields.
Record Buffer
A temporary storage area in data memory for a record, field, or variable. When you write
a record to the database, Progress gets that record from the record buffer.
Record Scope
The life span of a record in a record buffer. When the scope of a record ends, Progress
releases the record and writes the changes made to the record buffer to the database.
Rectangle Widget
A decorative parallelogram (all of whose angles equal 90 degrees) displayed in a frame or
in a frame background. Rectangles are display-only and cannot receive user input.
Related Tables
Tables that have at least one field in common.
Relational Database Management System (RDBMS)
A collection of hardware and software that organizes and provides access to a relational
database.
Relational Operator
A symbol such as = (equal to), < (less than), or > (greater than) that is used to compare
two values. It specifies a condition that can be either true or false.
Report
An organized display of data from a database.
Root Frame
A parent frame that is owned by a window and is the top parent of a frame family. See also
parent frame, child frame.
Glossary–14
Glossary
Root Window
A parent window that is parented only by the window system and is the top parent of a
window family. See also parent window, child window.
Row
1.) A collection of related items. Also called a record. 2.) A horizontally aligned set of
character cells in the character coordinate system.
Schema
A description of a database’s structure-the tables it contains, the fields within the tables,
views, etc. In addition to database structure, Progress database schemas contain items such
as validation expression and validation message.
Screen Buffer
A display area for a field, variable, or the result of a calculation. When you prompt for
information or display information for the user, Progress places that information in the
screen buffer.
Selection Criteria
Conditional expressions used to select particular records from a database table or tables.
Selection-list Widget
A scrolling list of character strings. The strings are the possible values for an underlying
field or variable.
Self
In a trigger, SELF is a system-handle whose value is the widget handle of the widget that
received the event that fired the trigger. See also system handle and widget handle.
Sensitive Widget
A widget that reacts to user actions.
Sequence
A database object that provides incremental values to an application. Sequences can
generate sequential values within any integer range with a positive or negative value.
Sequence Properties
The schema definitions that define the sequence, such as the sequence name, the initial
value, and so on.
Setable Attribute
An attribute to which the application can assign a new value.
Glossary–15
Progress Language Tutorial for Windows
Shared Variable
A variable used to pass information from one procedure to another.
Side Labels
Field labels to the left of the data and separated from the data by a colon and a space. See
also column labels.
Slider Widget
A field-level widget composed of a rectangular scale that represents a range of INTEGER
values. A marker within the scale indicates the current value. Only values of type
INTEGER can be viewed as sliders.
Sports Database
A sample Progress database containing files, fields, and indexes (including some data) that
procedures in Progress documentation use to acquaint you with the way Progress operates.
Statement
An instruction written in the Progress language.
Stream
A sequence of characters or items.
String
A character expression (a constant, field name, variable name, or any combination of these
that results in a character string value).
Submenu
A vertically displayed list of menu items and submenus that appears when the user selects
a menu title in a menu bar.
Subprocedure
A procedure that runs from the main procedure. A subprocedure can be either an internal
or external procedure.
System Handle
A pseudo widget handle that provides a range of system capabilities sometimes associated
with a visual widget. System handles that reference instances of visual widgets (for
example, FOCUS) adopt all the attributes, methods, and events of the widget. Other
system handles provide monitoring and control capabilities (for example, CLIPBOARD).
System handles have their own attributes and methods, but do not respond to Progress
events.
Glossary–16
Glossary
Table
A collection of logically related records organized into rows and columns. A table can
contain a program, data, or text. A table is made up of records. It is also called a file.
Table Properties
The schema definitions that define the table, such as the table name, the table type, and so
on.
Terminating Sequence
A sequence which begins at an initial value and increments in one direction until it reaches
the designated limit. See also nonterminating sequence.
Text Widget
A field-level widget that displays any kind of data. It is read-only, and does not receive
normal user events. Text widgets cannot have input focus.
ToolTip
A brief text message that Progress automatically displays when the user pauses the mouse
pointer over a widget for which a ToolTip has been defined. These language elements
support the TOOLTIP option: DEFINE BROWSE statement, DEFINE BUTTON
statement, DEFINE IMAGE statement, DEFINED RECTANGLE statement, and
VIEW-AS phrase. These widgets support the TOOLTIP attribute: browse, button,
combo-box, editor, fill-in, image, radio-set, rectangle, selection-list, slider, text, and
toggle-box. ToolTips are only supported on Windows.
Toggle Box Widget
A field-level widget composed of a small box that represents a logical value. Only values
of type LOGICAL can be viewed as toggle boxes. The presence (TRUE) or absence
(FALSE) of filling in the toggle box indicates the current value. A toggle box can be a
field-level widget or a special type of menu item.
Top-down Programming
Traditional programming where you define larger structures first and then define smaller
and smaller components.
Trigger
A piece of code that Progress executes on behalf of an application when a certain database
action occurs or a certain user-interface event occurs. There are two types of triggers:
database triggers and user-interface triggers.
Glossary–17
Progress Language Tutorial for Windows
Unique Index
An indexed field where every index key must be different. For example, Social Security
number could be a unique index.
User-defined Function
A function that you can create based on a programming task that you want to solve. You
can reuse this code once you create it. See also function.
User Interface Triggers
A piece of code that an application associates with one or more event-widget pairs. When
the widget receives the event, Progress locates this piece of code and executes it on behalf
of the application.
Validation Expression
A test to make sure that the user does not enter invalid data in a field.
Validation Message
A user-defined message the Dictionary displays when the user attempts to delete the
selected table without meeting the table-validation criteria.
Variable
A temporary field for storing data.
Widget
An object that provides visual and interactive capabilities for a Progress application. A
widget is a 4GL-aware control. That is, it is a control that shares common capabilities with
other controls of the same type defined in the 4GL. There are several widget types that
form a hierarchy in the 4GL, starting with windows. Windows can own other windows.
Windows also contain frames and dialog boxes. Frames and dialog boxes contain field
groups, and field groups contain field-level widgets or other frames. Widgets have
attributes and methods and respond to events. Widgets serve as receptors for user input and
also display application output.
Widget Attributes
Characteristics of the widget such as its type, screen location, size, color, font, and
relationship to other widgets.
Widget Handle
To allow you to reference widgets within an application, Progress assigns each widget a
unique widget handle. A widget handle is a pointer to the widget. Progress provides the
WIDGET-HANDLE data type, to support handle values.
Glossary–18
Glossary
Window Family
A related collection of parent and child windows.
Window Widget
The workspace of your application. Each time you start a Progress session, it automatically
creates a default window.
Word Index
Contains all the words from a character field or array of character fields. Searching with
this index makes it very easy to locate records that contain specific words.
Working Directory
The directory you are in when you issue a command.
Working Database
The connected database that is currently in use. Multiple databases can be connected at any
time, but only one is the current, working database.
Glossary–19
Progress Language Tutorial for Windows
Glossary–20
Index
Arguments
3GL. see also Third generation languages
passing 6–17
4GL conventions 2–18 using with include files 6–18
Index–2
Index
Index–3
Progress Language Tutorial for Windows
Index–4
Index
Index–5
Progress Language Tutorial for Windows
Index–6
Index
M Monospaced typeface
as typographical convention xx
Main logic 6–22
Mouse actions 2–7
Main procedures 6–2
Mouse functions 2–7
Manual
Multi-frame interfaces 12–11
organization of xvii
syntax notation xxi MULTIPLE option 7–45
MATCHES operator 9–4
Menu bar widget 2–3, 3–15, 11–2, 11–6 Nested submenus 11–2
menu title 11–2
NEW SHARED option 6–10
Menu conventions 2–11
NEXT-SIBLING attribute 3–30, 12–7
Menu item widget 3–15, 11–5
disabling 11–14 NO-BOX option 3–7
Index–7
Progress Language Tutorial for Windows
Index–8
Index
SCROLLBAR-HORIZONTAL option
Index–9
Progress Language Tutorial for Windows
Index–10
Index
THIS-PROCEDURE 12–7 U
Universal key functions 3–32
T
UPDATE statement 8–32
Tabbing
between frames 12–11 Updateable browse widget 8–52, 8–56
Index–11
Progress Language Tutorial for Windows
Index–12