4D 2003 Language
4D 2003 Language
_______________________________________________________________________________________________________________________________________________________________
Language Reference
Windows®/Mac™OS
4th Dimension®
© 1985 - 2003 4D SA / 4D, Inc. All Rights Reserved.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Software described in this manual is governed by the grant of license in the 4D
Product Line License Agreement provided with the Software in this package. The
Software, this manual, and all documentation included with the Software are copyrighted
and may not be reproduced in whole or in part except for in accordance with the 4D
Product Line License Agreement.
4th Dimension, 4D, the 4D logo and 4D Server are registered trademarks of 4D SA.
Apple, Macintosh, Mac, Power Macintosh, Laser Writer, Image Writer, ResEdit, and
QuickTime are trademarks or registered trademarks of Apple Computer, Inc.
All other referenced trade names are trademarks or registered trademarks of their
respective holders.
Use of this Software is subject to the 4D Product Line License Agreement, which is
provided in electronic form with the Software. Please read the 4D Product Line License
Agreement carefully before completely installing or using the Software.
Contents
1. Introduction 35
Preface 37
Introduction 39
Building a 4D Application 49
2. Language Definition 61
Introduction to the 4D Language 63
Data Types 68
Constants 73
Variables 77
System Variables 82
Pointers 85
Identifiers 94
Control Flow 105
If...Else...End if 107
Case of...Else...End case 109
While...End while 113
Repeat...Until 114
For...End for 115
Methods 121
Project Methods 127
3. 4D Environment 135
Application type 137
Version type 138
Application version 139
Compiled application 141
Application file 142
Structure file 143
Data file 145
Is data file locked 147
Get 4D folder 148
DATA SEGMENT LIST 150
ADD DATA SEGMENT 152
4. Arrays 163
Arrays 165
Creating Arrays 166
Arrays and Form Objects 168
Grouped Scrollable Areas 176
Arrays and the 4D Language 179
Arrays and Pointers 181
Using the element zero of an array 183
Two-dimensional Arrays 185
Arrays and Memory 187
ARRAY INTEGER 189
ARRAY LONGINT 190
ARRAY REAL 191
ARRAY STRING 192
ARRAY TEXT 194
ARRAY DATE 195
ARRAY BOOLEAN 196
ARRAY PICTURE 198
ARRAY POINTER 200
Size of array 202
SORT ARRAY 203
MULTI SORT ARRAY 205
Find in array 207
INSERT ELEMENT 209
DELETE ELEMENT 210
COPY ARRAY 211
LIST TO ARRAY 212
ARRAY TO LIST 213
SELECTION TO ARRAY 215
SELECTION RANGE TO ARRAY 217
5. BLOB 227
BLOB Commands 229
SET BLOB SIZE 232
BLOB size 233
COMPRESS BLOB 234
EXPAND BLOB 236
BLOB PROPERTIES 238
DOCUMENT TO BLOB 240
BLOB TO DOCUMENT 242
VARIABLE TO BLOB 244
BLOB TO VARIABLE 247
LIST TO BLOB 248
BLOB to list 249
INTEGER TO BLOB 251
LONGINT TO BLOB 253
REAL TO BLOB 255
TEXT TO BLOB 258
BLOB to integer 260
BLOB to longint 262
BLOB to real 264
BLOB to text 266
INSERT IN BLOB 268
DELETE FROM BLOB 269
COPY BLOB 270
ENCRYPT BLOB 271
DECRYPT BLOB 276
6. Boolean 277
Boolean Commands 279
True 280
False 281
7. Clipboard 283
APPEND TO CLIPBOARD 285
CLEAR CLIPBOARD 291
GET CLIPBOARD 292
GET PICTURE FROM CLIPBOARD 294
Get text from clipboard 295
SET PICTURE TO CLIPBOARD 297
SET TEXT TO CLIPBOARD 298
Test clipboard 299
8. Communications 301
SET CHANNEL 303
SET TIMEOUT 307
USE ASCII MAP 308
SEND PACKET 310
RECEIVE PACKET 312
RECEIVE BUFFER 315
SEND VARIABLE 317
RECEIVE VARIABLE 318
SEND RECORD 319
RECEIVE RECORD 320
9. Compiler 325
Compiler Commands 327
C_BLOB 330
C_BOOLEAN 331
C_DATE 332
C_GRAPH 333
C_INTEGER 334
C_LONGINT 335
C_PICTURE 336
C_POINTER 337
Introduction
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension has its own programming language. This built-in language, consisting of
over 500 commands, makes 4th Dimension a powerful development tool for database
applications on desktop computers. You can use the 4th Dimension language for many
different tasks—from performing simple calculations to creating complex custom user
interfaces. For example, you can:
• Programmatically access any of the editors available to the user in the User
environment,
• Create and print complex reports and labels with the information from the database,
• Communicate with other devices,
• Manage documents,
• Import and export data between 4th Dimension databases and other applications,
• Incorporate procedures written in other languages into the 4th Dimension
programming language.
The flexibility and power of the 4th Dimension programming language make it the ideal
tool for all levels of users and developers to accomplish a complete range of information
management tasks. Novice users can quickly perform calculations. Experienced users
without programming experience can customize their databases. Experienced developers
can use this powerful programming language to add sophisticated features and capabilities
to their databases, including file transfer and communications. Developers with
programming experience in other languages can add their own commands to the
4th Dimension language.
The 4th Dimension programming language is expanded when any of the 4th Dimension
modules are added to the application. Each module includes language commands that are
specific to the capabilities they provide.
• The Language Reference is a guide to using the 4th Dimension language. Use this manual
to learn how to customize your database by incorporating 4th Dimension commands and
functions.
• The Design Reference provides detailed descriptions of the operations you can perform in
the Design environment to create forms for managing data.
• The User Reference provides a description of the User environment, in which users enter
and manipulate data in forms.
• The Quickstart manual leads you through example lessons in which you create and use a
4th Dimension database. These examples provide hands-on experience and help you
become familiar with the concepts and features of 4th Dimension and 4D Server.
• The 4D Server Reference, which is included only in the 4D Server package, is a guide to
managing multi-user databases with 4D Server.
This topic introduces you to the 4th Dimension programming language. The following
topics are discussed:
• What the language is and what it can do for you,
• How you will use methods,
• How to develop an application with 4th Dimension.
These topics are covered here in general terms; they are covered in greater detail in other
sections.
What is a Language?
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The 4th Dimension language is not very different from the spoken language we use every
day. It is a form of communication used to express ideas, inform, and instruct. Like a
spoken language, 4th Dimension has its own vocabulary, grammar, and syntax; you use it
to tell 4th Dimension how to manage your database and data.
You do not need to know everything in the language in order to work effectively with
4th Dimension. In order to speak, you do not need to know the entire English language;
in fact, you can have a small vocabulary and still be quite eloquent. The 4th Dimension
language is much the same—you only need to know a small part of the language to
become productive, and you can learn the rest as the need arises.
At first it may seem that there is little need for a programming language in 4th
Dimension. The Design and User environments provide flexible tools, which require no
programming to perform a wide variety of data management tasks. Fundamental tasks,
such as data entry, queries, sorting, and reporting are handled with ease. In fact, many
extra capabilities are available, such as data validation, data entry aids, graphing, and label
generation.
Then why do we need a 4th Dimension language? Here are some of its uses:
• Automate repetitive tasks: These tasks include data modification, generation of complex
reports, and unattended completion of long series of operations.
• Control the user interface: You can manage windows and menus, and control forms
and interface objects.
• Perform sophisticated data management: These tasks include transaction processing,
complex data validation, multi-user management, sets, and named selection operations.
• Control the computer: You can control serial port communications, document
management, and error management.
The language lets you take complete control over the design and operation of your
database. While the User environment gives you powerful “generic” tools, the language
lets you customize your database to whatever degree you require.
The 4th Dimension language lets you take complete control of your data in a powerful
and elegant manner. The language is easy enough for a beginner, and sophisticated
enough for an experienced application developer. It provides smooth transitions from
built-in database functions to a completely customized database.
The commands in the 4th Dimension language provide access to the User environment
editors, with which you are already familiar. For example, when you use the QUERY
command, you are presented with the Query Editor. Using this language command is
almost as easy as choosing the Query command from the Queries menu, but the QUERY
command is even more useful. You can tell the QUERY command to search for explicitly
described data. For example, QUERY ([People];[People]Last Name="Smith") will find all the
people named Smith in your database.
The 4th Dimension language is very powerful—one command often replaces hundreds or
even thousands of lines of code written in traditional computer languages. Surprisingly
enough, with this power comes simplicity—commands have plain English names. For
example, to perform a query, you use the QUERY command; to add a new record, you use
the ADD RECORD command.
The language is designed for you to easily accomplish almost any task. Adding a record,
sorting records, searching for data, and similar operations are specified with simple and
direct commands. But the language can also control the serial ports, read disk documents,
control sophisticated transaction processing, and much more.
The 4th Dimension language accomplishes even the most sophisticated tasks with relative
simplicity. Performing these tasks without using the language would be unimaginable for
many.
Even with the language’s powerful commands, some tasks can be complex and difficult. A
tool by itself does not make a task possible; the task itself may be challenging and the
tool can only ease the process. For example, a word processor makes writing a book faster
and easier, but it will not write the book for you. Using the 4th Dimension language will
make the process of managing your data easier and will allow you to approach
complicated tasks with confidence.
If you are familiar with traditional computer languages, this section may be of interest. If
not, you may want to skip it.
The 4th Dimension language is not a traditional computer language. It is one of the most
innovative and flexible languages available on a computer today. It is designed to work
the way you do, and not the other way around.
To use traditional languages, you must do extensive planning. In fact, planning is one of
the major steps in development. 4th Dimension allows you to start using the language at
any time and in any part of your database. You may start by adding a method to a form,
then later add a few more methods. As your database becomes more sophisticated, you
might add a project method controlled by a menu. You can use as little or as much of the
language as you want. It is not “all or nothing,” as is the case with many other databases.
Traditional languages force you to define and pre-declare objects in formal syntactic
terms. In 4th Dimension, you simply create an object, such as a button, and use it.
4th Dimension automatically manages the object for you. For example, to use a button,
you draw it on a form and name it. When the user clicks the button, the language
automatically notifies your methods.
Traditional languages are often rigid and inflexible, requiring commands to be entered in
a very formal and restrictive style. The 4th Dimension language breaks with tradition,
and the benefits are yours.
A method is a series of instructions that causes 4th Dimension to perform a task. Each
line of instruction in a method is called a statement. Each statement is composed of parts
of the language.
Because you have already worked through the Quickstart tutorials (you did go through
Quickstart, didn’t you?), you have already written and used methods.
Object methods are the primary tools for managing the user interface, which is the
doorway to your database. The user interface consists of the procedures and conventions
by which a computer communicates with the user. The goal is to make the user interface
of your database as simple and easy to use as possible. The user interface should make
interaction with the computer a pleasant process, one that the user enjoys or does not
even notice.
4th Dimension enables you to build classic forms, such as the one shown here:
Whatever your style in building forms, all active objects have built-in aids, like range
checking and entry filters for data entry areas, and automatic actions for controls, menus,
and buttons. Always use these aids before adding object methods. The built-in aids are
similar to methods in that they remain associated with the active object and are active
only when the active object is being used. You will typically use a combination of built-in
aids and object methods to control the user interface.
An object method associated with an active object used for data entry typically performs a
data-management task specific to the field or variable. The method can perform data
validation, data formatting, or calculations. It may even get related information from
other files. Some of these tasks can, of course, also be performed with the built-in data
entry aids for objects. Use object methods when the task is too complex for the built-in
data entry aids to manage. For more information about the built-in data entry aids, refer
to the 4th Dimension Design Reference.
As you become more proficient with scripts, you will find that you can create libraries of
objects with associated methods. You can copy and paste these objects and their methods
between forms, tables, and databases. You can even keep them in the Clipbook
(Windows) or Scrapbook (Macintosh), ready to be used when you need them.
Form methods manage forms at a higher level than do object methods. Object methods
are activated only when the object is used, whereas a form method is activated when
anything in the form is used. Form methods are typically used to control the interaction
between the different objects and the form as a whole.
There is one other way to use project methods—associating them with menu commands.
When you associate a project method with a menu command, the method is executed
when the menu is chosen. You can think of the menu command as calling the project
method.
Development is the process of customizing a database using the language and other built-
in tools.
Perhaps your first use of the language is to add a method to a form object in order to
control data entry. Later, you might add a form method to control the display of your
form. As the database becomes more complex, you can add a menu bar with project
methods to completely customize your database.
As with other aspects of 4th Dimension, development is a very flexible process. There is
no formal path to take during development—you can develop in a manner with which
you are comfortable. There are, of course, some general patterns in the process.
• Implementation: Implement your design in the Design environment.
• Testing: You try out the design in the User environment and perhaps stay there to use
your customized database.
• Usage: When your database is fully customized, you use it in the Custom Menus
environment.
• Corrections: If you find errors, you return to the Design environment to fix them.
Special development support tools, hidden until needed, are built into 4th Dimension. As
you use the language more frequently, you will find that these tools facilitate the
development process. For example, the Method Editor catches typing errors and formats
your work; the Interpreter (the engine that runs the language) catches errors in syntax
and shows you where and what they are; and the Debugger lets you monitor the
execution of your methods to catch errors in design.
Building Applications
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
By now you are familiar with the general uses of a database—data entry, searching,
sorting, and reporting. You have performed these tasks in the User environment, using
the built-in menus and editors.
As you use a database, you perform some sequences of tasks repeatedly. For example, in a
database of personal contacts, you might search for your business associates, order them
by last name, and print a specific report each time information about them is changed.
These tasks may not seem difficult, but they can certainly be time-consuming after you
have done them 20 times. In addition, if you don’t use the database for a couple of weeks,
you may return to find that the steps used to generate the report are not so fresh in your
mind. The steps in methods are chained together, so a single command automatically
performs all the tasks linked to it. Consequently, you do not have to worry about the
specific steps.
You can compile your databases and create stand-alone Windows and Macintosh
applications. Compiling databases increases the execution speed of the language, protects
your databases, and allows you to create applications that are completely independent.
The integrated compiler also checks the syntax and the types of variables in methods for
consistency.
An application can be as simple as a single menu that lets you enter people’s names and
print a report, or as complex as an invoicing, inventory, and control system. There are no
limits to the uses of database applications. Typically, an application grows from a database
used in the User environment to a database controlled completely by custom menus.
An application is a database designed to fill a specific need. It has a user interface designed
specifically to facilitate its use. The tasks that an application performs are limited to those
appropriate for its purpose. Creating applications with 4th Dimension is smoother and
easier than with traditional programming. 4th Dimension can be used to create a variety
of applications, including:
• An invoice system
• An inventory control system
• An accounting system
• A payroll system
• A personnel system
• A customer tracking system
• A database shared over the Internet or an Intranet
It is possible that a single application could even contain all of these systems. Applications
like these are typical uses of databases. In addition, the tools in 4th Dimension allow you
to create innovative applications, such as:
• A document tracking system
• A graphic image management system
• A catalog publishing application
• A serial device control and monitoring system
• An electronic mail system (E-mail)
• A multi-user scheduling system
• A list such as a menu list, video collection, or music collection
An application typically starts as a database used in the User environment. The database
“evolves” into an application as it is customized. What differentiates an application is that
the systems required to manage the database are hidden from the user. Database
management is automated, and users use menus to perform specific tasks.
When you use a 4th Dimension database in the User environment, you must know the
steps to take to achieve a result. In an application, you use the Custom Menus
environment, in which you need to manage all the aspects that are automatic in the User
Environment. These include:
•Table Navigation: The Choose Table/Form dialog box and List of Tables window are not
available to the user. You can use menu commands and methods to control navigation
between tables.
• Menus: In the Custom Menus environment, you only have the default File menu with
the Quit menu command, Edit menu, and the Help menu (Windows only) or the Apple
menu (Macintosh only). If the application requires more menus, you have to create and
manage them using 4D methods.
The following sections include examples showing how the language can automate the use
of a database.
Custom Menus are the primary interface in an application. They make it easier for users
to learn and use a database. Creating custom menus is very simple—you associate
methods or automatic actions with each menu command (also called menu items) in the
Menu editor.
“The User's Perspective” section describes what happens when the user chooses a menu
command. Next, “Behind the Scenes” describes the design work that made it happen.
Although the example is simple, it should be apparent how custom menus make the
database easier to use and learn. Rather than the “generic” tools and menu commands in
the User environment, the user sees only things that are appropriate to his or her needs.
The user enters the person’s first name and then tabs to the next field.
The user tabs to the next field: the last name is converted to uppercase.
Another blank record appears, and the user clicks the Cancel button (the one with the
“X”) to terminate the “data entry loop.” The user is returned to the menu bar.
When the user chooses this menu item, the New Person method executes:
Repeat
ADD RECORD([People])
Until (OK=0)
The Repeat...Until loop with an ADD RECORD command within the loop acts just like the
New Record menu item in the User environment. It displays the input form to the user,
so that he or she can add a new record. When the user saves the record, another new
blank record appears. This ADD RECORD loop continues to execute until the user clicks
the Cancel button.
After a record has been entered, when the user clicks the Cancel button for the next one,
the OK variable is set to zero, thus ending the execution of the ADD RECORD loop.
As there are no more statements to execute, the New Person method stops executing and
control returns to the menu bar.
Let’s compare the way a task is performed in the User environment and the way the same
task is performed using the language. The task is a common one:
• Find a group of records
• Sort them
• Print a report
The following section, “Using the Built-in Editors within the Custom Menus
environment,” displays the same tasks performed in an application.
Note that although both methods perform the same task, the steps in the second section
are automated using the language.
The user enters the criteria and clicks the Query button. The search is performed.
The user enters the criteria and clicks the Sort button. The sort is performed.
A method called My Report is attached to the menu command; it looks like this:
QUERY ([People])
ORDER BY ([People])
OUTPUT FORM ([People]; "Report")
PRINT SELECTION ([People])
The user enters the criteria and clicks the Query button. The query is performed.
Note that the user did not need to know that ordering the records was the next step.
The user enters the criteria and clicks the Sort button. The sort is performed.
Once again, the user did not need to know what to do next; the method takes care of
that.
The Printing dialog boxes are displayed. The User chooses the settings, and the report is
printed.
The same commands used in the previous example can be used to further automate the
database.
The user chooses Report from the People menu. A method called My Report2 is attached
to the menu command. It looks like this:
QUERY([People];[People]Company="Acme")
ORDER BY([People]; [People]Last Name;>;[People]First Name;>)
OUTPUT FORM([People];"Report")
PRINT SELECTION([People];*)
The Query editor is not displayed. Instead, the query is specified and performed by the
QUERY command. The user does not need to do anything.
The Order By editor is not displayed, and the sort is immediately performed. Once again,
no user actions are required.
The Printing dialog boxes are not displayed. The PRINT SELECTION command accepts an
optional asterisk (*) parameter that instructs the command to use the print settings that
were in effect when the report form was created. The report is printed.
This additional automation saved the user from having to enter options in three dialog
boxes. Here are the benefits :
• The query is automatically performed: users may select wrong criteria when making a
query.
• The sort is automatically performed: users may select wrong criteria when defining a
sort.
• The printing is automatically performed: users may select the wrong form to print.
As you develop a 4D application, you will discover many capabilities that you did not
notice when you started. You can even augment the standard version of 4D by adding
other tools and plug-ins to your 4D development environment.
• 4D Backup allows you to automatically save the data entered and to restore the
information in the event of an operating incident.
4D Plug-ins
You can extend the capabilities of your 4D applications by adding professional Plug-ins to
your 4D development environment.
For more information, contact 4D or its Partners. Visit our Web Sites:
USA & International:
http://www.4d.com
France:
http://www.4d.fr
The 4D community offers access to tips and tricks, solutions, information, and additional
tools that will save you time and energy, and increase your productivity.
Language Definition
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The 4th Dimension language is made up of various components that help you perform
tasks and manage your data.
• Data types: Classifications of data in a database. See discussion in this section as well as
the detailed discussion in the section Data Types.
• Variables: Temporary storage places for data in memory. See detailed discussion in the
section Variables.
• Operators: Symbols that perform a calculation between two values. See discussion in this
section as well as the detailed discussion in the section Operators and its subsections.
• Expressions: Combinations of other components that result in a value. See discussion in
this section.
• Commands: Built-in instructions to perform an action. All 4D commands, such as ADD
RECORD, are described in this manual, grouped by theme; when necessary, the theme is
preceded by an introductory section. You can use 4D Plug-ins to add new commands to
your 4D development environment. For example, once you have added the 4D Write
Plug-in to your 4D system, the 4D Write commands become available for creating and
manipulating word-processing documents.
• Methods: Instructions that you write using all parts of the language listed here. See
discussion in the section Methods and its subsections.
This section introduces Data Types, Operators, and Expressions. For the other components,
refer to the sections cited above.
In addition:
• Language components, such as variables, have names called Identifiers. For a detailed
discussion about identifiers and the rules for naming objects, refer to the section
Identifiers.
• To learn more about array variables, refer to the section Arrays.
• To learn more about BLOB variables, refer to the section BLOB commands.
• If you plan to compile your database, refer to the section Compiler Commands as well as
the 4D Compiler Reference Guide.
In the language, the various types of data that can be stored in a 4th Dimension database
are referred to as data types. There are seven basic data types: string, numeric, date, time,
Boolean, picture, and pointer.
• String: A series of characters, such as “Hello there”. Alpha and Text fields, and string and
text variables, are of the string data type.
• Numeric: Numbers, such as 2 or 1,000.67. Integer, Long Integer, and Real fields and
variables are of the numeric data type.
• Date: Calendar dates, such as 1/20/89. Date fields and variables are of the date data type.
• Time: Times, including hours, minutes, and seconds, such as 1:00:00 or 4:35:30 PM.
Time fields and variables are of the time data type.
• Boolean: Logical values of TRUE or FALSE. Boolean fields and variables are of the
Boolean data type.
• Picture: Picture fields and variables are of the picture data type.
• Pointer: A special type of data used in advanced programming. Pointer variables are of
the pointer data type. There is no corresponding field type.
Note that in the list of data types, the string and numeric data types are associated with
more than one type of field. When data is put into a field, the language automatically
converts the data to the correct type for the field. For example, if an integer field is used,
its data is automatically treated as numeric. In other words, you need not worry about
mixing similar field types when using the language; it will manage them for you.
However, when using the language it is important that you do not mix different data
types. In the same way that it makes no sense to store “ABC” in a Date field, it makes no
sense to put “ABC” in a variable used for dates. In most cases, 4th Dimension is very
tolerant and will try to make sense of what you are doing. For example, if you add a
number to a date, 4th Dimension will assume that you want to add that number of days
to the date, but if you try to add a string to a date, 4th Dimension will tell you that the
operation cannot work.
There are cases in which you need to store data as one type and use it as another type. The
language contains a full complement of commands that let you convert from one data
type to another. For example, you may need to create a part number that starts with a
number and ends with characters such as “abc”. In this case, you might write:
[Products]Part Number:=String(Number)+"abc"
If Number is 17, then [Products]Part Number will get the string “17abc”.
The data types are fully defined in the section Data Types.
When you use the language, it is rare that you will simply want a piece of data. It is more
likely that you will want to do something to or with that data. You perform such
calculations with operators. Operators, in general, take two pieces of data and perform an
operation on them that results in a new piece of data. You are already familiar with many
operators. For example, 1 + 2 uses the addition (or plus sign) operator to add two numbers
together, and the result is 3. This table shows some familiar numeric operators:
Operator Operation Example
+ Addition 1 + 2 results in 3
– Subtraction 3 – 2 results in 1
* Multiplication 2 * 3 results in 6
/ Division 6 / 2 results in 3
Numeric operators are just one type of operator available to you. 4th Dimension supports
many different types of data, such as numbers, text, dates, and pictures, so there are
operators that perform operations on these different data types.
The same symbols are often used for different operations, depending on the data type. For
example, the plus sign (+) performs different operations with different data:
Data Type Operation Example
Number Addition 1 + 2 adds the numbers and results in 3
String Concatenation “Hello ” + “there” concatenates (joins together)
the strings and results in “Hello there”
Date and Number Date addition !1/1/1989! + 20 adds 20 days to the date
January 1, 1989, and results in the date
January 21, 1989
The operators are fully defined in the section Operators and its subsections.
Expressions
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Simply put, expressions return a value. In fact, when using the 4th Dimension language,
you use expressions all the time and tend to think of them only in terms of the value
they represent. Expressions are also sometimes referred to as formulas.
Expressions are made up of almost all the other parts of the language: commands,
operators, variables, and fields. You use expressions to build statements (lines of code),
which in turn are used to build methods. The language uses expressions wherever it needs
a piece of data.
An expression can simply be a constant, such as the number 4 or the string “Hello.” As
the name implies, a constant’s value never changes. It is when operators are introduced
that expressions start to get interesting. In preceding sections you have already seen
expressions that use operators. For example, 4 + 2 is an expression that uses the addition
operator to add two numbers together and return the result 6.
You refer to an expression by the data type it returns. There are seven expression types:
• String expression
• Numeric expression (also referred to as number)
• Date expression
• Time expression
• Boolean expression
• Picture expression
• Pointer expression
The following table gives examples of each of the seven types of expressions.
Expression Type Explanation
“Hello” String The word Hello is a string constant,
indicated by the double quotation marks.
“Hello ” + “there” String Two strings, “Hello ” and “there”, are added
together (concatenated) with the string
concatenation operator (+).
The string “Hello there” is returned.
“Mr. ” + [People]Name String Two strings are concatenated: the string “Mr. ”
and the current value of the Name field in the
People table.
If the field contains “Smith”, the expression
returns “Mr. Smith”.
Uppercase (“smith”) String This expression uses “Uppercase”, a command
from the language, to convert the string
“smith” to uppercase.
It returns “SMITH”.
4 Number This is a number constant, 4.
4*2 Number Two numbers, 4 and 2, are multiplied using the
multiplication operator (*).
The result is the number 8.
See Also
Arrays, Constants, Data Types, Methods, Operators, Pointers, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension fields, variables, and expressions can be of the following data types:
Notes
1. String includes alphanumeric field, fixed length variable, and text field or variable.
2. Number includes Real, Integer, and Long Integer field and variable.
3. BLOB is an acronym for Binary Large OBject. For more information about BLOBs, see
the section BLOB Commands.
4. Array includes all types of arrays. For more information, see the section Arrays.
String
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A string is composed of characters. Each character can be any of the 256 ASCII codes. For
more information about ASCII codes and how 4D handles them in a cross-platform
environment, see the section ASCII Codes.
You can assign a string to a text field and vice-versa; 4D does the conversion, truncating
if necessary. You can mix string and text in an expression.
Note: In the 4D Language Reference, both string and text parameters in command
descriptions are denoted as String, except when marked otherwise.
Number
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The range for the Real data type is ±1.7e±308 (15 digits)
The range for the Integer data type (2-byte Integer) is -32,768..32,767 (2^15..(2^15)-1)
The range for the Long Integer data type (4-byte Integer) is -2^31..(2^31)-1
You can assign any Number data type to another; 4D does the conversion, truncating or
rounding if necessary. However, when values are out of range, the conversion will not
return a valid value. You can mix Number data types in expressions.
Note: In the 4D Language Reference, no matter the actual data type, the Real, Integer, and
Long Integer parameters in command descriptions are denoted as Number, except when
marked otherwise.
Date
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Boolean
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Picture
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Pointer
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A BLOB field or variable is a series of bytes (from 0 to 2 GB in length) that you can address
individually or by using the BLOB Commands. There is no expression of type BLOB.
Note: In the 4D Language Reference, BLOB parameters in command descriptions are
denoted as BLOB.
Array
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Array is not actually a data type. The various types of arrays (such as Integer Array, Text
Array, and so on) are grouped under this title. Arrays are variables—there is no field of
type Array, and there is no expression of type Array. For more information about arrays,
see the section Arrays.
Subtable
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Subtable is not actually a data type. Only fields can be of type Subtable. There is no
variable or expression of type Subtable. For more information about subtables, see the 4th
Dimension Design Reference manual as well as the commands regrouped under the
Subrecords theme.
Undefined
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Undefined is not actually a data type. It denotes a variable that has not yet been defined.
A function (a project method that returns a result) can return an undefined value if,
within the method, the function result ($0) is assigned an undefined expression (an
expression calculated with at least one undefined variable). A field cannot be undefined.
The 4D language contains operators and commands to convert between data types, where
such conversions are meaningful. The 4D language enforces data type checking. For
example, you cannot write: "abc"+0.5+!12/25/96!-?00:30:45?. This will generate syntax
errors.
Note: In addition to the data conversions listed inthis table, more sophisticated data
conversions can be obtained by combining operators and other commands.
See Also
Arrays, Constants, Control Flow, Identifiers, Methods, Operators, Pointers, Type, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A constant is an expression that has a fixed value. There are two types of constants:
predefined constants that you select by name, and literal constants for which you type
the actual value.
Predefined Constants
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Version 6 of 4th Dimension introduces predefined constants. These constants are listed in
the Explorer Window:
The predefined constants are listed by theme. To use a predefined constant in a Method
editor window:
• Drag and drop the constant from the Explorer window to the Method Editor window.
• Directly type its name in the Method Editor window.
Tip: If you directly enter the name of a predefined constant, you can use the @ symbol (at
sign) to avoid typing the entire constant name. For example, if you type “No such da@”,
4D will fill the line with the constant “No such data in clipboard” when you press Return
or Enter to validate the line of code.
Predefined constants appeared underlined by default within the Method Editor and
Debugger windows:
In the window shown here, Is Alpha Field, for example, is a predefined constant.
Literal Constants
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
String Constants
A string constant is enclosed in double, straight quotation marks ("…"). Here are some
examples of string constants:
"Add Records"
"No records found."
"Invoice"
An empty string is specified by two quotation marks with nothing between them ("").
Negative numbers are specified with the minus sign(–). For example:
–27
–123.76
–0.0076
Date Constants
A date constant is enclosed by exclamation marks (!…!). In the US English version of 4D,
a date is ordered month/day/year, with a slash (/) setting off each part. Here are some
examples of date constants:
!1/1/76!
!4/4/04!
!12/25/96!
Tip: The Method Editor includes a shortcut for entering a null date. To type a null date,
enter the exclamation (!) character and press Enter.
Note: A two-digit year is assumed to be in the 1900’s. Unless this default setting has been
changed using the command SET DEFAULT CENTURY.
Time Constants
A time constant is enclosed by question marks (?...?).
Note: This syntax can be used on both Windows and Macintosh. On Macintosh, you can
also use the Dagger symbol (Option-T on a US keyboard).
Tip: The Method Editor includes a shortcut for entering a null time. To type a null time,
enter the question mark (?) character and press Enter.
See Also
Control Flow, Data Types, Identifiers, Methods, Operators, Pointers, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Data in 4th Dimension is stored in two fundamentally different ways. Fields store data
permanently on disk; variables store data temporarily in memory.
When you set up your 4th Dimension database, you specify the names and types of fields
that you want to use. Variables are much the same—you also give them names and
different types.
You can display variables (except Pointer and BLOB) on the screen, enter data into them,
and print them in reports. In these ways, enterable and non-enterable area variables act
just like fields, and the same built-in controls are available when you create them:
• Display formats
• Data validation, such entry filters and default values
• Character filters
• Choice lists (hierarchical lists)
• Enterable or non-enterable values
You create variables simply by using them; you do not need to formally define them as
you do with fields. For example, if you want a variable that will hold the current date plus
30 days, you write:
MyDate:=Current date+30
4th Dimension creates MyDate and holds the date you need. The line of code reads
“MyDate gets the current date plus 30 days.” You could now use MyDate wherever you
need it in your database. For example, you might need to store the date variable in a field
of same type:
[MyTable]MyField:=MyDate
Sometimes you may want a variable to be explicitly defined as a certain type. For more
information about typing variables for a database that you intend to compile, see the
section Compiler Commands.
Data can be put into and copied out of variables. Putting data into a variable is called
assigning the data to the variable and is done with the assignment operator (:=). The
assignment operator is also used to assign data to fields.
The assignment operator is the primary way to create a variable and to put data into it.
You write the name of the variable that you want to create on the left side of the
assignment operator. For example:
MyNumber:=3
creates the variable MyNumber and puts the number 3 into it. If MyNumber already exists,
then the number 3 is just put into it.
Of course, variables would not be very useful if you could not get data out of them. Once
again, you use the assignment operator. If you need to put the value of MyNumber in a
field called [Products]Size, you would write MyNumber on the right side of the assignment
operator:
[Products]Size:=MyNumber
In this case, [Products]Size would be equal to 3. This example is rather simple, but it
illustrates the fundamental way that data is transferred from one place to another by
using the language.
You can create three types of variables: local variables, process variables, and interprocess
variables. The difference between the three types of variables is their scope, or the objects
to which they are available.
Local variables
A local variable is, as its name implies, local to a method—accessible only within the
method in which it was created and not accessible outside of that method. Being local to
a method is formally referred to as being “local in scope.” Local variables are used to
restrict a variable so that it works only within the method.
The name of a local variable always starts with a dollar sign ($) and can contain up to 31
additional characters. If you enter a longer name, 4th Dimension truncates it to the
appropriate length.
When you are working in a database with many methods and variables, you often find
that you need to use a variable only within the method on which you are working. You
can create and use a local variable in the method without worrying about whether you
have used the same variable name somewhere else.
Frequently, in a database, small pieces of information are needed from the user. The
Request command can obtain this information. It displays a dialog box with a message
prompting the user for a response. When the user enters the response, the command
returns the information the user entered. You usually do not need to keep this
information in your methods for very long. This is a typical way to use a local variable.
Here is an example:
$vsID:=Request("Please enter your ID:")
If (OK=1)
QUERY ([People];[People]ID =$vsID)
End if
This method simply asks the user to enter an ID. It puts the response into a local variable,
$vsID, and then searches for the ID that the user entered. When this method finishes, the
$vsID local variable is erased from memory. This is fine, because the variable is needed
only once and only in this method.
A process variable does not have a prefix before its name. A process variable name can
contain up to 31 characters.
In interpreted mode, variables are maintained dynamically, they are created and erased
from memory “on the fly.” In compiled mode, all processes you create (user processes)
share the same definition of process variables, but each process has a different instance for
each variable. For example, the variable myVar is one variable in the process P_1 and
another one in the process P_2.
Starting with version 6, a process can “peek and poke” process variables from another
process using the commands GET PROCESS VARIABLE and SET PROCESS VARIABLE. It is
good programming practice to restrict the use of these commands to the situation for
which they were added to 4D:
• Interprocess communication at specific places or your code
• Handling of interprocess drag and drop
• In Client/Server, communication between processes on client machines and the stored
procedures running on the server machines
For more information, see the section Processes and the description of these commands.
Interprocess variables
Interprocess variables are available throughout the database and are shared by all
processes. They are primarily used to share information between processes.
The name of an interprocess variable always begins with the symbols (<>) — a “less than”
sign followed by a “greater than” sign— followed by 31 characters.
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
In Client/Server, each machine (Client machines and Server machine) share the same
definition of interprocess variables, but each machine has a different instance for each
variable.
In the Form editor, naming an active object—button, radio button, check box, scrollable
area, meter bar, and so on—automatically creates a variable with the same name. For
example, if you create a button named MyButton, a variable named MyButton is also
created. Note that this variable name is not the label for the button, but is the name of
the button.
The form object variables allow you to control and monitor the objects. For example,
when a button is clicked, its variable is set to 1; at all other times, it is 0. The variable
associated with a meter or dial lets you read and change the current setting. For example,
if you drag a meter to a new setting, the value of the variable changes to reflect the new
setting. Similarly, if a method changes the value of the variable, the meter is redrawn to
show the new value.
For more information about variables and forms, see the 4th Dimension Design Reference
Manual as well as the section Form event.
System Variables
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension maintains a number of variables called system variables. These variables
let you monitor many operations. System variables are all process variables, accessible only
from within a process.
The most important system variable is the OK system variable. As its name implies, it tells
you if everything is OK in the particular process. Was the record saved? Has the importing
operation been completed? Did the user click the OK button? The OK system variable is
set to 1 when a task is completed successfully, and to 0 when it is not.
For more information about system variables, see the section System Variables.
See Also
Arrays, Constants, Control Flow, Data Types, Identifiers, Methods, Operators, Pointers.
4th Dimension manages system variables, which allow you to control the execution of
different operations. All system variables are process variables that can only be accessed
within one process. This section describes 4th Dimension system variables.
OK
This is the most commonly used system variable. Usually it is set to 1 when an operation
is successfully executed. It is set to 0 when the operation fails. The following commands
modify the value of the OK system variable:
ACCEPT ADD RECORD
ADD SUBRECORD APPEND TO CLIPBOARD
Append document APPLY TO SELECTION
ARRAY TO LIST ARRAY TO SELECTION
ARRAY TO STRING LIST BLOB TO DOCUMENT
BLOB TO PICTURE CALL WEB SERVICE
CANCEL CHANGE ACCESS
CLOSE XML COMPRESS BLOB
CONFIRM Count XML attributes
Count XML elements Create document
Create resource file DELETE DOCUMENT
DELETE RESOURCE DIALOG
DISTINCT VALUES DOCUMENT TO BLOB
EXECUTE ON CLIENT EXPAND BLOB
EXPORT DATA EXPORT DIF
EXPORT SYLK EXPORT TEXT
Get current printer Get First XML element
GET ICON RESOURCE Get indexed string
Get Next XML element GET PICTURE FROM LIBRARY
GET PICTURE RESOURCE GET PRINT OPTION
GET REGISTERED CLIENTS GET RESOURCE
Get string resource Get text from clipboard
Get text resource GET XML ATTRIBUTE BY INDEX
GET XML ATTRIBUTE BY NAME Get XML element
GET XML ELEMENT VALUE GET XML ERROR
IMPORT DATA IMPORT DIF
IMPORT SYLK IMPORT TEXT
LOAD SET LOAD VARIABLES
MODIFY RECORD MODIFY SUBRECORD
Open document Open resource file
ORDER BY ORDER BY FORMULA
Parse XML source Parse XML variable
PICTURE TO GIF PICTURE TO BLOB
PLAY PRINTERS LIST
PRINT LABEL PRINT SELECTION
Document
Document contains either the "long name" (access path+name) or the name (depending
on the value passed as parameter) of the last file opened or created using the following
commands:
Append document LOAD SET
Create document Create resource file
SAVE VARIABLES EXPORT DATA
EXPORT TEXT EXPORT DIF
EXPORT SYLK READ PICTURE FILE
REPORT SELECT LOG FILE
PRINT LABEL IMPORT DATA
IMPORT TEXT IMPORT DIF
IMPORT SYLK LOAD VARIABLES
Open document Open resource file
SAVE SET SET CHANNEL
USE ASCII MAP WRITE PICTURE FILE
FldDelimit
FldDelimit contains the ASCII code that will be used as a field separator when importing or
exporting text. By default, this value is set to 9, which is the ASCII code for the Tab key.
To use a different field separator, assign a new value to FldDelimit.
RecDelimit
RecDelimit contains the ASCII code that will be used as a record separator when importing
or exporting text. By default, this value is set to 13, which is the ASCII code for the
Carriage Return key. To use a different record separator, assign a new value to RecDelimit.
Error
See Also
Sets, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
When you use the language, you access various objects—in particular, tables, fields,
variables, and arrays—by simply using their names. However, it is often useful to refer to
these elements and access them without knowing their names. This is what pointers let
you do.
The concept behind pointers is not that uncommon in everyday life. You often refer to
something without knowing its exact identity. For example, you might say to a friend,
“Let’s go for a ride in your car” instead of “Let’s go for a ride in the car with license plate
123ABD.” In this case, you are referencing the car with license plate 123ABD by using the
phrase “your car.” The phrase “car with license plate 123ABD” is like the name of an
object, and using the phrase “your car” is like using a pointer to reference the object.
Being able to refer to something without knowing its exact identity is very useful. In fact,
your friend could get a new car, and the phrase “your car” would still be accurate—it
would still be a car and you could still take a ride in it. Pointers work the same way. For
example, a pointer could at one time refer to a numeric field called Age, and later refer to
a numeric variable called Old Age. In both cases, the pointer references numeric data that
could be used in a calculation.
You can use pointers to reference tables, fields, variables, arrays, and array elements. The
following table gives an example of each data type:
It is easiest to explain the use of pointers through an example. This example shows how
to access a variable through a pointer. We start by creating a variable:
MyVar:="Hello"
MyVar is now a variable containing the string “Hello.” We can now create a pointer to
MyVar:
MyPointer:=->MyVar
The -> symbol means “get a pointer to.” This symbol is formed by a dash followed by a
“greater than” sign. In this case, it gets the pointer that references or “points to” MyVar.
This pointer is assigned to MyPointer with the assignment operator.
MyPointer is now a variable that contains a pointer to MyVar. MyPointer does not contain
“Hello”, which is the value in MyVar, but you can use MyPointer to get this value. The
following expression returns the value in MyVar:
MyPointer->
In this case, it returns the string “Hello”. The -> symbol, when it follows a pointer,
references the object pointed to. This is called dereferencing.
It is important to understand that you can use a pointer followed by the -> symbol
anywhere that you could have used the object that the pointer points to. This means that
you could use the expression MyPointer-> anywhere that you could use the original MyVar
variable.
For example, the following line displays an alert box with the word Hello in it:
ALERT(MyPointer->)
You can also use MyPointer to change the data in MyVar. For example, the following
statement stores the string "Goodbye" in the variable MyVar:
MyPointer->:="Goodbye"
If you examine the two uses of the expression MyPointer->, you will see that it acts just as
if you had used MyVar instead. In summary, the following two lines perform the same
action—both display an alert box containing the current value in the variable MyVar:
ALERT(MyPointer->)
ALERT(MyVar)
This section describes how to use a pointer to reference a button. A button is (from the
language point of view) nothing more than a variable. Although the examples in this
section use pointers to reference buttons, the concepts presented here apply to the use of
all types of objects that can be referenced by a pointer.
Let’s say that you have a number of buttons in your forms that need to be enabled or
disabled. Each button has a condition associated with it that is TRUE or FALSE. The
condition says whether to disable or enable the button. You could use a test like this each
time you need to enable or disable the button:
If (Condition) ` If the condition is TRUE…
ENABLE BUTTON (MyButton) ` enable the button
Else ` Otherwise…
DISABLE BUTTON (MyButton) ` disable the button
End if
You would need to use a similar test for every button you set, with only the name of the
button changing. To be more efficient, you could use a pointer to reference each button
and then use a subroutine for the test itself.
You must use pointers if you use a subroutine, because you cannot refer to the button’s
variables in any other way. For example, here is a project method called SET BUTTON,
which references a button with a pointer:
` SET BUTTON project method
` SET BUTTON ( Pointer ; Boolean )
` SET BUTTON ( -> Button ; Enable or Disable )
`
` $1 – Pointer to a button
` $2 – Boolean. If TRUE, enable the button. If FALSE, disable the button
Anywhere that the language expects to see a table, you can use a dereferenced pointer to
the table.
You create a pointer to a table by using a line like this:
TablePtr:=->[anyTable]
You can also get a pointer to a table by using the Table command. For example:
TablePtr:=Table(20)
Anywhere that the language expects to see a field, you can use a dereferenced pointer to
reference the field. You create a pointer to a field by using a line like this:
FieldPtr:=->[aTable]ThisField
You can also get a pointer to a field by using the Field command. For example:
FieldPtr:=Field(1; 2)
You can create a pointer to an array element. For example, the following lines create an
array and assign a pointer to the first array element to a variable called ElemPtr:
ARRAY REAL(anArray; 10) ` Create an array
ElemPtr:=->anArray{1} ` Create a pointer to the array element
You could use the dereferenced pointer to assign a value to the element, like this:
ElemPtr->:=8
You can create a pointer to an array. For example, the following lines create an array and
assign a pointer to the array to a variable called ArrPtr:
ARRAY REAL(anArray; 10) ` Create an array
ArrPtr := ->anArray ` Create a pointer to the array
It is important to understand that the pointer points to the array; it does not point to an
element of the array. For example, you can use the dereferenced pointer from the
preceding lines like this:
SORT ARRAY(ArrPtr->; >) ` Sort the array
If you need to refer to the fourth element in the array by using the pointer, you do this:
ArrPtr->{4} := 84
It is often useful to have an array of pointers that reference a group of related objects.
One example of such a group of objects is a grid of variables in a form. Each variable in
the grid is sequentially numbered, for example: Var1,Var2,…, Var10. You often need to
reference these variables indirectly with a number. If you create an array of pointers, and
initialize the pointers to point to each variable, you can then easily reference the
variables. For example, to create an array and initialize each element, you could use the
following lines:
ARRAY POINTER(apPointers; 10) ` Create an array to hold 10 pointers
For ($i; 1; 10) ` Loop once for each variable
apPointers{$i}:=Get pointer("Var"+String($i)) ` Initialize the array element
End for
To reference any of the variables, you use the array elements. For example, to fill the
variables with the next ten dates (assuming they are variables of the date type), you could
use the following lines:
For ($i; 1; 10) ` Loop once for each variable
apPointers{$i}->:=Current date+$i ` Assign the dates
End for
If you have a group of related radio buttons in a form, you often need to set them
quickly. It is inefficient to directly reference each one of them by name. Let’s say you
have a group of radio buttons named Button1, Button2,…, Button5.
In a group of radio buttons, only one radio button is on. The number of the radio button
that is on can be stored in a numeric field. For example, if the field called
[Preferences]Setting contains 3, then Button3 is selected. In your form method, you could
use the following code to set the button:
Case of
:(Form event=On Load)
` ...
Case of
: ([Preferences]Setting = 1)
Button1:=1
: ([Preferences]Setting = 2)
Button2:=1
: ([Preferences]Setting = 3)
Button3:=1
: ([Preferences]Setting = 4)
Button4:=1
: ([Preferences]Setting = 5)
Button5:=1
End case
` ...
End case
The number of the set radio button must be stored in the field called [Preferences]Setting.
You can do so in the form method for the On Clicked event:
[Preferences]Setting:=Button1+(Button2*2)+(Button3*3)+(Button4*4)+(Button5*5)
You can pass a pointer as a parameter to a method. Inside the method, you can modify
the object referenced by the pointer. For example, the following method, TAKE TWO,
takes two parameters that are pointers. It changes the object referenced by the first
parameter to uppercase characters, and the object referenced by the second parameter to
lowercase characters. Here is the method:
` TAKE TWO project method
` $1 – Pointer to a string field or variable. Change this to uppercase.
` $2 – Pointer to a string field or variable. Change this to lowercase.
$1->:=Uppercase($1->)
$2->:=Lowercase($2->)
The following line uses the TAKE TWO method to change a field to uppercase characters
and to change a variable to lowercase characters:
TAKE TWO (->[My Table]My Field; ->MyVar)
If the field [My Table]My Field contained the string "jones", it would be changed to the
string "JONES". If the variable MyVar contained the string "HELLO", it would be changed to
the string "hello".
Pointers to Pointers
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
If you really like to complicate things, you can use pointers to reference other pointers.
Consider this example:
MyVar := "Hello"
PointerOne := ->MyVar
PointerTwo := ->PointerOne
(PointerTwo->)-> := "Goodbye"
ALERT((Point Two->)->)
• MyVar:="Hello"
→ This line puts the string "Hello" into the variable MyVar.
• PointerOne:=->MyVar
→ PointerOne now contains a pointer to MyVar.
• PointerTwo:=->PointerOne
→ PointerTwo (a new variable) contains a pointer to PointerOne, which in turn points to
MyVar.
• (PointerTwo->)->:="Goodbye"
→ PointerTwo-> references the contents of PointerOne, which in turn references MyVar.
Therefore (PointerTwo->)-> references the contents of MyVar. So in this case, MyVar is
assigned "Goodbye".
• ALERT ((PointerTwo->)->)
→ Same thing: PointerTwo-> references the contents of PointerOne, which in turn
references MyVar. Therefore (PointerTwo->)-> references the contents of MyVar. So in this
case, the alert box displays the contents of myVar.
See Also
Arrays, Arrays and Pointers, Constants, Control Flow, Data Types, Identifiers, Methods,
Operators, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
This section describes the conventions for naming various objects in the 4th Dimension
language. The names for all objects follow these rules:
• A name must begin with an alphabetic character.
• Thereafter, the name can include alphabetic characters, numeric characters, the space
character, and the underscore character.
• Periods, slashes, and colons are not allowed.
• Characters reserved for use as operators, such as * and +, are not allowed.
• 4th Dimension ignores any trailing spaces.
Tables
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a table by placing its name between brackets: [...]. A table name can contain
up to 31 characters.
Examples
DEFAULT TABLE ([Orders])
INPUT FORM ([Clients]; "Entry")
ADD RECORD ([Letters])
Fields
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a field by first specifying the table to which the field belongs. The field name
immediately follows the table name. A field name can contain up to 31 characters.
Do not start a field name with the underscore character (_). The underscore character is
reserved for plug-ins. When 4th Dimension encounters this character at the beginning of
a field in the Method editor, it removes the underscore.
Examples
[Orders]Total:=Sum([Line]Amount)
QUERY([Clients];[Clients]Name="Smith")
[Letters]Text:=Capitalize text ([Letters]Text)
It is a good programming technique to specify the table name before the field, even
though it is not absolutely necessary in a table, form, or object method.
You denote a subtable by first specifying the parent table to which the subtable belongs.
The subtable name immediately follows the table name. A subtable name can contain up
to 31 characters.
Examples
ALL SUBRECORDS ([People]Children)
ADD SUBRECORD ([Clients]Phones;"Add One")
NEXT SUBRECORD ([Letters]Keywords)
A subtable is treated as a type of field; therefore, it follows the same rules as a field when
used in a form. If you are specifying a subtable in the table, form, or object method of the
parent table, you do not need to specify the parent table name. However, it is a good
programming technique to specify the name of the table before the subtable name.
Subfields
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a subfield in the same way as a field. You denote the subfield by first
specifying the subtable to which the subfield belongs. The subfield name follows, and is
separated from the subtable name by an apostrophe ('). A subfield name can contain up to
31 characters.
Examples
[People]Children'First Name:=Uppercase([People]Children'First Name)
[Clients]Phones'Number:="408 555–1212"
[Letters]Keywords'Word:=Capitalize text ([Letters]Keywords'Word)
If you are specifying a subfield in a subtable, form, or object method of the subfile, you
do not need to specify the subtable name. However it is a good programming technique
to specify the table name and the subtable name before the name of the subfield.
Interprocess Variables
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote an interprocess variable by preceding the name of the variable with the
symbols (<>) — a “less than” sign followed by a “greater than” sign.
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
An interprocess variable can have up to 31 characters, not including the <> symbols.
Process Variables
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a process variable by using its name (which cannot start with the <> symbols
nor the dollar sign $). A process variable name can contain up to 31 characters.
Examples
<>vrGrandTotal:=Sum([Accounts]Amount)
If (bValidate=1)
vsCurrentName:=""
Local Variables
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a local variable with a dollar sign ($) followed by its name. A local variable
name can contain up to 31 characters, not including the dollar sign.
Examples
For ($vlRecord; 1; 100)
If ($vsTempVar="No")
$vsMyString:="Hello there"
Arrays
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote an array by using its name, which is the name you passed to the array
declaration (such as ARRAY LONGINT) when you created the array. Arrays are variables,
and from the scope point of view, like variables, there are three different types of arrays:
• Interprocess arrays,
• Process arrays,
• Local arrays.
Interprocess Arrays
The name of an interprocess array is preceded by the symbols (<>) — a “less than” sign
followed by a “greater than” sign.
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
Examples
ARRAY TEXT(<>atSubjects;Records in table([Topics]))
SORT ARRAY (<>asKeywords; >)
ARRAY INTEGER(<>aiBigArray;10000)
Process Arrays
You denote a process array by using its name (which cannot start with the <> symbols
nor the dollar sign $). A process array name can contain up to 31 characters.
Examples
ARRAY TEXT(atSubjects;Records in table([Topics]))
SORT ARRAY (asKeywords; >)
ARRAY INTEGER(aiBigArray;10000)
Local Arrays
The name of a local array is preceded by the dollar sign ($). An local array name can
contain up to 31 characters, not including the dollar sign.
Examples
ARRAY TEXT($atSubjects;Records in table([Topics]))
SORT ARRAY ($asKeywords; >)
ARRAY INTEGER($aiBigArray;10000)
Elements of arrays
You reference an element of an interprocess, process or local array by using the curly
braces({…}). The element referenced is denoted by a numeric expression.
Examples
` Addressing an element of an interprocess array
If (<>asKeywords{1}="Stop")
<>atSubjects{$vlElem}:=[Topics]Subject
$viNextValue:=<>aiBigArray{Size of array(<>aiBigArray)}
Examples
` Addressing an element of a two-dimensional interprocess array
If (<>asKeywords{$vlNextRow}{1}="Stop")
<>atSubjects{10}{$vlElem}:=[Topics]Subject
$viNextValue:=<>aiBigArray{$vlSet}{Size of array(<>aiBigArray{$vlSet})}
Forms
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You denote a form by using a string expression that represents its name. A form name
can contain up to 31 characters.
Examples
INPUT FORM([People];"Input")
OUTPUT FORM([People]; "Output")
DIALOG([Storage];"Note box"+String($vlStage))
You denote a method (procedure and function) by using its name. A method name can
contain up to 31 characters.
Note: A method that does not return a result is also called a procedure. A method that
returns is a result is also called a function.
Examples
If (New client)
DELETE DUPLICATED VALUES
APPLY TO SELECTION ([Employees];INCREASE SALARIES)
Tip: It is a good programming technique to adopt the same naming convention as the
one used by 4D for built-in commands. Use uppercase characters for naming your
methods; however if a method is function, capitalize the first character of its name. By
doing so, when you reopen a database for maintenance after a few months, you will
already know if a method returns a result by simply looking at its name in the Explorer
window.
Note: When you call a method, you just type its name. However, some 4D built-in
commands, such as ON EVENT CALL, as well as all the Plug-In commands, expect the
name of a method as a string when a method parameter is passed. Example:
Examples
` This command expects a method (function) or formula
QUERY BY FORMULA ([aTable];Special query)
` This command expects a method (procedure) or statement
APPLY TO SELECTION ([Employees];INCREASE SALARIES)
` But this command expects a method name
ON EVENT CALL ("HANDLE EVENTS")
` And this Plug-In command expects a method name
WR ON ERROR ("WR HANDLE ERRORS")
Methods can accept parameters (arguments). The parameters are passed to the method in
parentheses, following the name of the method. Each parameter is separated from the
next by a semicolon (;). The parameters are available within the called method as
consecutively numbered local variables: $1, $2,…, $n. In addition, multiple consecutive
(and last) parameters can be addressed with the syntax ${n}where n, numeric expression,
is the number of the parameter.
` Within Dump:
` - The three parameters are text or string
` - They can be addressed as $1, $2 or $3
` - They can also be addressed as, for instance,
` ${$vlParam} where $vlParam is 1, 2 or 3
` - The result value is assigned to $0
vtClone:=Dump ("is"; "the"; "it")
You denote a plug-in command by using its name as defined by the plug-in. A plug-in
command name can contain up to 31 characters.
Examples
WR BACKSPACE (wrArea; 0)
$spNewArea:=SP New offscreen area
From the scope point of view, there are two types of sets:
• Interprocess sets
• Process sets
4D Server also includes:
• Client sets
Interprocess Sets
A set is an interprocess set if the name of the set is preceded symbols (<>) — a “less than”
sign followed by a “greater than” sign.
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
An interprocess set name can contain up to 80 characters, not including the <> symbols.
Process Sets
You denote a process set by using a string expression that represents its name (which
cannot start with the <> symbols or the dollar sign $). A set name can contain up to 80
characters.
Client Sets
The name of a client set is preceded by the dollar sign ($). A client set name can contain
up to 80 characters, not including the dollar sign.
Examples
` Interprocess sets
USE SET("<>Deleted Records")
CREATE SET([Customers];"<>Customer Orders")
If (Records in set("<>Selection"+String($i))>0)
` Process sets
USE SET("Deleted Records")
CREATE SET([Customers];"Customer Orders")
If (Records in set("<>Selection"+String($i))>0)
` Client sets
USE SET("$Deleted Records")
CREATE SET([Customers];"$Customer Orders")
If (Records in set("$Selection"+String($i))>0)
From the scope point of view, there are two types of named selections:
• Interprocess named selections
• Process named selections
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
An interprocess named selection name can contain up to 80 characters, not including the
<> symbols.
Examples
` Interprocess Named Selection
USE NAMED SELECTION([Customers];"<>ByZipcode")
` Process Named Selection
USE NAMED SELECTION([Customers];"<>ByZipcode")
Processes
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In the single-user version, or in Client/Server on the Client side, there are two types of
processes:
• Global processes
• Local processes
Global Processes
You denote a global process by using a string expression that represents its name (which
cannot start with the dollar sign $). A process name can contain up to 31 characters.
Local Processes
You denote a local process if the name of the process is preceded by a dollar ($) sign. The
process name can contain up to 31 characters, not including the dollar sign.
If a particular object has the same name as another object of a different type (for
example, if a field is named Person and a variable is also named Person), 4th Dimension
uses a priority system to identify the object. It is up to you to ensure that you use unique
names for the parts of your database.
1. Fields
2. Commands
3. Methods
4. Plug-in routines
5. Predefined constants
6. Variables
For example, 4th Dimension has a built-in command called Date. If you named a method
Date, 4th Dimension would recognize it as the built-in Date command, and not as your
method. This would prevent you from calling your method. If, however, you named a
field “Date”, 4th Dimension would try to use your field instead of the Date command.
See Also
Arrays, Constants, Data Types, Methods, Operators, Pointers, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Regardless of the simplicity or complexity of a method, you will always use one or more
of three types of programming structures. Programming structures control the flow of
execution, whether and in what order statements are executed within a method. There
are three types of structures:
• Sequential
• Branching
• Looping
The 4th Dimension language contains statements that control each of these structures.
Sequential structure
The sequential structure is a simple, linear structure. A sequence is a series of statements
that 4th Dimension executes one after the other, from first to last. For example:
OUTPUT FORM([People]; "Listing")
ALL RECORDS([People])
DISPLAY SELECTION([People])
A one-line routine, frequently used for object methods, is the simplest case of a sequential
structure. For example:
[People]Last Name:=Uppercase([People]Last Name)
Branching structures
A branching structure allows methods to test a condition and take alternative paths,
depending on the result. The condition is a Boolean expression, an expression that
evaluates TRUE or FALSE. One branching structure is the If...Else...End if structure, which
directs program flow along one of two paths. The other branching structure is the Case
of...Else...End case structure, which directs program flow to one of many paths.
The loops are controlled in two ways: either they loop until a condition is met, or they
loop a specified number of times. Each looping structure can be used in either way, but
While loops and Repeat loops are more appropriate for repeating until a condition is met,
and For loops are more appropriate for looping a specified number of times.
Note: 4th Dimension allows you to embed programming structures (If/While/For/Case
of/Repeat) up to a "depth" of 512 levels.
See Also
Logical Operators, Methods.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The If...Else...End if structure lets your method choose between two actions, depending on
whether a test (a Boolean expression) is TRUE or FALSE.
When the Boolean expression is TRUE, the statements immediately following the test are
executed. If the Boolean expression is FALSE, the statements following the Else statement
are executed. The Else statement is optional; if you omit Else, execution continues with
the first statement (if any) following the End if.
Example
` Ask the user to enter the name
$Find:=Request(“Type a name:”)
If (OK=1)
QUERY([People]; [People]LastName=$Find)
Else
ALERT("You did not enter a name.")
End if
or:
If (Boolean_Expression)
statements(s)
Else
End if
See Also
Case of...Else...End case, Control Flow, For...End for, Repeat...Until, While...End while.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The formal syntax of the Case of...Else...End case control flow structure is:
Case of
: (Boolean_Expression)
statement(s)
: (Boolean_Expression)
statement(s)
.
.
.
: (Boolean_Expression)
statement(s)
Else
statement(s)
End case
: (Boolean_Expression)
statement(s)
End case
As with the If...Else...End if structure, the Case of...Else...End case structure also lets your
method choose between alternative actions. Unlike the If...Else...End if structure, the Case
of...Else...End case structure can test a reasonable unlimited number of Boolean expressions
and take action depending on which one is TRUE.
Only the statements following the first TRUE case (and up to the next case) will be
executed. If none of the cases are TRUE, none of the statements will be executed (if no
Else part is included).
You can include an Else statement after the last case. If all of the cases are FALSE, the
statements following the Else will be executed.
Example
This example tests a numeric variable and displays an alert box with a word in it:
Case of
: (vResult = 1) ` Test if the number is 1
ALERT("One.") ` If it is 1, display an alert
: (vResult = 2) ` Test if the number is 2
ALERT("Two.") ` If it is 2, display an alert
: (vResult = 3) ` Test if the number is 3
ALERT("Three.") ` If it is 3, display an alert
Else ` If it is not 1, 2, or 3, display an alert
ALERT("It was not one, two, or three.")
End case
Remember that with a Case of...Else...End case structure, only the first TRUE case is
executed. Even if two or more cases are TRUE, only the statements following the first
TRUE case will be executed.
Case of
: (vResult = 1)
... `statement(s)
: ((vResult = 1) & (vCondition#2)) `this case will never be detected
... `statement(s)
End case
.
In the code above, the presence of the second condition is not detected since the test
"vResult=1" branches off the code before any further testing. For the code to operate
properly, you can write it as follows:
Case of
: ((vResult = 1) & (vCondition#2)) `this case will be detected first
... `statement(s)
: (vResult = 1)
... `statement(s)
End case
.
Also, if you want to implement hierarchical testing, you may consider using hierarchical
code.
.
.
.
: (Boolean_Expression)
statement(s)
Else
statement(s)
End case
: (Boolean_Expression)
statement(s)
Else
End case
or:
Case of
Else
statement(s)
End case
See Also
Control Flow, For...End for, If...Else...End if, Repeat...Until, While...End while.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The formal syntax of the While...End while control flow structure is:
While (Boolean_Expression)
statement(s)
End while
A While...End while loop executes the statements inside the loop as long as the Boolean
expression is TRUE. It tests the Boolean expression at the beginning of the loop and does
not enter the loop at all if the expression is FALSE.
It is common to initialize the value tested in the Boolean expression immediately before
entering the While...End while loop. Initializing the value means setting it to something
appropriate, usually so that the Boolean expression will be TRUE and While...End while
executes the loop.
The Boolean expression must be set by something inside the loop or else the loop will
continue forever. The following loop continues forever because NeverStop is always TRUE:
NeverStop:=True
While (NeverStop)
End while
If you find yourself in such a situation, where a method is executing uncontrolled, you
can use the trace facilities to stop the loop and track down the problem. For more
information about tracing a method, see the section Debugging.
Example
CONFIRM ("Add a new record?") ` The user wants to add a record?
While (OK = 1) ` Loop as long as the user wants to
ADD RECORD([aTable]) ` Add a new record
End while ` The loop always ends with End while
In this example, the OK system variable is set by the CONFIRM command before the loop
starts. If the user clicks the OK button in the confirmation dialog box, the OK system
variable is set to 1 and the loop starts. Otherwise, the OK system variable is set to 0 and
the loop is skipped. Once the loop starts, the ADD RECORD command keeps the loop
going because it sets the OK system variable to 1 when the user saves the record. When
the user cancels (does not save) the last record, the OK system variable is set to 0 and the
loop stops.
See Also
Case of...Else...End case, Control Flow, For...End for, If...Else...End if, Repeat...Until.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A Repeat...Until loop is similar to a While...End while loop, except that it tests the Boolean
expression after the loop rather than before. Thus, a Repeat...Until loop always executes
the loop once, whereas if the Boolean expression is initially False, a While...End while loop
does not execute the loop at all.
The other difference with a Repeat...Until loop is that the loop continues until the Boolean
expression is TRUE.
Example
Compare the following example with the example for the While...End while loop. Note
that the Boolean expression does not need to be initialized—there is no CONFIRM
command to initialize the OK variable.
Repeat
ADD RECORD([aTable])
Until (OK=0)
See Also
Case of...Else...End case, Control Flow, For...End for, If...Else...End if, While...End while.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The formal syntax of the For...End for control flow structure is:
For (Counter_Variable; Start_Expression; End_Expression {; Increment_Expression})
statement(s)
End for
Tip: However, for special purposes, you can change the value of the counter variable
Counter_Variable within the loop; this will affect the loop.
Basic Examples
1. The following example executes 100 iterations:
For (vCounter;1;100)
` Do something
End for
2. The following example goes through all elements of the array anArray:
For ($vlElem;1;Size of array(anArray))
` Do something with the element
anArray{$vlElem}:=...
End for
4. The following example goes through the selected records for the table [aTable]:
FIRST RECORD([aTable])
For ($vlRecord;1;Records in selection([aTable]))
` Do something with the record
SEND RECORD([aTable])
` ...
` Go to the next record
NEXT RECORD([aTable])
End for
Most of the For...End for loops you will write in your databases will look like the ones
listed in these examples.
6. The following example goes through all elements of the array anArray:
For ($vlElem;Size of array(anArray);1;-1)
` Do something with the element
anArray{$vlElem}:=...
End for
8. The following example goes through the selected records for the table [aTable]:
LAST RECORD([aTable])
For ($vlRecord;Records in selection([aTable]);1;-1)
` Do something with the record
SEND RECORD([aTable])
` ...
` Go to the previous record
PREVIOUS RECORD([aTable])
End for
9. The following loop addresses only the even elements of the array anArray:
For ($vlElem;2;((Size of array(anArray)+1)\2)*2;2)
` Do something with the element #2,#4...#2n
anArray{$vlElem}:=...
End for
Note that the ending expression ((Size of array(anArray)+1)\2)*2 takes care of even and
odd array sizes.
10. In the following example, a selection of the records is browsed until this is actually
done or until the interprocess variable <>vbWeStop, intially set to FALSE, becomes TRUE.
This variable is handled by an ON EVENT CALL project method that allows you to interrupt
the operation:
<>vbWeStop:=False
ON EVENT CALL ("HANDLE STOP")
` HANDLE STOP sets <>vbWeStop to True if Ctrl-period (Windows) or Cmd-Period
(Macintosh) is pressed
$vlNbRecords:=Records in selection([aTable])
FIRST RECORD([aTable])
For ($vlRecord;1;$vlNbRecords)
` Do something with the record
SEND RECORD([aTable])
` ...
` Go to the next record
If (<>vbWeStop)
$vlRecord:=$vlNbRecords+1 ` Force the counter variable to get out of the loop
Else
NEXT RECORD([aTable])
End if
End for
ON EVENT CALL("")
If (<>vbWeStop)
ALERT("The operation has been interrupted.")
Else
ALERT("The operation has been successfully completed.")
End if
It is interesting to see how the While...End while loop and Repeat...Until loop would
perform the same action.
Tip: The For...End for loop is usually faster than the While...End while and Repeat...Until
loops, because 4th Dimension tests the condition internally for each cycle of the loop and
increments the counter. Therefore, use the For...End for loop whenever possible.
13. The following example builds an array of pointers to all the date fields present in the
database:
ARRAY POINTER($apDateFields;0)
$vlElem:=0
For ($vlTable;1;Count table)
For($vlField;1;Count fields($vlTable))
$vpField:=Field($vlTable;$vlField)
If (Type($vpField->)=Is Date)
$vlElem:=$vlElem+1
INSERT ELEMENT($apDateFields;$vlElem)
$apDateFields{$vlElem}:=$vpField
End if
End for
End for
See Also
Case of...Else...End case, Control Flow, If...Else...End if, Repeat...Until, While...End while.
In order to make the commands, operators, and other parts of the language work, you
put them in methods. There are several kinds of methods: Object methods, Form
methods, Table methods (Triggers), Project methods, and Database methods. This section
describes features common to all types of methods.
A method is composed of statements; each statement consists of one line in the method.
A statement performs an action, and may be simple or complex. Although a statement is
always one line, that one line can be as long as needed (up to 32,000 characters, which is
probably enough for most tasks).
For example, the following line is a statement that will add a new record to the [People]
table:
ADD RECORD([People])
A method also contains tests and loops that control the flow of the execution. For a
detailed discussion about the control flow programming structures, see the section Control
Flow.
Note: The maximum size of a method is limited to 2 GB of text or 32 000 lines of
command. Beyond these limits, a warning message appears, indicating that the extra lines
will not be displayed.
Types of Methods
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
• Project methods: Unlike object methods, form methods, and triggers, which are all
associated with a particular object, form, or table, project methods are available for use
throughout your database. Project methods are reusable, and available for use by any
other method. If you need to repeat a task, you do not have to write identical methods
for each case. You can call project methods wherever you need them—from other project
methods or from object or form methods. When you call a project method, it acts as if
you had written the method at the location where you called it. Project methods called
from other method are often referred to as “subroutines.” A project method that returns a
result can also be called a function.
There is one other way to use project methods—associating them with menu commands.
When you associate a project method with a menu command, the method is executed
when the menu is chosen. You can think of the menu command as calling the project
method.
For detailed information about Project methods, see the section Project Methods.
• Database methods: In the same way object and form methods are invoked when events
occur in a form, there are methods associated with the database that are invoked when a
working session event occurs. These are the database methods. For example, each time
you open a database, you may want to initialize some variables that will be used during
the whole working session. To do so, you use the On Startup Database Method,
automatically executed by 4D when you open the database.
For more information about Database Methods, see the section Database Methods.
1. Version 6 introduces many new object and form events (such as On Double Clicked, On
Getting Focus, and so on) that replace the execution cycles from the previous versions. If
you have converted a version 3 database to version 6, your forms have been converted in
order to preserve as much as the “expected behavior” of your forms and objects. If you
want to take advantage of the new events for forms and objects created with a previous
version of 4D, you must enable the new events in the Form Properties and Object
Properties windows for the forms and the objects.
2. Table method, also called trigger, is a new type of method introduced in version 6. In
previous versions of 4th Dimension, table methods (called file procedures) were executed
by 4D only when a form for a table was used for data entry, display, or printing. They
were rarely used. Note that triggers execute at a much lower level that the old file
procedures. No matter what you do to a record via user actions (like data entry) or
programmatically (like a call to SAVE RECORD), the trigger of a table will be invoked by
4D. Triggers are truly quite different from the old file procedures. If you have converted a
version 3 database to version 6, and if you want to take advantage of the new Trigger
capability, you must deselect the Use Old File Procedures Scheme property in the
Preferences dialog box (shown in this section).
All methods are fundamentally the same—they start at the first line and work their way
through each statement until they reach the last line (i.e., they execute sequentially).
Here is an example project method:
QUERY ([People]) ` Display the Query editor
If (OK=1) ` The user clicked OK, not cancel
If (Records in selection([People])=0) ` If no record was found…
ADD RECORD([People]) ` Let the user add a new record
End if
End if ` The end
Each line in the example is a statement or line of code. Anything that you write using
the language is loosely referred to as code. Code is executed or run; this means that 4th
Dimension performs the task specified by the code.
The first element in the line, QUERY, is a command. A command is part of the 4th
Dimension language—it performs a task. In this case, QUERY displays the Query editor.
This is similar to choosing Query from the Queries menu in the User environment.
The second element in the line, specified between parantheses, is an argument to the
QUERY command. An argument (or parameter) is data required by a command in order
to complete its task. In this case, [People] is the name of a table. Table names are always
specified inside square brackets ([…]). In our example, the People table is an argument to
the QUERY command. A command can accept several parameters.
The third element is a comment at the end of the line. A comment tells you (and anyone
else who might read your code) what is happening in the code. It is indicated by the
reverse apostrophe (`). Anything (on the line) following the comment mark will be
ignored when the code is run. A comment can be put on a line by itself, or you can put
comments to the right of the code, as in the example. Use comments generously
throughout your code; this makes it easier for you and others to read and understand the
code.
The next line of the method checks to see if any records were found:
If (Records in selection([People]) = 0) ` If no record was found…
Note: Notice that only the first letter of the function name is capitalized. This is the
naming convention for 4th Dimension functions.
You should already know what the current selection is—it is the group of records you are
working on at any one time. If the number of records is equal to 0 (in other words, if no
record was found), then the following line is executed:
ADD RECORD([People]) ` Let the user add a new record
The ADD RECORD command displays a form so that the user can add a new record. 4th
Dimension formats your code automatically; notice that this line is indented to show you
that it is dependent on the control-of-flow statement (If).
End if ` The end
Be sure you feel comfortable with the concepts in this section. If they are all new, you
may want to review them until they are clear to you.
See Also
Arrays, Constants, Control Flow, Data Types, Database Methods, Identifiers, Operators,
Pointers, Triggers, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Project methods are aptly named. Whereas form and object methods are bound to forms
and objects, a project method is available anywhere; it is not specifically attached to any
particular object of the database. A project method can have one of the following roles,
depending on how it is executed and used:
• Menu method
• Subroutine and function
• Process method
• Event catching method
• Error catching method
These terms do not distinguish project methods by what they are, but by what they do.
A menu method is a project method called from a custom menu. It directs the flow of
your application. The menu method takes control—branching where needed, presenting
forms, generating reports, and generally managing your database.
The subroutine is a project method that can be thought of as a servant. It performs those
tasks that other methods request it to perform. A function is a subroutine that returns a
value to the method that called it.
A process method is a project method that is called when a process is started. The process
lasts only as long as the process method continues to execute. For more information
about processes, see the section Processes. Note that a menu method attached to a menu
command whose property Start a New Process is selected, is also the process method for
the newly started process.
An event catching method runs in a separate process as the process method for catching
events. Usually, you let 4D do most of the event handling for you. For example, during
data entry, 4D detects keystrokes and clicks, then calls the correct object and form
methods so you can respond appropriately to the events from within these methods. In
other circumstances, you may want to handle events directly. For example, if you run a
lengthy operation (such as For...End For loop browsing records), you may want to be able
to interrupt the operation by typing Ctrl-Period (Windows) or Cmd-Period (Macintosh).
In this case, you should use an event catching method to do so. For more information,
see the description of the command ON EVENT CALL.
A menu method is invoked in the Custom Menus environment when you select the
custom menu command to which it is attached. You assign the method to the menu
command using the Menu editor. The menu executes when the menu command is
chosen. This process is one of the major aspects of customizing a database. By creating
custom menus with menu methods that perform specific actions, you personalize your
database. Refer to the 4th Dimension Design Reference manual for more information about
the Menu editor.
Custom menu commands can cause one or more activities to take place. For example, a
menu command for entering records might call a method that performs two tasks:
displaying the appropriate input form, and calling the ADD RECORD command until the
user cancels the data entry activity.
Subroutines
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
When you create a project method, it becomes part of the language of the database in
which you create it. You can then call the project method in the same way that you call
4th Dimension’s built-in commands. A project method used in this way is called a
subroutine.
For example, let’s say you have a database of customers. As you customize the database,
you find that there are some tasks that you perform repeatedly, such as finding a
customer and modifying his or her record. The code to do this might look like this:
` Look for a customer
QUERY BY EXAMPLE([Customers])
` Select the input form
INPUT FORM([Customers];"Data Entry")
` Modify the customer's record
MODIFY RECORD([Customers])
If the previously described code was a method called MODIFY CUSTOMER, you would
execute it simply by using the name of the method in another method. For example, to
modify a customer’s record and then print the record, you would write this method:
MODIFY CUSTOMER
PRINT SELECTION([Customers])
This capability simplifies your methods dramatically. In the example, you do not need to
know how the MODIFY CUSTOMER method works, just what it does. This is the second
reason for using subroutines—to clarify your methods. In this way, your methods become
extensions to the 4th Dimension language.
If you need to change your method of finding customers in this example database, you
will need to change only one method, not ten. This is the next reason to use
subroutines—to facilitate changes to your methods.
Using subroutines, you make your code modular. This simply means dividing your code
into modules (subroutines), each of which performs a logical task. Consider the following
code from a checking account database:
FIND CLEARED CHECKS ` Find the cleared checks
RECONCILE ACCOUNT ` Reconcile the account
PRINT CHECK BOOK REPORT ` Print a checkbook report
Even for someone who doesn’t know the database, it is clear what this code does. It is not
necessary to examine each subroutine. Each subroutine might be many lines long and
perform some complex operations, but here it is only important that it performs its task.
We recommend that you divide your code into logical tasks, or modules, whenever
possible.
You’ll often find that you need to pass data to your methods. This is easily done with
parameters.
Parameters (or arguments) are pieces of data that a method needs in order to perform its
task. The terms parameter and argument are used interchangeably throughout this
manual. Parameters are also passed to built-in 4th Dimension commands. In this example,
the string “Hello” is an argument to the ALERT command:
ALERT("Hello")
Parameters are passed to methods in the same way. For example, if a method named DO
SOMETHING accepted three parameters, a call to the method might look like this:
DO SOMETHING(WithThis;AndThat;ThisWay)
In the subroutine (the method that is called), the value of each parameter is automatically
copied into sequentially numbered local variables: $1, $2, $3, and so on. The numbering
of the local variables represents the order of the parameters.
The local variables/parameters are not the actual fields, variables, or expressions passed by
the calling method; they only contain the values that have been passed.
Within the subroutine, you can use the parameters $1, $2... in the same way you would
use any other local variable.
Since they are local variables, they are available only within the subroutine and are cleared
at the end of the subroutine. For this reason, a subroutine cannot change the value of the
actual fields or variables passed as parameters at the calling method level. For example:
` Here is some code from the method MY METHOD
` ...
DO SOMETHING ([People]Last Name) ` Let's say [People]Last Name is equal to "williams"
ALERT([People]Last Name)
The alert box displayed by DO SOMETHING will read “WILLIAMS” and the alert box
displayed by MY METHOD will read “williams”. The method locally changed the value of
the parameter $1, but this does not affect the value of the field [People]Last Name passed
as parameter by the method MY METHOD.
Here the parameter is not the field, but a pointer to it. Therefore, within the DO
SOMETHING method, $1 is no longer the value of the field but a pointer to the field. The
object referenced by $1 ($1-> in the code above) is the actual field. Consequently,
changing the referenced object goes beyond the scope of the subroutine, and the actual
field is affected. In this example, both alert boxes will read “WILLIAMS”.
2. Rather than having the method DO SOMETHING “doing something,” you can rewrite
the method so it returns a value. Thus you would write:
` Here is some code from the method MY METHOD
` ...
` Let's say [People]Last Name is equal to "williams"
[People]Last Name:=DO SOMETHING ([People]Last Name)
ALERT([People]Last Name)
Advanced note: Parameters within the subroutine are accessible through the local
variables $1, $2... In addition, parameters can be optional and can be referred to using the
syntax ${...}. For more information on parameters, see the description of the command
Count parameters.
Data can be returned from methods. A method that returns a value is called a function.
For example, the following line is a statement that uses the built-in function, Length, to
return the length of a string. The statement puts the value returned by Length in a
variable called MyLength. Here is the statement:
MyLength:=Length("How did I get here?")
Any subroutine can return a value. The value to be returned is put into the local variable
$0.
For example, the following function, called Uppercase4, returns a string with the first four
characters of the string passed to it in uppercase:
$0:=Uppercase(Substring($1; 1; 4))+Substring($1; 5)
The function result, $0, is a local variable within the subroutine. It can be used as such
within the subroutine. For example, in the previous DO SOMETHING example, $0 was first
assigned the value of $1, then used as parameter to the ALERT command. Within the
subroutine, you can use $0 in the same way you would use any other local variable. It is
4D that returns the value of $0 (as it is when the subroutine ends) to the called method.
Here is an example. Let’s say you have a [Friends and Relatives] table composed of this
extremely simplified set of fields:
- [Friends and Relatives]Name
- [Friends and Relatives]Children'Name
$0:=$1
QUERY([Friends and Relatives];[Friends and Relatives]Children'Name=$1)
If (Records in selection([Friends and Relatives])>0)
$0:=$0+" who is the child of "+Genealogy of ([Friends and Relatives]Name)
End if
The first way is an iterative algorithm. The second way is a recursive algorithm.
When implementing code for cases like the previous example, it is important to note that
you can always write methods using iteration or recursion. Typically, recursion provides
more concise, readable, and maintainable code, but using it is not mandatory.
Important: Recursive calls should always end at some point. In the example, the method
Genealogy of stops calling itself when the query returns no records. Without this
condition test, the method would call itself indefinitely; eventually, 4D would return a
“Stack Full” error becuase it would no longer have space to “pile up” the calls (as well as
parameters and local variables used in the method).
See Also
Control Flow, Database Methods, Methods.
4D Environment
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Function result Long Integer ← Numeric value denoting the type of the
application
Description
The Application type command returns a numeric value that denotes the type of 4D
environment that you are running. 4D provides the following predefined constants:
Constant Type Value
4th Dimension Long Integer 0
4D Engine Long Integer 1
4D Runtime Long Integer 2
4D Runtime Classic Long Integer 3
4D Client Long Integer 4
4D Server Long Integer 5
4D First Long Integer 6
Example
Somewhere in your code, other than in the On Server Startup database method, you need
to check if you are running 4D Server. You can write:
⇒ If (Application type=4D Server)
` Perform appropriate actions
End if
See Also
Application version, Version type.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Version type command returns a numeric value that denotes the type of 4D
environment version that you are running. 4D provides the following predefined
constants:
Constant Type Value
Full Version Long Integer 0
Demo Version Long Integer 1
Example
Your 4D application includes some features that are not available when a demo version of
the 4D environment is used. Surround these features with a test that calls Version type:
⇒ If (Version type=Full Version)
` Perform appropriate operations
Else
ALERT("This feature is not available in the Demo version of"
+" Super Management Systems™.")
End if
See Also
Application type, Application version.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Application version command returns an encoded string value that expresses the
version number of the 4D environment you are running.
• If you do not pass the optional * parameter, a 4-character string is returned, formatted as
follows:
Characters Description
1-2 Version number
3 Update number
4 Revision number
Example: The string "0600" stands for version 6.0.0.
Examples
1. This example displays the 4D environment version number:
⇒ $vs4Dversion:=Application version
ALERT("You are using the version "+String(Num(Substring($vs4Dversion;1;2)))+"."+
$vs4Dversion≤3≥+"."+$vs4Dversion≤4≥)
See Also
Application type, Version type.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Compiled application tests whether you are running in compiled mode (True) or
interpreted mode (False).
Example
In one of your routines, you include debugging code useful only when you are running
in interpreted mode, so surround this debugging code with a test that calls Compiled
application:
` ...
⇒ If (Not(Compiled application))
` Include debugging code here
End if
` ...
See Also
IDLE, Undefined.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Application file command returns the long name of the 4D executable file or
application you are running.
On Windows
If, for example, you are running 4th Dimension located at \4DWIN600\PROGRAM on
the volume E, the command returns E:\4DWIN600\PROGRAM\4D.EXE.
On Macintosh
If, for example, you are running 4th Dimension in the folder 4th Dimension® 6.0ƒ on
the disk Macintosh HD, the command returns Macintosh HD:4th Dimension® 6.0ƒ:4th
Dimension® 6.0.
Example
At startup on Windows, you need to check if a DLL Library is correctly located at the
same level as the 4D executable file. In the On Startup database method of your
application you can write:
If (On Windows & (Application type#4D Server))
⇒ If (Test path name (Long name to path name (
Application file)+"XRAYCAPT.DLL")#Is a document)
` Display a dialog box explaining that the library XRAYCAPT.DLL
` is missing. Therefore, the X-rays capture capabilitity will not be available.
End if
End if
Note: The project methods On Windows and Long name to path name are listed in the
section System Documents.
See Also
Data file, DATA SEGMENT LIST, Structure file.
Description
The Structure file command returns the long name of structure file for the database with
which you are currently working.
On Windows
If, for example, you are working with the database MyCDs located in \DOCS\MyCDs on
the volume G, the command returns G:\DOCS\MyCDs\MyCDs.4DB.
On Macintosh
If, for example, you are are working with the database located in the folder
Documents:MyCDsƒ: on the disk Macintosh HD, the command returns Macintosh
HD:Documents:MyCDsƒ:MyCDs.
Note: If you call this command under MacOS from an application merged with 4D
Engine, it returns the full name of the structure file located inside the software package. If
you want to get the full name of the software package itself, it is preferable to use the
Application file command. The technique consists of testing the application using the
Application type command, then executing Structure file or Application file depending on
the context.
WARNING: If you call this command while running 4D Client, only the name of the
structure file is returned; the long name is not returned.
Note: The project methods Long name to file name and Long name to path name are listed
in the section System Documents.
See Also
Application file, Data file, DATA SEGMENT LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Function result String ← Long name of the data file for the database
Description
The Data file command returns the long name of the data file or one data segment for the
database with which you are currently working.
If you do not pass the segment parameter, it returns the long name of the data file or the
first segment (if the database is segmented). If you pass the segment parameter, it returns
the long name of the corresponding data segment. If you pass a segment number greater
than the number of data segments, it returns an empty string.
On Windows
If, for example, you are working with the database MyCDs located at \DOCS\MyCDs on
the volume G, a call to Data file returns G:\DOCS\MyCDs\MyCDs.4DD (provided that
you accepted the default location and name proposed by 4D when you created the
database).
On Macintosh
If, for example, you are working with the database located in the folder
Documents:MyCDsƒ: on the disk Macintosh HD, a call to Data file returns Macintosh
HD:Documents:MyCDsƒ:MyCDs.data (provided that you accepted the default location
and name proposed by 4D when you created the database).
WARNING: If you call this command while running 4D Client, only the name of the data
file or the first data segment is returned, not the long name. In addition, even though
the database is segmented, the command returns an empty string for the other data
segments. If you need (for adminstrative purposes) to display a list of the data segments
on a 4D Client station, use a Stored Procedure to build the data segment list and store it in
a variable on the server machine, then get the contents of this variable using the GET
PROCESS VARIABLE command.
See Also
Application file, DATA SEGMENT LIST, Structure file.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Is data file locked command returns True if the data file of the open database or at least
one of its segments is locked — i.e. write protected.
Placed, for instance, in the On Startup Database Method, this command enables the
prevention of any risk of accidental opening of a locked data file.
Example
This method will prevent the opening of the database if the data file is locked:
Description
The Get 4D folder command returns the pathname to the active 4D folder. The 4D
environment uses the 4D folder to store the following information:
• User registration files
• Preferences files used by the 4D environment applications, tools, and utility programs
• TCP/IP Network protocol option file
• .rex and .res files created by 4D Client for storing resources downloaded from 4D Server
• Local database folders created by 4D Client for storing the 4D Extensions downloaded
from 4D Server
You can also use the 4D folder to store your own on-line help files, settings files, etc. By
using the Get 4D folder command to get the actual pathname to that folder, you also
ensure that your code will work on any platform running any localized system.
WARNING: You are free to store whatever files or documents you wish into the 4D folder,
however, it is good idea not to move or modify the files created by the 4D environment
itself.
Example
During the startup of a single-user database, you want to load (or create) your own
settings in a file located in the 4D folder. To do so, in the On Startup Database Method,
you can write code similar to this:
MAP FILE TYPES("PREF";"PRF";"Preferences file")
` Map PREF MacOS file type to .PRF Windows file extension
⇒ $vsPrefDocName:=Get 4D folder+"MyPrefs" ` Build pathname to the Preferences file
` Check if the file exists
If (Test path name($vsPrefDocName+(".PRF"*Num(On Windows)))#Is a document)
$vtPrefDocRef:=Create document($vsPrefDocName;"PREF") ` If not, create it
Else
$vtPrefDocRef:=Open document($vsPrefDocName;"PREF") ` If so, open it
End if
If (OK=1)
` Process document contents
CLOSE DOCUMENT($vtPrefDocRef)
Else
` Handle error
End if
See Also
System folder, Temporary folder, Test path name.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DATA SEGMENT LIST populates the segments array with the long names of the data
segments for the database with which you are currently working.
WARNING: This command does nothing if executed on 4D Client. If you need (for
administrative purposes) to display a list of the data segments on a 4D Client station, use
a Stored Procedure to build the data segment list and store it in a variable on the server
machine, then get the contents of this variable using the GET PROCESS VARIABLE
command.
Examples
1. In the Data Segments Information form for the [Dialogs] table, you want to display a
drop-down list populated with the names of the data segments. To do so, write:
` [Dialogs];"Data Segments Information" form method
Case of
: (Form event=On Load )
` ...
ARRAY STRING(255;asDataSegName;0)
⇒ DATA SEGMENT LIST(asDataSegName)
` ...
End case
See Also
Application file, Data file, Structure file.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The ADD DATA SEGMENT command displays the Data Segment Management dialog box
shown here:
If the user clicks the OK button to validate the dialog box, the OK variable is set to 1. If
the user clicks the Cancel button, OK is set to 0.
When all data segments are full, 4th Dimension or 4D Server generates an error -9999. An
error message is displayed, stating that the disk is full.
If you are using 4th Dimension, you can use the ON ERR CALL method to trap the error
message so you can handle the error procedurally. You can then use ADD DATA SEGMENT
to allow the user to add a new data segment on another volume that has available space.
If you are using 4D Server, you can display an alert stating that the Database
Administrator must add a new data segment from the server machine.
See Also
ON ERR CALL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
FLUSH BUFFERS
Description
The command FLUSH BUFFERS immediately saves the data buffers to disk. All changes that
have been made to the database are stored on disk.
You usually do not need to call this command, as 4D saves data modification on a regular
basis. The database property Flush Data Buffers (in the Design environment), which
specifies how often to save, is typically used to control buffer flushing.
Note: 4D integrates a built-in data cache scheme for accelerating I/O operations. The fact
that data modifications are, for some time, present in the data cache and not on the disk
is transparent to your coding. For example, if you issue a QUERY call, the 4D database
engine integrates the data cache in the query operation.
version 6.8
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command OPEN DATA FILE allows changing the data file opened by the 4D
application on-the-fly.
Pass the name or the full access path of the data file to open in the accessPath parameter.
If you pass only the file name, it must be placed next to the structure file of the database.
If the access path sets a valid data file, 4D quits the database in progress and re-opens it
with the specified data file. The On Exit Database Method and the On Startup Database
Method are successively called.
Before launching the operation, the command checks the validity of the specified data
file: it must have the “.4dd” extension under Windows or have the “dat5” type under
MacOS. Also, if the file was already open, the command verifies that it corresponds to the
current structure.
If you pass an empty string in accessPath, the command will re-open the database without
changing the data file.
See Also
CREATE DATA FILE.
version 6.8
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CREATE DATA FILE allows creating a new data file to disk and to replace the
data file opened by the 4D application on-the-fly.
The general functioning of this command is identical to that of the OPEN DATA FILE
command; the only difference is that the new data file set by the accessPath parameter is
created just after the structure is re-opened.
Before launching the operation, the command verifies that the specified access path does
not correspond to an existing file.
See Also
OPEN DATA FILE.
QUIT 4D {(time)}
Description
The QUIT 4D command exits 4th Dimension/4D Client or 4D Server and returns to the
Desktop.
If the user is performing data entry, the records will be cancelled and not saved.
If you want to let the user save data entry modifications made in the current open
windows, you can use interprocess communication to signal all the other user processes
that the database is going to be exited. To do so, you can adopt two strategies:
• Perform these operations from within the current process before calling QUIT 4D
• Handle these operations from within the On Exit Database Method.
A third strategy is also possible. Before calling QUIT 4D, you check whether a window will
need validation; if that is the case, you ask the user to validate or cancel these windows
and then to choose Quit again. However, from a user interface standpoint, the first two
strategies are preferable.
Note: The time parameter cannot be used with 4th Dimension or 4D Client.
If there is an On Server Stop Database Method, it is executed after the delay set by the time
parameter, or after all clients have disconnected, depending on your parameters.
The action of the QUIT 4D command used in a stored procedure is the same as the one for
the Quit command of the 4D Server File menu: it causes a dialog box to appear on each
client machine indicating that the server is about to quit.
Example
The project method listed here is associated with the Quit or Exit menu item in the File
menu.
` M_FILE_QUIT Project Method
See Also
On Exit Database Method, On Server Shutdown Database Method.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SELECT LOG FILE command opens, creates, or closes the Log File according to the
value you pass in logFile.
IMPORTANT: Calling SELECT LOG FILE is the same as choosing Log File from the File
menu in the User environment. This should only be used when 4D Backup is installed in
the database.
If you pass an empty string in logFile, SELECT LOG FILE presents an Open File dialog box,
allowing the user to open a log file or to create a new one. If the user clicks the Open
button and the file is opened correctly, the OK variable is set to 1. Otherwise, if the user
clicks Cancel or if the Log File could not be opened or created, OK is set to 0.
If you pass "*" in logFile, SELECT LOG FILE closes the current Log File for the database. The
OK variable is set to 1 when the log file is closed.
If you use SELECT LOG FILE to create or open a Log File when a full backup has not yet
been performed and the data file already contains records, 4th Dimension displays the
following alert:
Note: The SELECT LOG FILE command does not do anything when used with 4D Server.
For more information about this command, see the documentation for the 4D Backup
plug-in.
See Also
ON ERR CALL.
Error Handling
An error -4447 is generated if the operation cannot be performed because the database
needs to be backed up. You can intercept the error with an ON ERR CALL method.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET SERIAL INFORMATION returns various information about the 4D
current version serialization.
The serialization works as follows: a user who wants to get a component sends his unique
key generated through the GET SERIAL INFORMATION command to the developer. This
can be done through an Order form included in a demo version of the component. The
generated key is unique and is associated to a specific 4D application.
The component developer can then generate his own serial number combining the key
and a given cipher. The delivered component will offer a function verifying if the
information returned by the GET SERIAL INFORMATION matches this serial number.
Otherwise, the user will not be able to use the component.
Note: Plug-ins developers can use this protection scheme too. For more information, refer
to the 4D Plugin API Reference.
See Also
Get component resource ID.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is license available enables you to know the availability of a product or plug-
in. It is useful, for instance, for displaying or hiding functions requiring the presence of a
plug-in.
• You pass one of the constants of the “Is license available” theme in the license
parameter:
Constant Type Value
4D Draw License Longint 808464694
4D for OCI License Longint 808465208
4D View License Longint 808465207
4D Web License Longint 808464945
4D Write License Longint 808464697
In this case, the command returns True if the corresponding product is loaded and if
(with 4D Server) it has a license available.
For instance, if you have a serial number for 4D Draw but no available expansion serial
number, the command returns True with a 4th Dimension single-station system but False
with 4D Server. On the contrary, if you have an expansion serial number for 4D Draw but
not a serial number, the command returns True with 4D Server but False with
4th Dimension. If you have both a serial number and an expansion serial number, the
command returns True in all cases.
• You pass the ID number of the plug-in “4BNX” resource directly in the license
parameter. In this case, the command behaves as described above.
Arrays
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An array is an ordered series of variables of the same type. Each variable is called an
element of the array. The size of an array is the number of elements it holds. An array is
given its size when it is created; you can then resize it as many times as needed by adding,
inserting, or deleting elements, or by resizing the array using the same command used to
create it.
You create an array with one of the array declaration commands. For details, see the
section Creating Arrays.
Elements are numbered from 1 to N, where N is the size of the array. An array always has
an element zero that you can access just like any other element of the array, but this
element is not shown when an array is present in a form. Although the element zero is
not shown when an array supports a form object, there is no restriction in using it with
the language. For more information about the element zero, see the section Using the
element zero of an array.
Arrays are 4D variables. Like any variable, an array has a scope and follows the rules of the
4D language, though with some unique differences. For more information, see the
sections Arrays and the 4D Language and Arrays and Pointers.
Arrays are language objects; you can create and use arrays that will never appear on the
screen. Arrays are also user interface objects. For more information about the interaction
between arrays and form objects, see the sections Arrays and Form Objects and Grouped
Scrollable Areas.
Arrays are designed to hold reasonable amounts of data for a short period of time.
However, because arrays are held in memory, they are easy to handle and quick to
manipulate. For details, see the section Arrays and Memory.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You create an array with one of the array declaration commands described in this chapter.
The following table lists the array declaration commands:
(*) Longint arrays allows you to manipulate data of Time type. To display a Time array in a
form, apply to the associated form object the display format &/x, in which x represents
the number of the format in the Time formats list (by order of appearance). For exemple,
&/4 will display the Hour Min format.
(**) The difference between Text arrays and String arrays lies in the nature of their
elements. In both types of array, elements can hold text values (characters). However:
• In a Text array, each element is of variable length and stores its characters in a separate
part of memory.
• In a String array, all elements have the same fixed length (the length passed when the
array was created). All elements are stored one after the other in the same part of
memory, no matter what the contents.
Due to this structural difference, string arrays act faster than text arrays. Note, however,
that an element of a String array can only hold up to 255 characters.
Note the syntax atNames{$vlElem}. Rather than specifying a numeric literal such as
atNames{3}, you can use a numeric variable to indicate which element of an array you are
addressing.
Using the iteration provided by a loop structure (For...End for, Repeat...Until or While...End
while), compact pieces of code can address all or part of the elements in an array.
See Also
ARRAY BOOLEAN, ARRAY DATE, ARRAY INTEGER, ARRAY LONGINT, ARRAY PICTURE, ARRAY
POINTER, ARRAY REAL, ARRAY STRING, ARRAY TEXT, Arrays, Two-dimensional Arrays.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Arrays are language objects—you can create and use arrays that will never appear on the
screen. However, arrays are also user interface objects. The following types of Form
Objects are supported by arrays:
• Pop-up/Drop-down List
• Combo Box
• Scrollable Area
• Tab Control
While you can predefine these objects in the Design Environment Form Editor (using the
Default Values button of the Object Properties window), you can also define them
programmatically using the arrays commands. In both cases, the form object is supported
by an array created by you or 4D.
When using these objects, you can detect which item within the object has been selected
(or clicked) by testing the array for its selected element. Conversely, you can select a
particular item within the object by setting the selected element for the array.
When an array is used to support a form object, it has then a dual nature; it is both a
language object and a user interface object. For example, when designing a form, you
create a scrollable area; in the Variable page of the Object Properties window, you name
the Variable Object:
The name, in this case atNames, is the name of the array you use for creating and
handling the array.
The following example shows how to fill an array and display it in a drop-down list. An
array arSalaries is created using the ARRAY REAL command. It contains all the standard
salaries paid to people in a company. When the user chooses an element from the drop-
down list, the [Employees]Salary field is assigned the value chosen in the User or Custom
Menus environment.
The lines:
ARRAY REAL(arSalaries;10)
For($vlElem;1;10)
arSalaries{$vlElem}:=2000+($vlElem*500)
End for
create the numeric array 2500, 3000... 7000, corresponding to the annual salaries $30,000
up to $84,000, before tax.
The lines:
arSalaries:=Find in array(arSalaries;[Employees]Salary)
If (arSalaries=-1)
arSalaries:=0
End if
handle both the creation of a new record or the modification of existing record.
• If you create a new record, the field [Employees]Salary is initially equal to zero. In this
case, Find in array does not find the value in the array and returns -1. The test If
(arSalaries=-1) resets arSalaries to zero, indicating that no element is selected in the drop-
down list.
• If you modify an existing record, Find in array retrieves the value in the array and sets
the selected element of the drop-down list to the current value of the field. If the value
for a particular employee is not in the list, the test If (arSalaries=-1) deselects any element
in the list.
Note: For more information about the array selected element, read the next section.
In the User or Custom Menus environment, the drop-down list looks like this:
The following section describes the common and basic operations you will perform on
arrays while using them as form objects.
You can obtain the current size of the array by using the Size of array command. Using
the previous example, the following line of code would display 5:
ALERT ("The size of the array atNames is: "+String(Size of array(atNames)))
You can reorder the elements of the array using the SORT ARRAY command. Using the
previous example, and provided the array is shown as a scrollable area:
a. Initially, the area would look like the list on the left.
b. After the execution of the following line of code:
SORT ARRAY(atNames;>)
the area would look like the list in the middle.
c. After the execution of the following line of code:
SORT ARRAY(atNames;<)
the area would look like the list on the right.
You can add, insert, or delete elements using the commands INSERT ELEMENT and DELETE
ELEMENT.
Using the previous example, and provided the array is shown as a scrollable area, you can
handle clicks in this area as follows:
` atNames scrollable area object method
Case of
: (Form event=On Load)
` Initialize the array (as shown further above)
ARRAY TEXT (atNames;5)
` ...
: (Form event=On Unload)
` We no longer need the array
CLEAR VARIABLE(atNames)
While the syntax atNames{$vlElem} allows you to work with a particular element of the
array, the syntax atNames returns the element number of the selected element within
the array. Thus, the syntax atNames{atNames} means “the value of the selected element
in the array atNames.” If no element is selected, atNames is equal to 0 (zero), so the test If
(atNames#0) detects whether or not an element is actually selected.
In a similar fashion, you can programmatically change the selected element by assigning
a value to the array.
If ((0<atNames)&(atNames<Size of array(atNames))
` If possible, selects the next element to the selected element
atNames:=atNames+1
End if
If (1<atNames)
` If possible, selects the previous element to the selected element
atNames:=atNames-1
End if
The Find in array command searches for a particular value within an array. Using the
previous example, the following code will select the element whose value is “Richard,” if
that is what is entered in the request dialog box:
$vsName:=Request("Enter the first name:")
If (OK=1)
$vlElem:=Find in array (atNames;$vsName)
If ($vlElem>0)
atNames:=$vlElem
Else
ALERT ("This is no "+$vsName+" in that list of first names.")
End if
End if
Pop-up menus, drop-down lists, scrollable areas, and tab controls can be usually handled in
the same manner. Obviously, no additional code is required to redraw objects on the
screen each time you change the value of an element, or add or delete elements.
Note: To create and use tab controls with icons and enabled and disabled tabs, you must
use a hierarchical list as the supporting object for the tab control. For more information,
see the example for the New list command.
While you can handle pop-up menus, drop-down lists, scrollable areas, and tab controls
with the algorithms described in the previous section, you must handle combo boxes
differently.
A combo box is actually a text enterable area to which is attached a list of values (the
elements from the array). The user can pick a value from this list, and then edit the text.
So, in a combo box, the notion of selected element does not apply.
With combo boxes, there is never a selected element. Each time the user selects one of
the values attached to the area, that value is put into the element zero of the array. Then,
if the user edits the text, the value modified by the user is also put into that element zero.
Example
` asColors Combo Box object method
Case of
: (Form event=On Load)
ARRAY STRING(31;asColors;3)
asColors{1}:="Blue"
asColors{2}:="White"
asColors{3}:="Red"
: (Form event=On Clicked)
If (asColors{0}#"")
` The object automatically changes its value
` Using the On Clicked event with a Combo Box
` is required only when additional actions must be taken
End if
: (Form event=On Data Change)
` Find in array ignores element 0, so returns -1 or >0
If (Find in array(asColors;asColors{0})<0)
` Entered value is not one the values attached to the object
` Add the value to the list for next time
$vlElem:=Size of array(asColors)+1
INSERT ELEMENT(asColors;$vlElem)
asColors{$vlElem}:=asColors{0}
Else
` Entered value is among the values attached to the object
End if
End case
See Also
Arrays, Grouped Scrollable Areas.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You can group scrollable areas for display in a form. When several scrollable areas are
grouped, they act as one scrollable area. Each scrollable area can have its own font and
style; however, we recommend that you use the same font height (which depends on the
font and font size) for each column. When displayed during data entry, only the
frontmost scrollable area displays a scroll bar. Following are three scrollable areas grouped
together in the Design environment:
The following project method fills the three arrays and displays them on the screen:
ALL RECORDS(Employees)
SELECTION TO ARRAY([Employees]Last
Name;asName;[Employees]Title;asTitle;[Departments]Name;asDepartment)
DIALOG([Departments];"Example Grouped SA")
Note: The [Departments] table can be used, provided that there is an automatic relation
from [People] to [Departments].
Note that only a single scroll bar is displayed; it is always on the frontmost scrollable area.
This scroll bar controls the scrolling of all three arrays as if they were one. When the user
clicks a line, all three areas are highlighted simultaneously. The variable associated with
each scrollable area is set to the number of the line that the user clicks; only the object
method for the area that is clicked executes. For example, if the user clicks the name
“Bentley,” asName, asTitle, and asDepartment are all set to two, but only the object
method for asName executes. If you set the selected element of one of the arrays in the
grouped scrollable areas, the other arrays are set to the same selected element for the next
event, and the respective line in the scrollable area is highlighted.
Note that the arrays were sorted based on the first argument to the SORT ARRAY
command; the other two arrays were specified in order to keep the rows synchronized.
The command SORT ARRAY always sorts the arrays (if several are specified) on the values
of the first array and keeps the additional arrays synchronized.
Note: SORT ARRAY does not perform a multi-level sort on arrays. To show a table similar to
the one above and also perform multi-level sorts (i.e., by department, then by title, then
by name), use a subform in which you display the table, and then use ORDER BY.
See Also
Arrays, Arrays and Form Objects.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Arrays are 4D variables. Like any variable, an array has a scope and follows the rules of the
4D language, though with some unique differences.
You can create and work with local, process, and interprocess arrays. Examples:
ARRAY INTEGER ($aiCodes;100)
` This creates a local array of 100 2-byte Integer values
ARRAY INTEGER (aiCodes;100)
` This creates a process array of 100 2-byte Integer values
ARRAY INTEGER (<>aiCodes;100)
` This creates an interprocess array of 100 2-byte Integer values
The scope of these arrays is identical to the scope of other local, process, and interprocess
variables:
Local arrays
A local array is declared when the name of the array starts with a dollar sign ($).
The scope of a local array is the method in which it is created. The array is cleared when
the method ends. Local arrays with the same name in two different methods can have
different types, because they are actually two different variables with different scopes.
When you create a local array within a form method, within an object method, within or
a project method called as subroutine by the two previous type of method, the array is
created and cleared each time the form or object method is invoked. In other words, the
array is created and cleared for each form event. Consequently, you cannot use local
arrays in forms, neither for display nor printing.
As with local variables, it is a good idea to use local arrays whenever possible. In doing so,
you tend to minimize the amount of memory necessary for running your application.
Process arrays
A process array is declared when the name of the array starts with a letter.
The scope of a process array is the process in which it is created. The array is cleared when
the process ends or is aborted. A process array automatically has one instance created per
process. Therefore, the array is of the same type throughout the processes. However, its
contents are particular to each process.
Note: You can use process and interprocess arrays in forms to create form objects such as
scrollable areas, drop-down lists, and so on.
Unlike text or string variables, you cannot assign one array to another. To copy (assign)
an array to another one, use COPY ARRAY.
See Also
Arrays, Arrays and Pointers.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Note: You can pass process and interprocess arrays as parameters, but not local arrays.
If you need to do the same thing for 50 different arrays in various forms, you can avoid
writing the same thing 50 times, by using the following project method:
` SELECT NEXT ELEMENT project method
` SELECT NEXT ELEMENT ( Pointer )
` SELECT NEXT ELEMENT ( -> Array )
C_POINTER ($1)
If ((0<$1->)&($1-><Size of array($1->))
$1->:=$1->+1 ` If possible, selects the next element to the selected element
End if
C_REAL ($0)
$0:=0
For ($vlElem;1;Size of array($1->))
$0:=$0+$1->{$vlElem}
End for
• The following project method capitalizes of all the elements of a string or text array:
` CAPITALIZE ARRAY
` CAPITALIZE ARRAY ( Pointer )
` CAPITALIZE ARRAY ( -> Array )
The combination of arrays, pointers, and looping structures, such as For... End for, allows
you to write many useful small project methods for handling arrays.
See Also
Arrays, Arrays and the 4D Language.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An array always has an element zero. While element zero is not shown when an array
supports a form object, there is no restriction in using it with the language.
One example of the use of element zero is the case of the combo box discussed in the
section Arrays and Form Objects.
1. If you want to execute an action only when you click on an element other than the
previously selected element, you must keep track of each selected element. One way to do
this is to use a process variable in which you maintain the element number of the selected
element. Another way is to use the element zero of the array:
In certain cases, you might want to fully control the way ASCII codes are translated. One
way to do this is to use an Integer array of 255 elements, where the Nth element is set to
the translated ASCII code for the character whose source ASCII code is N. For example, if
the ASCII code #187 must be translated as #156, you would write
<>aiCustomOutMap{187}:=156 and <>aiCustomInMap{156}:=187 in the method that
initializes the interprocess arrays used everywhere in the database. You can then send a
stream of characters with the following custom project method:
` X SEND PACKET ( Text { ; Time } )
For ($vlChar;1;Length($1))
$1[[vlChar]]:=Char(<>aiCustomOutMap{Ascii($1[[vlChar]])})
End for
If (Count parameters>=2)
SEND PACKET ($2;$1)
Else
SEND PACKET ($1)
End if
See Also
Arrays.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Each of the array declaration commands can create or resize one-dimensional or two-
dimensional arrays. Example:
` Creates a text array composed of 100 rows of 50 columns
ARRAY TEXT (atTopics;100;50)
Two-dimensional arrays are essentially language objects; you can neither display nor print
them.
In the following example, a pointer to each field of each table in the database is stored in
a two-dimensional array:
` Get the pointers to the fields for the table currently displayed at the screen:
COPY ARRAY (<>apFields{Table(Current form table)};$apTheFieldsIamWorkingOn)
` Initialize Boolean and Date fields
For ($vlElem;1;Size of array($apTheFieldsIamWorkingOn))
Case of
: (Type($apTheFieldsIamWorkingOn{$vlElem}->)=Is Date)
$apTheFieldsIamWorkingOn{$vlElem}->:=Current date
: (Type($apTheFieldsIamWorkingOn{$vlElem}->)=Is Boolean)
$apTheFieldsIamWorkingOn{$vlElem}->:=True
End case
End for
Note: As this example suggests, rows of a two-dimensional arrays can be the same size or
different sizes.
See Also
Arrays.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Unlike the data you store on disk using tables and records, an array is always held in
memory in its entirety.
For example, if all US zip codes were entered in the [Zip Codes] table, it would contain
about 100,000 records. In addition, that table would include several fields: the zip code
itself and the corresponding city, county, and state. If you select only the zip codes from
California, the 4D database engine creates the corresponding selection of records within
the [Zip Codes] table, and then loads the records only when they are needed (i.e., when
they are displayed or printed). In order words, you work with an ordered series of values
(of the same type for each field) that is partially loaded from the disk into the memory by
the database engine of 4D.
Doing the same thing with arrays would be prohibitive for the following reasons:
• In order to maintain the four information types (zip code, city, county, state), you
would have to maintain four large arrays in memory.
• Because an array is always held in memory in its entirety, you would have to keep all the
zip codes information in memory throughout the whole working session, even though
the data is not always in use.
• Again, because an array is always held in memory in its entirety, each time the database
is started and then quit, the four arrays would have to be loaded and then saved on the
disk, even though the data is not used or modified during the working session.
Conclusion: Arrays are intended to hold reasonable amounts of data for a short period of
time. On the other hand, because arrays are held in memory, they are easy to handle and
quick to manipulate.
However, in some circumstances, you may need to work with arrays holding hundreds or
thousands of elements. The following table lists the formulas used to calculate the
amount of memory used for each array type:
Array Type Formula for determining Memory Usage in Bytes
Boolean (31+number of elements)\8
Date (1+number of elements) * 6
String (1+number of elements) * Declared length (+1 of odd, +2 if even)
Integer (1+number of elements) * 2
Long Integer (1+number of elements) * 4
Picture (1+number of elements) * 4 + Sum of the size of each picture
Pointer (1+number of elements) * 16
Real (1+number of elements) * 8 (Windows, PPC) or * 10 (68K)
Text (1+number of elements) * 6 + Sum of the size of each text
Two-dimemsional (1+number of elements) * 12 + Sum of the size of each array
When working with very large arrays, the best way to handle full memory situations is to
surround the creation of the arrays with an ON ERR CALL project method. Example:
` You are going to run a batch operation the whole night
` that requires the creation of large arrays. Instead of risking
` occurrences of errors in the middle of the night, put
` the creation of the arrays at the beginning of the operation
` and test the errors at this moment:
gError:=0 ` Assume no error
ON ERR CALL ("ERROR HANDLING") ` Install a method for catching errors
ARRAY STRING (63;asThisArray;50000) ` Roughly 3125K
ARRAY REAL (arThisAnotherArray;50000) ` 488K
ON ERR CALL ("") ` No longer need to catch errors
If (gError=0)
` The arrays could be created
` and let's pursue the operation
Else
ALERT ("This operation requires more memory!")
End if
` Whatever the case, we no longer need the arrays
CLEAR VARIABLE (asThisArray)
CLEAR VARIABLE (arThisAnotherArray)
See Also
Arrays, ON ERR CALL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY INTEGER creates and/or resizes an array of 2-byte Integer elements
in memory.
Examples
1. This example creates a process array of 100 2-byte Integer elements:
2. This example creates a local array of 100 rows of 50 2-byte Integer elements:
3. This example creates an interprocess array of 50 2-byte Integer elements, and sets each
element to its element number:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY LONGINT creates and/or resizes an array of 4-byte Long Integer
elements in memory.
Examples
1. This example creates a process array of 100 4-byte Long Integer elements:
2. This example creates a local array of 100 rows of 50 4-byte Long Integer elements:
3. This example creates an interprocess array of 50 4-byte Long Integer elements and sets
each element to its element number:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY REAL creates and/or resizes an array of Real elements in memory.
Examples
1. This example creates a process array of 100 Real elements:
3. This example creates an interprocess array of 50 Real elements and sets each element to
its element number:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY STRING creates and/or resizes an array of String elements in
memory.
• The strLen parameter specifies the maximum number of characters that can be
contained in each array element in a string array. The length can be from 1 to 255
characters.
• The arrayName parameter is the name of the array.
• The size parameter is the number of elements in the array.
• The size2 parameter is optional; if size2 is specified, the command creates a two-
dimensional array. In this case, size specifies the number of rows and size2 specifies the
number of columns in each array. Each row in a two-dimensional array can be treated as
both an element and an array. This means that while working with the first dimension of
the array, you can use other array commands to insert and delete entire arrays in a two-
dimensional array.
Examples
1. This example creates a process array of 100 31-character String elements:
2. This example creates a local array of 100 rows of 50 63-character String elements:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY TEXT creates and/or resizes an array of Text elements in memory.
Examples
1. This example creates a process array of 100 Text elements:
3. This example creates an interprocess array of 50 Text elements and sets each element to
the value “Element #” followed by its element number:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY DATE creates and/or resizes an array of Date elements in memory.
Examples
1. This example creates a process array of 100 Date elements:
3. This example creates an interprocess array of 50 Date elements, and sets each element
to the current date plus a number of days equal to the element number:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY BOOLEAN creates and/or resizes an array of Boolean elements in
memory.
Tip: In some contexts, an alternative to using Boolean arrays is using an Integer array
where each element “means true” if different from zero and “means false” if equal to
zero.
Examples
1. This example creates a process array of 100 Boolean elements:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY PICTURE creates and/or resizes an array of Picture elements in
memory.
Examples
1. This example creates a process array of 100 Picture elements:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY POINTER creates or resizes an array of Pointer elements in memory.
Examples
1. This example creates a process array of 100 Pointer elements:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Size of array returns the number of elements in array.
Example
1. The following example returns the size of the array anArray:
3. The following example returns the number of columns for a row in a two-dimensional
array:
See Also
DELETE ELEMENT, INSERT ELEMENT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SORT ARRAY sorts one or more arrays into ascending or descending order.
Note: You cannot sort Pointer or Picture arrays. You can sort the elements of a two-
dimensional array (i.e., a2DArray{$vlThisElem}) but you cannot sort the two-dimensional
array itself (i.e., a2DArray).
The last parameter specifies whether to sort array in ascending or descending order. The
“greater than” symbol (>) indicates an ascending sort; the “less than” symbol (<)
indicates a descending sort. If you do not specify the sorting order, then the sort is
ascending.
If more than one array is specified, the arrays are sorted following the sort order of the
first array; no multi-level sorting is performed here. This feature is especially useful with
grouped scrollable areas in a form; SORT ARRAY maintains the synchronicity of the arrays
that sustain the scrollable areas.
Examples
1. The following example creates two arrays and then sorts them by company:
ALL RECORDS ([People])
SELECTION TO ARRAY ([People]Name;asNames;[People]Company;asCompanies)
⇒ SORT ARRAY (asCompanies; asNames;>)
However, because SORT ARRAY does not perform multi-level sorts, you will end up with
people‘s names in random order within each company. To sort people by name within
each company, you would write:
ALL RECORDS ([People])
ORDER BY ([People];[People]Company;>;[People]Name;>)
SELECTION TO ARRAY ([People]Name;asNames;[People]Company;asCompanies)
See Also
ORDER BY, SELECTION TO ARRAY.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The MULTI SORT ARRAY command enables you to carry out a multi-level sort on a set of
arrays. This function is particularly useful in the context of grouped scrolling areas in
forms. It is also invaluable for generic developments (for example, you can create a
generic method for sorting arrays of all types, or yet again, create the equivalent of a
generic SORT ARRAY command).
The ptrArrayName parameter contains the name of an array of array pointers; each
element of this array is a pointer designating an array to be sorted. The sorts are
performed in the order of the array pointers defined by ptrArrayName.
Note: ptrArrayName can be an array of local ($ptrArrayName), process (ptrArrayName) or
inter-process (<>ptrArrayName) pointers. Conversely, the elements of this array must
point to process or inter-process arrays only.
The sortArrayName parameter contains the name of an array in which each element
indicates the sorting order (-1, 0 or 1) of the element of the corresponding array of
pointers:
-1 = Sort by decreasing order.
0 = The array is not used as a sorting criterion but must be sorted according to the other
sorts.
1 = Sort by increasing order.
Note: You cannot sort arrays of the Pointer or Picture type. You can sort an element of a
two-dimensional array (i.e. a2DArray{$vlThisElement}), but you cannot sort the 2D array
itself (i.e. a2DArray).
For each element of the ptrArrayName array, there must be a corresponding element of
the sortArrayName array. Both arrays must therefore have exactly the same number of
elements.
If you want the array of names be used as a third sort criterion, you need to assign the
value 1 to the sorts_Array{3} element. Or else, if you want the arrays to be sorted only by
the city criterion, assign the value 0 to the sorts_Array{2}, sorts_Array{3} and sorts_Array{4}
elements. In this way, you obtain an identical result to SORT
ARRAY(cities;companies;names;telNums;>).
See also
ORDER BY, SELECTION TO ARRAY, SORT ARRAY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Find in array returns the number of the first element in array that matches
value.
Find in array can be used with Text, String, Numeric, Date, Pointer, and Boolean arrays.
The array and value parameters must be of the same type.
If start is specified, the command starts searching at the element number specified by
start. If start is not specified, the command starts searching at element 1.
Examples
1. The following project method deletes all empty elements from the string or text array
whose pointer is passed as parameter:
` CLEAN UP ARRAY project method
` CLEAN UP ARRAY ( Pointer )
` CLEAN UP ARRAY ( -> Text or String array )
C_POINTER ($1)
Repeat
⇒ $vlElem:=Find in array ($1->;"")
If ($vlElem>0)
DELETE ELEMENT ($1->;$vlElem)
End if
Until ($vlElem<0)
2. The following project method selects the first element of an array whose pointer is
passed as the first parameter that matches the value of the variable or field whose pointer
is passed as parameter:
` SELECT ELEMENT project method
` SELECT ELEMENT ( Pointer ; Pointer)
` SELECT ELEMENT ( -> Text or String array ; -> Text or String variable or field )
End case
See Also
DELETE ELEMENT, INSERT ELEMENT, Size of array.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command INSERT ELEMENT inserts one or more elements into the array array. The
new elements are inserted before the element specified by where, and are initialized to the
empty value for the array type. All elements beyond where are consequently moved
within the array by an offset of one or the value you pass in howMany.
If where is greater than the size of the array, the elements are added to the end of the
array.
The howMany parameter is the number of elements to insert. If howMany is not specified,
then one element is inserted. The size of the array grows by howMany.
Example
1. The following example inserts five new elements, starting at element 10:
See Also
DELETE ELEMENT, Size of array.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE ELEMENT deletes one or more elements from array. Elements are
deleted starting at the element specified by where.
The howMany parameter is the number of elements to delete. If howMany is not specified,
then one element is deleted. The size of the array shrinks by howMany.
Examples
1. The following example deletes three elements, starting at element 5:
2. The following example deletes the last element from an array, if it exists:
$vlElem:=Size of array(anArray)
If ($vlElem>0)
⇒ DELETE ELEMENT (anArray;$vlElem)
End if
See Also
INSERT ELEMENT, Size of array.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command COPY ARRAY creates or overwrites the destination array destination with
the exact contents, size, and type of the source array source.
The source and destination arrays can be local, process, or interprocess arrays. When
copying arrays, the scope of the array does not matter.
Examples
The following example fills the array named C. It then creates a new array, named D, of
the same size as C and with the same contents:
ALL RECORDS ([People]) ` Select all records in People
SELECTION TO ARRAY ([People]Company; C) ` Move company field data into array C
⇒ COPY ARRAY (C; D) ` Copy the array C to the array D
version 3
Compatibility Note
Due to the new implementation of Choice Lists, compatibility for this command could
not be fully maintained. Also, starting with version 6, we recommend that you start using
the command Load list to work with the hierarchical lists defined in the Design
environment List Editor.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command LIST TO ARRAY creates or overrides the array array with the first level items
of the list list.
The optional itemRefs parameter (a numeric array) returns the list item reference numbers.
Compatibility Note: In the previous version of 4D, this array was filled with the names of
any linked lists. If an element of the list had a linked list, the name of the linked list was
put into the array element with the same number as the list element. If there was no
linked list, then the element was the empty string. The second array was set to the same
size as array. You could use the names in this array to access the linked lists.
You can continue to use LIST TO ARRAY to build an array based on the first level items of a
hierarchical list. However, this command does not provide you with the child items, if
any. To work with hierarchical lists, use the new Hierarchical Lists commands introduced
in version 6.
Example
The following example copies the items of a list called Regions into an array called
atRegions:
See Also
ARRAY TO LIST, Load list, SAVE LIST.
version 3
Compatibility Note
Due to the new implementation of Choice Lists, compatibility for this command could
not be fully maintained. Also, starting with version 6, we recommend that you use the
command SAVE LIST to work with the hierarchical lists defined in the Design
environment List Editor.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY TO LIST creates or replaces the list list (as defined in the Design
environment List Editor) using the elements of the array array.
This command allows you to define only the first level items of the list.
The optional itemRefs parameter, if specified, must be a numeric array synchronized with
the array array. Each element, then, indicates the list item reference number for the
corresponding element in array. If you omit this parameter, 4D automatically sets the list
item reference numbers to 1, 2... N.
Compatibility Note: In the previous version of 4D, this parameter was used to link other
lists to each element in array. If an element of the links array was the name of an existing
list, then that list was attached to the corresponding item.
You can continue to use ARRAY TO LIST to build a list based on the elements of an array.
However, this command does not provide a means of working with the child items. To
work with hierarchical lists, use the new Hierarchical Lists commands introduced in
version 6.
See Also
LIST TO ARRAY, Load list, ON ERR CALL, SAVE LIST.
Error Handling
An error -9957 is generated when ARRAY TO LIST is applied to a list that is currently being
edited in the Design environment List Editor. You can catch this error using an ON ERR
CALL project method.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SELECTION TO ARRAY (field | table; array{; field2 | table2; array2; ...; fieldN | tableN; arrayN})
Description
The command SELECTION TO ARRAY creates one or more arrays and copies data in the
fields or record numbers from the current selection into the arrays.
The command SELECTION TO ARRAY applies to the selection for the table specified in the
first parameter. SELECTION TO ARRAY, can perform the following:
• Load values from one or several fields.
• Load Record numbers using the syntax ...;[table];Array;...
• Load values from related fields, provided that there is a Many to One automatic relation
between the tables or provided that you have previously called AUTOMATIC RELATIONS to
make manual Many to One relations automatic. In both cases, values are loaded from
tables through several levels of Many to One relations.
Each array is typed according to the field type. There are two exceptions:
• If a Text field is copied into a String array, the array will remain a String array.
• A Time field is copied into a Long Integer array.
If you load record numbers, they are copied into a Long Integer array.
4D Server: The SELECTION TO ARRAY command is optimized for 4D Server. Each array is
created on the server and then sent, in its entirety, to the client machine.
WARNING: The SELECTION TO ARRAY command can create large arrays, depending on the
range you specify in start and end, and on the type and size of the data you are loading.
Arrays reside in memory, so it is a good idea to test the result after the command is
completed. To do so, test the size of each resulting array or cover the call to the
command, using an ON ERR CALL project method.
Note: After a call to SELECTION TO ARRAY, the current selection and current record
remain the same, but the current record is no longer loaded. If you need to use the values
of the fields in the current record, use the LOAD RECORD command after the SELECTION
TO ARRAY command.
2. The following example returns the [Clients] record numbers in the array
alRecordNumbers and the [Clients]Names field values in the array asNames:
See Also
ARRAY TO SELECTION, AUTOMATIC RELATIONS, ON ERR CALL, SELECTION RANGE TO
ARRAY.
version 3.5.3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SELECTION RANGE TO ARRAY (start; end; field | table; array{; field2 | table2; array2; ...;
fieldN | tableN; arrayN})
Description
SELECTION RANGE TO ARRAY creates one or more arrays and copies data from the fields or
record numbers from the current selection into the arrays.
Unlike SELECTION TO ARRAY, which applies to the current selection in its entirety,
SELECTION RANGE TO ARRAY only applies to the range of selected records specified by the
parameters start and end.
The command expects you to pass in start and end the selected record numbers
complying with the formula 1 <= start <= end <= Records in selection ([...]).
If you pass 1 <= start = end < Records in selection ([...]), you will load fields or get the
record number from the record whose selected record is start = end.
If you pass incorrect selected record numbers, the command does the following:
• If end > Records in selection ([...]), it returns values from the selected record specified by
start to the last selected record.
• If start > end, it returns values from the record whose selected record is start only.
Like SELECTION TO ARRAY, the SELECTION RANGE TO ARRAY command applies to the
selection for the table specified in the first parameter.
Also like SELECTION TO ARRAY, SELECTION RANGE TO ARRAY can perform the following:
• Load values from one or several fields.
• Load Record numbers using the syntax ...;[table];Array;...
• Load values from related fields, if there is a Many to One automatic relation between the
tables or if you have previously called AUTOMATIC RELATIONS to change manual Many to
One relations to automatic. In both cases, values can be loaded from tables through
several levels of Many to One relations.
Each array is typed according to the field type. There are two exceptions:
• If a Text field is copied into a String array. In this case, the array will remain a String
array.
• A Time field is copied into a Long Integer array.
If you load record numbers, they are copied into a Long Integer array.
4D Server: SELECTION RANGE TO ARRAY is optimized for 4D Server. Each array is created
on the server and then sent, in its entirety, to the client machine.
WARNING: SELECTION RANGE TO ARRAY can create large arrays, depending on the range
you specify in start and end, and on the type and size of the data you are loading. Arrays
reside in memory, so it is a good idea to test the result after the command is completed.
To do so, test the size of each resulting array or cover the call to the command, using an
ON ERR CALL project method.
If the command is successful, the size of each resulting array is equal to (end-start)+1,
except if the end parameter exceeded the number of records in the selection. In such a
case, each resulting array contains (Records in selection([...])-start)+1 elements.
2. The following code addresses the last 50 records from the current selection for the
[Invoices] table. It loads the record numbers of the [Invoices] records as well as those of the
[Customers] related records:
lSelSize := Records in selection ([Invoices])
⇒ SELECTION RANGE TO ARRAY (lSelSize-49;lSelSize;[Invoices];alInvRecN;[Customers];
alCustRecN)
3. The following code process, in sequential “chunks”of 1000 records, a large selection
that could not be downloaded in its entirety into arrays:
lMaxPage := 1000
lSelSize := Records in selection ([Phone Directory])
For ($lPage ; 1; 1+((lSelSize-1)\lMaxPage) )
` Load the values and/or record numbers
⇒ SELECTION RANGE TO ARRAY (1+(lMaxPage*($lPage-1));lMaxPage*$lPage;...;...;
...;...;...;...)
` Do something with the arrays
End for
See Also
AUTOMATIC RELATIONS, ON ERR CALL, SELECTION TO ARRAY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY TO SELECTION copies one or more arrays into a selection of records.
All fields listed must belong to the same table.
If a selection exists at the time of the call, the elements of the array are put into the
records, based on the order of the array and the order of the records. If there are more
elements than records, new records are created. The records, whether new or existing, are
automatically saved.
If the arrays are of different sizes, the first array is used to determine how many elements
to copy. Any additional arrays are moved into the field that follows each array name.
This command does the reverse of SELECTION TO ARRAY. However, the ARRAY TO
SELECTION command does not allow fields from different tables, including related tables,
even when an automatic relation exists.
4D Server: The command is optimized for 4D Server. Arrays are sent by the client
machine to the server, and the records are modified or created on the server machine. As
such a request is handled synchronously, the client machine must wait for the operation
to be completed successfully. In the multi-user or multi-process environment, any records
that are locked will not be overwritten.
See Also
SELECTION TO ARRAY.
Description
The command DISTINCT VALUES creates and populates the array array with non-repeated
(unique) values coming from the field field for the current selection of the table to which
the field or subfield belongs.
You can pass to DISTINCT VALUES any indexable field or subfield, that is, whose type
supports indexing without necessarily being indexed.
However, executing this command on unindexed fields will be slower. Also note that, in
this case, the command looses the current record.
Note: As this command now functions with indexed and unindexed fields, its execution
mode can now be set by using the SET DATABASE PARAMETER command.
If you pass the field of a table, DISTINCT VALUES browses and retains the non-repeated
values present only in the currently selected records. However, if you pass a subfield,
DISTINCT VALUES browses all the subrecords present in each currently selected record.
Note: Starting from 4D 6.5, when the DISTINCT VALUES command is called during a
transaction (that has not yet finished), it will take into account records created during
that transaction.
If you create the array prior to the call, DISTINCT VALUES expects an array type compatible
with the field or subfield you pass. Otherwise, in interpreted mode, DISTINCT VALUES will
create an array of the proper type. However, if the field or subfield is of type Time, the
command expects or creates a LongInt array.
After the call, the size of the array is equal to the number of distinct values found in the
selection. The command does not change the current selection or the current record. The
DISTINCT VALUES command uses the index of the field, so the elements in array are
returned sorted in ascending order. If this is the order you need, you do not need to call
SORT ARRAY after using DISTINCT VALUES.
4D Server: The command is optimized for 4D Server. The array is created and the values
are calculated on the server machine; the array is then sent, in its entirety, to the client.
Examples
1. The following example creates a list of cities from the current selection and tells the
user the number of cities in which the firm has stores:
ALL RECORDS([Retail Outlets]) ` Create a selection of records
⇒ DISTINCT VALUES([Retail Outlets]City;asCities)
ALERT("The firm has stores in " +String(Size of array(asCities))+" cities.")
2. The following example returns in asKeywords all the keywords that are attached (using
a subtable) to the 4D Write documents stored in the table [Documentation] and whose
theme is “Economy”:
QUERY ([Documentation];[Documentation]Theme="Economy")
⇒ DISTINCT VALUES([Documentation]Keywords'Keyword;asKeywords)
After this array has been built, you can reuse it to quickly locate all the documents
associated with the selected keyword:
QUERY
([Documentation];[Documentation]Keywords'Keyword=asKeywords{asKeywords})
SELECTION TO ARRAY ([Documentation]Subject;asSubjects)
` ...
See Also
ON ERR CALL, SELECTION RANGE TO ARRAY, SELECTION TO ARRAY, SET DATABASE
PARAMETER.
Description
The command LONGINT ARRAY FROM SELECTION fills the recordArray array with the
(absolute) record numbers that are in selection.
If you do not pass the selection parameter, the command will use the current selection of
table.
Note: The array element number 0 is initialized to -1.
See Also
CREATE SELECTION FROM ARRAY.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BOOLEAN ARRAY FROM SET fills an array of booleans indicating if each
record in the table is or is not in set.
The elements in the array are ordered in the order in which the records are created in the
table (absolute record numbers). If N is the number of records in the table, element 0 of
the array corresponds to record number 0, element 1 of the array corresponds to record
number 1, etc.
Warning: The total number of elements in the booleanArr array is not significant. For
structural reasons, this number can be different from the number of records actually
present in the table. Possible extra elements are set to False.
If you don’t pass the set parameter, the command will use UserSet in the current process.
See Also
CREATE SET FROM ARRAY.
BLOB
Definition
4th Dimension version 6 introduces the BLOB (Binary Large OBjects) data type.
Within 4th Dimension, a BLOB is a contiguous series of variable length bytes, which can
be treated as one whole object or whose bytes can be addressed individually. A BLOB can
be empty (null length) or can contain up to 2147483647 bytes (2 GB).
Like the other field types that can retain a large amount of data (Picture and subtable field
types), BLOB fields are not duplicated in memory when you modify a record.
Consequently, the result returned by the commands Old and Modified is not significant
when applied to a BLOB field.
Displaying BLOBs
A BLOB can retain any type of data, so it has no default representation on the screen. If
you display a BLOB field or variable in a form, it will always appear blank, whatever its
contents.
BLOB fields
You can use BLOB fields to store any kind of data, up to 2 GB. You cannot index a BLOB
field, so you must use a formula in order to search records on values stored in a BLOB
field. Do not use BLOB fields for storing data that you want to retrieve quickly with a
search operation. For example, do not store keywords in a BLOB field; instead, use a subfile
in which you can index the keyword subfield.
To pass a BLOB to your own methods, define a pointer to the BLOB and pass the pointer
as parameter.
Examples:
` Declare a variable of type BLOB
C_BLOB (anyBlobVar)
` The BLOB is passed as parameter to a 4D command
SET BLOB SIZE (anyBlobVar;1024*1024)
` The BLOB is passed as parameter to an external routine
$errCode:= Do Something With This BLOB (anyBlobVar)
` A pointer to the BLOB is passed as parameter to a user method
COMPUTE BLOB (->anyBlobVar )
` Declare a variable of type Pointer
C_POINTER (aPointer)
` Define a pointer to the BLOB
aPointer := ->anyBlobVar
` A pointer to the BLOB is passed as parameter to a user method
COMPUTE BLOB (aPointer)
Note for Plug-ins developers: A BLOB parameter is declared as “&O” (the letter “O”, not
the digit “0”).
Assignment
You can assign BLOBs to each other.
Example:
` Declare two variables of type BLOB
C_BLOB (vBlobA;vBlobB)
` Set the size of the first BLOB to 10K
SET BLOB SIZE (vBlobA;10*1024)
` Assign the first BLOB to the second one
vBlobB:=vBlobA
Because you can address all the bytes of a BLOB individually, you can actually store
whatever you want in a BLOB field or variable.
In addition:
• C_BLOB declares a variable of type BLOB. Refer to the Compiler chapter for more
information.
• GET CLIPBOARD and APPEND CLIPBOARD enable you to deal with any data type stored
in the Clipboard. Refer to the Clipboard chapter for more information.
• GET RESOURCE and SET RESOURCE enable you to work with any type stored of resource
stored on disk. Refer to the Resources chapter for more information.
• SEND HTML BLOB enable you to send any type of data to a Web browser. Refer to the
Web Server chapter for more information.
• PICTURE TO BLOB, BLOB TO PICTURE and PICTURE TO GIF allow you to open and
convert pictures. Refer to the Pictures chapter for more information.
• GENERATE ENCRYPTION KEYPAIR and GENERATE CERTIFICATE REQUEST are encryption
commands used by the SSL (Secured Socket Layer) secured connection protocol. Refer to
the Secured Protocol chapter for more information.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET BLOB SIZE resizes the BLOB blob according to the value passed in size.
If you want to allocate new bytes to a BLOB and want to have those bytes initialized to a
specific value, pass the value (0..255) into the filler optional parameter.
Examples
1. When you are through with a large process or interprocess BLOB, it is good idea to free
the memory it occupies. To do so, write:
See Also
BLOB size.
Error Handling
If you cannot resize a BLOB due to insufficient memory, the error -108 is generated. You
can trap this error using an ON ERR CALL interruption method.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
BLOB size returns the size of blob expressed in bytes.
Examples
The line of code adds 100 bytes to the BLOB myBlob:
⇒ SET BLOB SIZE (BLOB size(myBlob)+100)
See Also
SET BLOB SIZE.
Description
The COMPRESS BLOB command compresses the BLOB blob using the internal
4th Dimension compression algorithm. This command only compresses BLOB whose size
is over 255 bytes.
The optional compression parameter allows to set the way the BLOB will be compressed:
• If you pass 1, the BLOB is compressed as much as possible, at the expanse of the speed of
compression and decompression operations.
• If you pass 2, the BLOB is compressed as fast as possible (and will be decompressed as fast
as possible), at the expense of the compression ratio (the compressed BLOB will be bigger).
• If you pass another value or if you omit the parameter, the BLOB is compressed as much
as possible, using the compression mode 1.
After the call, the OK variable is set to 1 if the BLOB has been successfully compressed. If
the compression could not be performed, the OK variable is set to 0. If the compression
could not be performed because of a lack of memory or because the actual size of the blob
is less than 255 bytes, no error is generated and the method resumes its execution.
In any other cases (i.e. the BLOB is damaged), the error -10600 is generated. This error can
be trapped using the ON ERR CALL command.
After a BLOB has been compressed, you can expand it using the EXPAND BLOB command.
To detect if a BLOB has been compressed, use the BLOB PROPERTIES command.
WARNING: A compressed BLOB is still a BLOB, so there is nothing to stop you from
modifying its contents. However, if you do so, the EXPAND BLOB command will not be
able to decompress the BLOB properly.
Note however, that if you apply COMPRESS BLOB to an already compressed BLOB, the
command detects it and does nothing.
2. This example allows you to select a document and then compress it:
$vhDocRef := Open document ("")
If (OK=1)
CLOSE DOCUMENT ($vhDocRef)
DOCUMENT TO BLOB (Document;vxBlob)
If (OK=1)
⇒ COMPRESS BLOB (vxBlob)
If (OK=1)
BLOB TO DOCUMENT (Document;vxBlob)
End if
End if
End if
See Also
BLOB PROPERTIES, EXPAND BLOB.
Description
The EXPAND BLOB command expands the BLOB blob that was previously compressed
using the COMPRESS BLOB command.
After the call, the OK variable is set to 1 if the BLOB has been expanded. If the expansion
could not be performed, the OK variable is set to 0.
To check if a BLOB has been compressed, use the BLOB PROPERTIES command.
Examples
1. This example tests if the BLOB vxMyBlob is compressed and, if so, expands it:
BLOB PROPERTIES (vxMyBlob;$vlCompressed;$vlExpandedSize;$vlCurrentSize)
If ($vlCompressed#Is not compressed)
⇒ EXPAND BLOB (vxMyBlob)
End if
2. This example allows you to select a document and then expand it, if it is compressed:
$vhDocRef := Open document ("")
If (OK=1)
CLOSE DOCUMENT ($vhDocRef)
DOCUMENT TO BLOB (Document;vxBlob)
If (OK=1)
BLOB PROPERTIES (vxBlob;$vlCompressed;$vlExpandedSize;$vlCurrentSize)
If ($vlCompressed#Is not compressed)
⇒ EXPAND BLOB (vxBlob)
If (OK=1)
BLOB TO DOCUMENT (Document;vxBlob)
End if
End if
End if
End if
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The BLOB PROPERTIES command returns information about the BLOB blob.
• The compressed parameter tells whether or not the BLOB is compressed, and returns one
of the following values. Note: 4th Dimension provides the predefined constants.
Constant Type Value
Is not compressed Long Integer 0
Compact compression mode Long Integer 1
Fast compression mode Long Integer 2
• Whatever the compression status of the BLOB, the expandedSize parameter returns the
size of the BLOB when it is not compressed.
• The parameter currentSize returns the current size of the BLOB. If the BLOB is
compressed, you will usually obtain currentSize less than expandedSize. If the BLOB is not
compressed, you will always obtain currentSize equal to expandedSize.
2. After a BLOB has been compressed, the following project method obtains the
percentage of space saved by the compression:
` Space saved by compression project method
` Space saved by compression (Pointer {; Pointer } ) -> Long
` Space saved by compression ( -> BLOB {; -> savedBytes } ) -> Percentage
C_POINTER ($1;$2)
C_LONGINT ($0;$vlCompressed;$vlExpandedSize;$vlCurrentSize)
After this method has been added to your application, you can use it this way:
` ...
COMPRESS BLOB (vxBlob)
$vlPercent:=Space saved by compression (->vxBlob;->vlBlobSize)
ALERT ("The compression saved "+String (vlBlobSize)+" bytes, so "+String
($vlPercent;"#0%")+" of space.")
See Also
COMPRESS BLOB, EXPAND BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DOCUMENT TO BLOB loads the whole contents of document into blob. You must pass the
name of an existing document that is not already open, otherwise an error will be
generated. To let the user choose the document to be loaded into the BLOB, use the
command Open document and the process variable document (see Example).
Note regarding Macintosh: Macintosh documents can be composed of two forks: the
Data fork and the Resource fork. By default, the command DOCUMENT TO BLOB loads
the Data fork of the document. To load the Resource fork of the document instead, pass
the optional * parameter. On Windows, the optional * parameter is ignored. Note that the
4D environment provides the equivalent of MacOS resource forks on Windows. For
example, the data fork of a 4D database is stored in a file with the file extension .4DB; the
resource fork is stored in a file with the same name and the file extension .RSR. On
Windows, if you write a 4D application with the data fork and resource fork stored in
BLOBs, you just need to access the file corresponding to the fork with which you want to
work.
Example
You write an Information System that enables you to quickly store and retrieve
documents. In a data entry form, you create a button that allows you to load a document
into a BLOB field. The method for this button could be:
$vhDocRef:=Open document("") ` Select the document of your choice
If (OK=1) ` If a document has been chosen
CLOSE DOCUMENT($vhDocRef) ` We don't need to keep it open
⇒ DOCUMENT TO BLOB (Document;[YourTable]YourBLOBField)
If (OK=0)
` Handle error
End if
End if
System Variables
OK is set to 1 if the document is correctly loaded, otherwise OK is set to 0 and an error is
generated.
Error Handling
• If you try to load (into a BLOB) a document that does not exist or that is already open
by another process or application, the appropriate File Manager error is generated.
• An I/O error can occur if the document is locked, located on a locked volume, or if there
is problem in reading the document.
• If there is not enough memory to load the document, an error -108 is generated.
In each case, you can trap the error using an ON ERR CALL interruption method.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
BLOB TO DOCUMENT rewrites the whole contents of document using the data stored in
blob. If you want to let the user choose the document, use the commands Open document
or Create document and use the process variable document (see example).
Note regarding Macintosh: Macintosh documents can be composed of two forks: the
Data fork and the Resource fork. By default, the command BLOB TO DOCUMENT rewrites
the Data fork of the document. To rewrite the Resource fork of the document instead,
pass the optional * parameter. On Windows, the optional * parameter is ignored. Note
that the 4D environment provides the equivalent of MacOS resource forks on Windows.
For example, the data fork of a 4D database is stored in a file with the file extension .4DB;
the resource fork is stored in a file with the same name and the file extension .RSR. On
Windows, if you write a 4D application with the data fork and resource fork stored in
BLOBs, you just need to access the file corresponding to the fork with which you want to
work.
Example
You write an Information System that enables you to quickly store and retrieve
documents. In a data entry form, you create a button which allows you to save a
document that will contain the data previously loaded into a BLOB field. The method for
this button could be:
$vhDocRef:=Create document("") ` Save the document of your choice
If (OK=1) ` If a document has been created
CLOSE DOCUMENT($vhDocRef) ` We don't need to keep it open
⇒ BLOB TO DOCUMENT (Document;[YourTable]YourBLOBField)
` Write the document contents
If (OK=0)
` Handle error
End if
End if
System Variables
OK is set to 1 if the document is correctly written, otherwise OK is set to 0 and an error is
generated.
Error Handling
• If you try to rewrite a document that does not exist or that is already open by another
process or application, the appropriate File Manager error is generated.
• The disk space may be insufficient for writing the new contents of the document.
• I/O errors can occur while writing the document.
In all cases, you can trap the error using an ON ERR CALL interruption method.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command VARIABLE TO BLOB stores the variable variable in the BLOB blob.
If you specify the * optional parameter, the variable is appended to the BLOB and the size
of the BLOB is extended accordingly. Using the * optional parameter, you can sequentially
store any number of variables or lists (see other BLOB commands) in a BLOB, as long as
the BLOB fits into memory.
If you do not specify the * optional parameter or the offset variable parameter, the
variable is stored at the beginning of the BLOB, overriding its previous contents; the size
of the BLOB is adjusted accordingly.
If you pass the offset variable parameter, the variable is written at the offset (starting from
zero) within the BLOB. No matter where you write the variable, the size of the BLOB is
increased according to the location you passed (plus the size of the variable, if necessary).
Newly allocated bytes, other than the ones you are writing, are initialized to zero.
After the call, the offset variable parameter is returned, incremented by the number of
bytes that have been written. Therefore, you can reuse that same variable with another
BLOB writing command to write another variable or list.
VARIABLE TO BLOB accepts any type of variable (including other BLOBs), except the
following:
• Pointer
• Array of pointers
• Two-dimensional arrays
However, if you store a Long Integer variable that is a reference to a hierarchical list
(ListRef), VARIABLE TO BLOB will store the Long Integer variable, not the list. To store and
retrieve hierarchical lists in and from a BLOB, use the commands LIST TO BLOB and BLOB
to list.
After the call, if the variable has been successfully stored, the OK variable is set to 1. If the
operation could not be performed, the OK variable is set to 0; for example, there was not
enough memory.
Note regarding Platform Independence: VARIABLE TO BLOB and BLOB TO VARIABLE use a
4D internal format for handling variables stored in BLOBs. As a benefit, you do not need
to worry about byte swapping between platforms while using these two commands. In
other words, a BLOB created on Windows using either of these commands can be reused
on Macintosh, and vice-versa.
Examples
1. The two following project methods allow you to quickly store and retrieve arrays into
and from documents on disk:
` SAVE ARRAY project method
` SAVE ARRAY ( String ; Pointer )
` SAVE ARRAY ( Document ; -> Array )
C_STRING (255;$1)
C_POINTER ($2)
C_BLOB ($vxArrayData)
⇒ VARIABLE TO BLOB ($2->;$vxArrayData) ` Store the array into the BLOB
COMPRESS BLOB ($vxArrayData) ` Compress the BLOB
BLOB TO DOCUMENT ($1;$vxArrayData) ` Save the BLOB on disk
After these methods have been added to your application, you can write:
ARRAY STRING (...;asAnyArray;...)
` ...
SAVE ARRAY ( $vsDocName;->asAnyArray)
` ...
LOAD ARRAY ( $vsDocName;->asAnyArray)
$vlOffset:=0
For ($vlParam;2;Count parameters)
⇒ BLOB TO VARIABLE ($1->;${$vlParam}->;$vlOffset)
End for
After these methods have been added to your application, you can write:
STORE VARIABLES INTO BLOB ( ->vxBLOB;->vgPicture;->asAnArray;->alAnotherArray)
` ...
RETRIEVE VARIABLES FROM BLOB ( ->vxBLOB;->vgPicture;->asAnArray;->alAnotherArray)
See Also
BLOB to list, BLOB TO VARIABLE, LIST TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB TO VARIABLE rewrites the variable variable with the data stored within
the BLOB blob at the byte offset (starting at zero) specified by offset.
The BLOB data must be consistent with the destination variable. Typically, you will use
BLOBs that you previously filled out using the command VARIABLE TO BLOB.
If you do not specify the optional offset parameter, the variable data is read starting from
the beginning of the BLOB. If you deal with a BLOB in which several variables have been
stored, you must pass the offset parameter and, in addition, you must pass a numeric
variable. Before the call, set this numeric variable to the appropriate offset. After the call,
that same numeric variable returns the offset of the next variable stored within the BLOB.
After the call, if the variable has been successfully rewritten, the OK variable is set to 1. If
the operation could not be performed, the OK variable is set to 0; for example, if there
was not enough memory.
Note regarding Platform Independence: BLOB TO VARIABLE and VARIABLE TO BLOB use a
4D internal format for handling variables stored in BLOBs. As a benefit, you do not need
to worry about byte swapping between platforms while using these two commands. In
other words, a BLOB created on Windows using either of these commands can be reused
on Macintosh, and vice-versa.
Example
See the examples for the command VARIABLE TO BLOB.
See Also
VARIABLE TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command LIST TO BLOB stores the hierarchical list list in the BLOB blob.
If you specify the * optional parameter, the hierarchical list is appended to the BLOB and
the size of the BLOB is extended accordingly. Using the * optional parameter, you can
sequentially store any number of variables or lists (see other BLOB commands) in a BLOB,
as long as the BLOB fits into memory.
If you do not specify the * optional parameter, the hierarchical list is stored at the
beginning of the BLOB, overriding its previous contents; the size of the BLOB is adjusted
accordingly.
Wherever the hierarchical list is stored, the size of the BLOB will be increased if necessary
according to the specified location (plus up to the size of the list if necessary). Modified
bytes (other than the ones you set) are reset to 0 (zero).
WARNING: If you use a BLOB for storing lists, you must later use the command BLOB to
list for reading back the contents of the BLOB, because lists are stored in BLOBs using a
4D internal format.
After the call, if the list has been successfully stored, the OK variable is set to 1. If the
operation could not be performed, the OK variable is set to 0; for example, if there was
not enough memory.
Note regarding Platform Independence: LIST TO BLOB and BLOB to list use a 4D internal
format for handling lists stored in BLOBs. As a benefit, you do not need to worry about
byte swapping between platforms when using these two commands. In other words, a
BLOB created on Windows using those commands can be reused on Macintosh, and vice-
versa.
Examples
See example for the command BLOB to list.
See Also
BLOB to list, BLOB TO VARIABLE, VARIABLE TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB to list creates a new hierarchical list with the data stored within the
BLOB blob at the byte offset (starting at zero) specified by offset and returns a List
Reference number for that new list.
The BLOB data must be consistent with the command. Typically, you will use BLOBs that
you previously filled out using the command LIST TO BLOB.
If you do not specify the optional offset parameter, the list data is read starting from the
beginning of the BLOB. If you deal with a BLOB in which several variables or lists have
been stored, you must pass the offset parameter and, in addition, you must pass a numeric
variable. Before the call, set this numeric variable to the appropriate offset. After the call,
that same numeric variable returns the offset of the next variable stored within the BLOB.
After the call, if the hierarchical list has been successfully created, the OK variable is set to
1. If the operation could not be performed, the OK variable is set to 0; for example, if
there was not enough memory.
Note regarding Platform Independence: BLOB to list and LIST TO BLOB use a 4D internal
format for handling lists stored in BLOBs. As a benefit, you do not need to worry about
byte swapping between platforms when using these two commands. In other words, a
BLOB created on Windows using those two commands can be reused on Macintosh and
vice-versa.
Case of
: (bValidate=1)
⇒ LIST TO BLOB(hList;[Things To Do]Other Crazy Ideas)
End case
See Also
LIST TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command INTEGER TO BLOB writes the 2-byte Integer value integer into the BLOB
blob.
The byteOrder parameter fixes the byte ordering of the 2-byte Integer value to be written.
You pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
Native byte ordering Long Integer 0
Macintosh byte ordering Long Integer 1
PC byte ordering Long Integer 2
Note regarding Platform Independence: If you exchange BLOBs between the Macintosh
and PC platforms, it is up to you to manage byte swapping issues when using this
command.
If you specify the * optional parameter, the 2-byte Integer value is appended to the BLOB
and the size of the BLOB is extended accordingly. Using the * optional parameter, you can
sequentially store any number of Integer, Long Integer, Real or Text values (see other BLOB
commands) in a BLOB, as long as the BLOB fits into memory.
If you do not specify the * optional parameter or the offset variable parameter, the 2-byte
Integer value is stored at the beginning of the BLOB, overriding its previous contents; the
size of the BLOB is adjusted accordingly.
If you pass the offset variable parameter, the 2-byte Integer value is written at the byte
offset (starting from zero) within the BLOB. No matter where you write the 2-byte
Integer value, the size of the BLOB is increased according to the location you passed (plus
up to 2 bytes, if necessary). Newly allocated bytes, other than the ones you are writing,
are initialized to zero.
Examples
1. After executing this code:
⇒ INTEGER TO BLOB (0x0206;vxBlob;Native byte ordering)
• The size of vxBlob is 2 bytes
• On Macintosh vxBLOB{0} = $02 and vxBLOB{1} = $06
• On PC vxBLOB{0} = $06 and vxBLOB{1} = $02
See Also
BLOB to integer, BLOB to longint, BLOB to real, BLOB to text, LONGINT TO BLOB, REAL TO
BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command LONGINT TO BLOB writes the 4-byte Long Integer value integer into the
BLOB blob.
The byteOrder parameter fixes the byte ordering of the 4-byte Long Integer value to be
written. You pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
Native byte ordering Long Integer 0
Macintosh byte ordering Long Integer 1
PC byte ordering Long Integer 2
Note regarding Platform Independence: If you exchange BLOBs between Macintosh and
PC platforms, it is up to you to manage byte swapping issues while using this command.
If you specify the * optional parameter, the 4-byte Long Integer value is appended to the
BLOB and the size of the BLOB is extended accordingly. Using the * optional parameter,
you can sequentially store any number of Integer, Long Integer, Real or Text values (see
other BLOB commands) in a BLOB, as long as the BLOB fits into memory.
If you do not specify the * optional parameter nor the offset variable parameter, the 4-
byte Long Integer value is stored at the beginning of the BLOB, overriding its previous
contents; the size of the BLOB is adjusted accordingly.
If you pass the offset variable parameter, the 4-byte Long Integer value is written at the
offset (starting from zero) within the BLOB. No matter where you write the 4-byte Long
Integer value, the size of the BLOB is increased according to the location you passed (plus
up to 4 bytes, if necessary). New allocated bytes, other than the ones you are writing, are
initialized to zero.
Examples
1. After executing this code:
⇒ LONGINT TO BLOB (0x01020304;vxBlob;Native byte ordering)
• The size of vxBlob is 4 bytes
• On Macintosh vxBLOB{0}=$01, vxBLOB{1}=$02, vxBLOB{2}=$03, vxBLOB{3}=$04
• On PC vxBLOB{0}=$04, vxBLOB{1}=$03, vxBLOB{2}=$02, vxBLOB{3}=$01
See Also
BLOB to integer, BLOB to longint, BLOB to real, BLOB to text, INTEGER TO BLOB, REAL TO
BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command REAL TO BLOB writes the Real value real into the BLOB blob.
The realFormat parameter fixes the internal format and byte ordering of the Real value to
be written. You pass one of the following predefined constants provided by 4th
Dimension:
Constant Type Value
Native real format Long Integer 0
Extended real format Long Integer 1
Macintosh double real format Long Integer 2
PC double real format Long Integer 3
If you specify the * optional parameter, the Real value is appended to the BLOB; the size
of the BLOB is extended accordingly. Using the * optional parameter, you can sequentially
store any number of Integer, Long Integer, Real or Text values (see other BLOB commands)
in a BLOB, as long as the BLOB fits into memory.
If you do not specify the * optional parameter or the offset variable parameter, the Real
value is stored at the beginning of the BLOB, overriding its previous contents; the size of
the BLOB is adjusted accordingly.
After the call, the offset variable parameter is returned, incremented by the number of
bytes that have been written. Therefore, you can reuse that same variable with another
BLOB writing command to write another value.
Examples
1. After executing this code:
C_REAL (vrValue)
vrValue := ...
⇒ REAL TO BLOB (vrValue;vxBlob;Native real format)
• On PC and Power Macintosh, the size of vxBlob is 8 bytes
• On Macintosh 68K, the size of vxBlob is 10 bytes
See Also
BLOB to integer, BLOB to longint, BLOB to real, BLOB to text, INTEGER TO BLOB, LONGINT
TO BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command TEXT TO BLOB writes the Text value text into the BLOB blob.
The textFormat parameter fixes the internal format of the text value to be written. You
pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
C string Long Integer 0
Pascal string Long Integer 1
Text with length Long Integer 2
Text without length Long Integer 3
Note: The command accepts both Text (declared with C_TEXT) and String (declared with
C_STRING) expressions. Remember that a Text variable can contain up to 32,000
characters and a String variable can contain up to the number of characters in its
declaration, with a maximum of 255 characters.
If you specify the * optional parameter, the Text value is appended to the BLOB; the size
of the BLOB is extended accordingly. Using the * optional parameter, you can sequentially
store any number of Integer, Long Integer, Real or Text values (see other BLOB commands)
in a BLOB, as long as the BLOB fits into memory.
If you do not specify the * optional parameter nor the offset variable parameter, the Text
value is stored at the beginning of the BLOB, overriding its previous contents; the size of
the BLOB is adjusted accordingly.
If you pass the offset variable parameter, the Text value is written at the offset (starting
from zero) within the BLOB. No matter where you write the Text value, the size of the
BLOB is, increased according to the location you passed (plus up to the size of the text, if
necessary). New allocated bytes, other than the ones you are writing, are initialized to
zero.
After the call, the offset variable parameter is returned, incremented by the number of
bytes that have been written. Therfore, you can reuse that same variable with another
BLOB writing command to write another value.
Example
After executing this code:
SET BLOB SIZE (vxBlob;0)
C_TEXT (vtValue)
vtValue := "Hello World!" ` Length of vtValue is 12 bytes
⇒ TEXT TO BLOB (vtValue;vxBlob;C string) ` Size of BLOB becomes 13 bytes
⇒ TEXT TO BLOB (vtValue;vxBlob;Pascal string) ` Size of BLOB becomes 13 bytes
⇒ TEXT TO BLOB (vtValue;vxBlob;Text with length) ` Size of BLOB becomes 14 bytes
⇒ TEXT TO BLOB (vtValue;vxBlob;Text without length) ` Size of BLOB becomes 12 bytes
See Also
BLOB to integer, BLOB to longint, BLOB to real, BLOB to text, INTEGER TO BLOB, LONGINT
TO BLOB, REAL TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB to integer returns a 2-byte Integer value read from the BLOB blob.
The byteOrder parameter fixes the byte ordering of the 2-byte Integer value to be read.
You pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
Native byte ordering Long Integer 0
Macintosh byte ordering Long Integer 1
PC byte ordering Long Integer 2
Note regarding Platform Independence: If you exchange BLOBs between Macintosh and
PC platforms, it is up to you to manage byte swapping issues when using this command.
If you specify the optional offset variable parameter, the 2-byte Integer value is read at
the offset (starting from zero) within the BLOB. If you do not specify the optional offset
variable parameter, the first two bytes of the BLOB are read.
Note: You should pass an offset (in bytes) value between 0 (zero) and the size of the BLOB
minus 2. If you do not do so, an error -111 is generated.
After the call, the variable is incremented by the number of bytes read, Therefore, you
can reuse that same variable with another BLOB reading command to read another value.
See Also
BLOB to longint, BLOB to real, BLOB to text, INTEGER TO BLOB, LONGINT TO BLOB, REAL
TO BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB to longint returns a 4-byte Long Integer value read from the BLOB
blob.
The byteOrder parameter fixes the byte ordering of the 4-byte Long Integer value to be
read. You pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
Native byte ordering Long Integer 0
Macintosh byte ordering Long Integer 1
PC byte ordering Long Integer 2
Note regarding Platform Independence: If you exchange BLOBs between Macintosh and
PC platforms, it is up to you to manage byte swapping issues while using this command.
If you specify the optional offset variable parameter, the 4-byte Long Integer is read at
the offset (starting from zero) within the BLOB. If you do not specify the optional offset
variable parameter, the first four bytes of the BLOB are read.
Note: You should pass an offset value between 0 (zero) and the size of the BLOB minus 4.
If you do not do so, an error -111 is generated.
After the call, the variable is incremented by the number of bytes read. Therefore, you
can reuse that same variable with another BLOB reading command to read another value.
See Also
BLOB to integer, BLOB to real, BLOB to text, INTEGER TO BLOB, LONGINT TO BLOB, REAL
TO BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB to real returns a Real value read from the BLOB blob.
The realFormat parameter fixes the internal format and byte ordering of the Real value to
be read. You pass one of the following predefined constants provided by 4th Dimension:
Constant Type Value
Native real format Long Integer 0
Extended real format Long Integer 1
Macintosh double real format Long Integer 2
PC double real format Long Integer 3
Note regarding Platform Independence: If you exchange BLOBs between Macintosh and
PC platforms, it is up to you to manage real formats and byte swapping issues while using
this command.
If you specify the optional offset variable parameter, the Read value is read at the offset
(starting from zero) within the BLOB. If you do not specify the optional offset variable
parameter, the first 8 or 10 bytes of the BLOB are read.
Note: You should pass an offset value between 0 (zero) and the size of the BLOB minus 8
or 10. If you do not do so, an error -111 is generated.
After the call, the variable is incremented by the number of bytes read. Therefore, you
can reuse that same variable with another BLOB reading command to read another value.
See Also
BLOB to integer, BLOB to longint, BLOB to text, INTEGER TO BLOB, LONGINT TO BLOB,
REAL TO BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB to text returns a Text value read from the BLOB blob.
The textFormat parameter fixes the internal format of the text value to be read. You pass
one of the following predefined constants provided by 4th Dimension:
Constant Type Value
C string Long Integer 0
Pascal string Long Integer 1
Text with length Long Integer 2
Text without length Long Integer 3
Remember that a Text variable can contain up to 32,000 characters and a String variable
can contain up to the number of characters in its declaration, with a maximum of 255
characters. If you try to read more data than a variable can hold, 4D will truncate the
result of the command when placing it into the variable.
If you specify the optional offset variable parameter, the Text value is read at the offset
(starting from zero) within the BLOB. If you do not specify the optional offset variable
parameter, the beginning of the BLOB is read according to the value you pass in
textFormat. Note that you must pass the offset variable parameter when you are reading
text without length.
Note: You should pass an offset value between 0 (zero) and the size of the BLOB minus
the size of the text to be read. If you do not do so, the function result is unpredictable.
After the call, the variable is incremented by the number of bytes read. Therefore, you
can reuse that same variable with another BLOB reading command to read another value.
Example
The following example reads an hypothetical MacOS-based resource whose internal
format is identical to that of the 'STR#' resources:
GET RESOURCE ("ABCD";viResID;vxResData;viMyResFile)
vlSize:=BLOB Size(vxResData)
If (vlSize>0)
` The resource starts with a 2-byte integer specifying the number of strings
vlOffset:=0
viNbEntries:=BLOB to integer(vxResData;Macintosh Byte Ordering;vlOffset)
` Then the resource contains concatenated, not padded, Pascal strings
For (viEntry;1;viNbEntries)
If (vlOffset<vlSize)
⇒ vsEntry:=BLOB to text(vxResData;Pascal string;vlOffset)
` Do something with vsEntry
Else
` Resource data is invalid, get out of the loop
viEntry:=viNbEntries+1
End if
End for
End if
See Also
BLOB to integer, BLOB to longint, BLOB to real, INTEGER TO BLOB, LONGINT TO BLOB, REAL
TO BLOB, TEXT TO BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command INSERT IN BLOB inserts the number of bytes specified by len into the BLOB
blob at the position specified by offset. The BLOB then becomes len bytes larger.
If you do not specify the optional filler parameter, the bytes inserted into the BLOB are set
to 0x00. Otherwise, the bytes are set to the value you pass in filler (modulo 256 — 0..255).
Before the call, you pass in the offset variable parameter the position of the insertion
relative to the beginning of the BLOB.
See Also
DELETE FROM BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE FROM BLOB deletes the number of bytes specified by len from the
BLOB blob at the position specified by offset (expressed relative to the beginning of the
BLOB). The BLOB then becomes len bytes smaller.
See Also
INSERT IN BLOB.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The COPY BLOB command copies the number of bytes specified by len from the BLOB
srcBLOB to the BLOB dstBLOB.
The copy starts at the position (expressed relative to the beginning of the source BLOB)
specified by srcOffset and takes place at the position (expressed relative to the beginning
of the destination BLOB) specified by dstOffset.
See Also
DELETE FROM BLOB, INSERT IN BLOB.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ENCRYPT BLOB encrypts the content of the toEncrypt BLOB with the
sender’s private key sendPrivKey, as well as optionally the recipient’s public key
recipPubKey. These keys should be generated by the command GENERATE ENCRYPTION
KEYPAIR (within the “Secured Protocol” theme).
Note: This command uses the SSL protocol algorithm and encryption features. To be able
to use this command, make sure that the components necessary to the SSL protocol are
installed properly on your machine — even though you do not want to use SSL for 4D
Web server connections. For detailed information on this protocol, please refer to section
Web Services, Using SSL Protocol.
• If one key is used for the encryption (the sender’s private key), only people in
possession of the public key will be able to read the information. This system guarantees
that the sender himself has encrypted the information.
• The simultaneous use of the sender’s private key and recipient’s public key guarantees
that only one recipient will be able to read the information.
The BLOB containing the keys has a PKCS internal forma. This standard cross platform
format allows exchanging or handling keys simply by copy-pasting in an Email or a text
file.
Once the command has been run, the toEncrypt BLOB contains the encrypted data that
will be decrypted only with the DECRYPT BLOB command, with the sender’s public key
passed as parameter.
Moreover, if the optional recipient’s public key has been used to encrypt the information,
the recipient’s private key will also be necessary for decrypting.
Note: The cipher contains a checksum functionality in order to avoid any BLOB content
modification (deliberately or not). Consequently, an encrypted BLOB should not be
modified otherwise it might not be decrypted.
1. The company generates a pair of keys with the command GENERATE ENCRYPTION
KEYPAIR:
`Method GENERATE_KEYS_TXT
C_BLOB($BPublicKey; $BPrivateKey)
GENERATE ENCRYPTION KEYPAIR($BPrivateKey; $BPublicKey)
BLOB TO DOCUMENT("PublicKey.txt"; $BPublicKey)
BLOB TO DOCUMENT("PrivateKey.txt"; $BPrivateKey)
2. The company keeps the private key and sends a copy of the document containing the
public key to each subsidiary. For maximum security, the key should be copied on a disk
handed over to the subsidiaries.
3. Then the company copies the private information (stored in the text field, for
example) in BLOBs which will be encrypted with the private key:
`Method ENCRYPT_INFO
C_BLOB($vbEncrypted;$vbPrivateKey)
C_TEXT($vtEncrypted)
$tvEncrypted:=[Private]Info
VARIABLE TO BLOB ($vtEncrypted;$vbEncrypted)
DOCUMENT TO BLOB("PrivateKey.txt"; $vbPrivateKey)
If(OK=1)
⇒ ENCRYPT BLOB ($vbEncrypted; $vbPrivateKey
BLOB TO DOCUMENT ("Update.txt";$vbEncrypted)
End if
4. The update files can be sent to the subsidiaries (though a non-secured channel such as
the Internet). If a third person gets hold of the encrypted file, he will not be able to
decrypt it without the public key.
5. Each subsidiary can decrypt the document with the public key:
`Method DECRYPT_INFO
C_BLOB($vbEncrypted;$vbPublicKey)
C_TEXT($vtDecrytped)
C_TIME ($vtDocRef)
• Using keypairs
A company wants to use the Internet to exchange information. Each subsidiary receives
private information and also sends information to the corporate office. Consequently
there are two requirements:
- The recipient only should be able to read the message,
- The recipient must have proof that the message was sent by the sender himself.
1. The corporate office and each subsidiary generate their own key pairs (with the
GENERATE_KEYS_TXT method).
2. The private key is kept secret by both sides. Each subsidiary sends its public key to the
corporate office who, in its turn, sends its public key too. This key transfer does not need
to be done through a secured channel as the public key is not enough to decrypt the
message.
3. To encrypt the information to send, the subsidiary or the corporate house executes the
ENCRYPT_INFO_2 method which uses the sender’s private key and the recipient’s public
key to encrypt the information:
`Method ENCRYPT_INFO_2
C_BLOB($vbEncrypted;$vbPrivateKey;$vbPublicKey)
C_TEXT($vtEncrypt)
C_TIME ($vtDocRef)
$vtEncrypt:= [Private]Info
VARIABLE TO BLOB ($vtEncrypt;$vbEncrypted)
` Your own private key is loaded...
DOCUMENT TO BLOB("PrivateKey.txt"; $vbPrivateKey)
If (OK=1)
` ...and the recipient’s public key
ALERT ("Please select the recipient’s public key.")
$vhDocRef:=Open document("") `Public key to load
4. The encrypted file can then be sent to the recipient via the Internet. If a third person
gets hold of it, he or she will not be able to decrypt the message, even if he or she has the
public keys as the recipient’s private key will also be required.
5. Each recipient can decrypt the document by using his/her own private key and the
sender’s public key:
`Method DECRYPT_INFO_2
C_BLOB($vbEncrypted;$vbPublicKey;$vbPrivateKey)
C_TEXT($vtDecrypted)
C_TIME ($vhDocRef)
See Also
DECRYPT BLOB, GENERATE ENCRYPTION KEYPAIR.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DECRYPT BLOB decrypts the content of the BLOB toDecrypt using the
sender’s public key sendPubKey and, optionally, the recipient’s private key recipPrivKey.
The BLOB containing the sender’s public key is passed in the sendPubKey parameter. This
key has been generated by the sender using the GENERATE ENCRYPTION KEYPAIR
command and it has to be sent to the recipient.
The BLOB containing the recipient’s private key can be passed in the optional parameter
recipPrivKey. In this case, the recipient has to generate a pair of encryption keys with the
GENERATE ENCRYPTION KEYPAIR command and has to send his/her public key to the
sender. The keypair-based encryption system guarantees that the message has been
encrypted by the sender only and it can be decrypted by the recipient only. For more
information about the keypair-based encryption system, refer to the routine ENCRYPT
BLOB.
The command DECRYPT BLOB offers a checksum functionality in order to avoid any
BLOB content modification (deliberate or not). If the encrypted BLOB is damaged or
modified, the command will do nothing and an error will be returned.
Example
Refer to the examples given for the ENCRYPT BLOB command.
See Also
ENCRYPT BLOB, GENERATE ENCRYPTION KEYPAIR.
Boolean
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Examples
This example sets a Boolean variable based on the value of a button. It returns True in
myBoolean if the myButton button was clicked and False if the button was not clicked.
When a button is clicked, the button variable is set to 1.
If (myButton=1) ` If the button was clicked
myBoolean:=True ` myBoolean is set to True
Else ` If the button was not clicked,
myBoolean:=False ` myBoolean is set to False
End if
See Also
False, Logical Operators, Not, True.
In addition, the following 4D commands return a Boolean result: Activated, After, Before,
Before selection, Before subselection, Caps lock down, Compiled application, Deactivated,
During, End selection, End subselection, In break, In footer, In header, In transaction, Is a list,
Is a variable, Is in set, Is user deleted, Locked, Macintosh command down, Macintosh control
down, Macintosh option down, Modified, Modified record, Nil, Outside call, Read only state,
Semaphore, Shift down, True, Undefined, User in group, Windows Alt down, Windows Ctrl
down.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
True → Boolean
Description
True returns the Boolean value True.
Example
The following example sets the variable vbOptions to True:
⇒ vbOptions:=True
See Also
False, Not.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
False → Boolean
Description
False returns the Boolean value False.
Example
The following example sets the variable vbOptions to False:
⇒ vbOptions:=False
See Also
Not, True.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Not function returns the negation of boolean, changing True to False or False to True.
Example
This example first assigns True to a variable, then changes the variable value to False, and
then back to True.
vResult:=True ` vResult is set to True
⇒ vResult:=Not(vResult) ` vResult is set to False
⇒ vResult:=Not(vResult) ` vResult is set to True
Clipboard
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The APPEND TO CLIPBOARD command appends to the Clipboard the data contained in
the BLOB data under the data type specified in dataType.
WARNING: The value you pass in dataType is case sensitive, i.e., “abcd” is not equal to
“ABCD.”
If the BLOB data is correctly appended to the Clipboard, the OK variable is set to 1.
Otherwise the OK variable is set to 0 and an error may be generated.
Usually, you will use the APPEND TO CLIPBOARD command to append multiple instances
of the same data to the Clipboard or to append data that is not of type TEXT or PICT. To
append new data to the Clipboard, you must first clear the Clipboard using the
CLEAR CLIPBOARD command.
However, note that if a BLOB actually contains some text or a picture, you can use the
APPEND TO CLIPBOARD command to append a text or a picture to the Clipboard.
Example
Using Clipboard commands and BLOBs, you can build sophisticated Cut/Copy/Paste
schemes that deal with structured data rather than a unique piece of data. In the
following example, the two project methods SET RECORD TO CLIPBOARD and GET
RECORD FROM CLIPBOARD enable you to treat a whole record as one piece of data to be
copied to or from the Clipboard.
C_LONGINT($1;$vlField;$vlFieldType)
C_POINTER($vpTable;$vpField)
C_STRING(255;$vsDocName)
C_TEXT($vtRecordData;$vtFieldData)
C_BLOB($vxRecordData)
` Clear the Clipboard (it will stay empty if there is no current record)
⇒ CLEAR CLIPBOARD
` Get a pointer to the table whose number is passed as parameter
$vpTable:=Table($1)
` If there is a current record for that table
If ((Record number($vpTable->)>=0) | (Record number($vpTable->)=-3))
` Initialize the text variable that will hold the text image of the record
$vtRecordData:=""
` For each field of the record:
For ($vlField;1;Count fields($1))
` Get the type of the field
GET FIELD PROPERTIES($1;$vlField;$vlFieldType)
` Get a pointer to the field
$vpField:=Field($1;$vlField)
` Depending on the type of the field, copy (or not) its data
` in the appropriate manner
Case of
: (($vlFieldType=Is Alpha field ) | ($vlFieldType=Is Text ))
$vtFieldData:=$vpField->
: (($vlFieldType=Is Real ) | ($vlFieldType=Is Integer ) |
($vlFieldType=Is LongInt ) | ($vlFieldType=Is Date ) | ($vlFieldType=Is Time ))
$vtFieldData:=String($vpField->)
: ($vlFieldType=Is Boolean )
$vtFieldData:=String(Num($vpField->);"Yes;;No")
Else
` Skip and ignore other field data types
$vtFieldData:=""
End case
` Accumulate the field data into the text variable holding
` the text image of the record
$vtRecordData:=$vtRecordData+Field name($1;$vlField)+":"+Char(9)
+$vtFieldData+CR
` Note: The method CR returns Char(13) on Macintosh
` and Char(13)+Char(10) on Windows
End for
` Put the text image of the record into the clipboard
SET TEXT TO CLIPBOARD($vtRecordData)
You can paste this image of the record to another record, using the method GET RECORD
FROM CLIPBOARD, as follows:
` GET RECORD FROM CLIPBOARD method
` GET RECORD FROM CLIPBOARD ( Number )
` GET RECORD FROM CLIPBOARD ( Table number )
C_LONGINT($1;$vlField;$vlFieldType;$vlPosCR;$vlPosColon)
C_POINTER($vpTable;$vpField)
C_STRING(255;$vsDocName)
C_BLOB($vxClipboardData)
C_TEXT($vtClipboardData;$vtFieldData)
See Also
CLEAR CLIPBOARD, SET PICTURE TO CLIPBOARD, SET TEXT TO CLIPBOARD.
System Variables
If the BLOB data is correctly appended to the clipboard, OK is set to 1; otherwise OK is set
to 0 and an error may be generated.
Error Handling
If there is not enough memory to append the BLOB data to the clipboard, an error -108 is
generated.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
CLEAR CLIPBOARD
Description
The CLEAR CLIPBOARD command clears the Clipboard of its contents. If the Clipboard
contains multiple instances of the same data, all instances are cleared. After a call to
CLEAR CLIPBOARD, the Clipboard becomes empty.
You must call CLEAR CLIPBOARD once before appending new data to the Clipboard using
the command APPEND TO CLIPBOARD, because this latter command does not clear the
Clipboard before appending the new data.
Calling CLEAR CLIPBOARD once and then calling APPEND TO CLIPBOARD several times
enables you to Cut or Copy the same data under different formats.
On the other hand, the commands SET TEXT TO CLIPBOARD and SET PICTURE TO
CLIPBOARD automatically clear the Clipboard before appending the TEXT or PICT data to
it.
Example
(1) The following code clears and then appends data to the clipboard:
See Also
APPEND TO CLIPBOARD.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET CLIPBOARD command returns into the BLOB field or into the variable data the
data present in the Clipboard and whose type you pass in dataType.
WARNING: The value you pass in dataType is case sensitive, i.e., “abcd” is not equal to
“ABCD.”
If the data is correctly extracted from the clipboard, the command sets the OK variable to
1. If the Clipboard is empty or does not contains any data of the specified type, the
command returns an empty BLOB, sets the OK variable to 0 and generates an error -102.
If there is not enough memory to extract the data from the clipboard,the command sets
the OK variable to 0 and generates an error -108.
Example
The following object methods for two buttons copy from and paste data to the array
asOptions (pop-up menu, drop-downlist,...) located in a form:
` bCopyasOptions object method
If (Size of array(asOptions)>0) ` Is there something to copy?
` Accumulate the array elements in a BLOB
VARIABLE TO BLOB (asOptions;$vxClipData)
CLEAR CLIPBOARD ` Empty the clipboard
APPEND TO CLIPBOARD ("artx";asOptions) ` Note the data type arbitrarily chosen
End if
System Variables
If the data is correctly extracted, OK is set to 1; otherwise OK is set to 0 and an error is
generated.
Error Handling
• If there is not enough memory to extract the data, an error -108 is generated.
• If there is no data of the requested type in the clipboard, an error -102 is generated.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GET PICTURE FROM CLIPBOARD returns the picture present in the Clipboard into the
picture field or variable picture.
If the picture is correctly extracted from the Clipboard, the command sets the OK variable
to 1. If the Clipboard is empty or does not contain a picture, the command returns an
empty picture, sets the OK variable to 0, and generates an error -102. If there is not
enough memory to extract the picture from the Clipboard, the command sets the OK
variable to 0 and generates an error -108.
Examples
The following button’s object method assigns the picture present in the Clipboard (if
any) to the field [Employees]Photo:
If (Test clipboard ("PICT")>0)
⇒ GET PICTURE FROM CLIPBOARD ([Employees]Photo)
Else
ALERT ("The clipboard does not contain any picture.")
End if
See Also
GET CLIPBOARD, Get text from clipboard, Test clipboard.
System Variables
If the picture is correctly extracted, OK is set to 1; otherwise OK is set to 0 and an error is
generated.
Error Handling
• If there is not enough memory to extract the picture, an error -108 is generated.
• If there is no picture in the Clipboard, an error -102 is generated.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Get text from clipboard returns the text present in the clipboard.
If the text is correctly extracted from the Clipboard, the command sets the OK variable to
1. If the Clipboard is empty or does not contain any text, the command returns an
empty string, sets the OK variable to 0, and generates an error -102. If there is not
enough memory to extract the text from the Clipboard, the command sets the OK
variable to 0 and generates an error -108.
4th Dimension text fields and variables can contain up to 32,000 characters. If there are
more than 32,000 characters in the Clipboard, the result returned by Get text from
clipboard will be truncated when placed into the field or variable receiving the value. To
handle very large Clipboard text contents, first test the size of the data using the
command Test clipboard. Then, if the text exceeds 32,000 characters, use the command
GET CLIPBOARD instead of Get text from clipboard.
Examples
The following example tests the for the presence of text in the Clipboard, then,
depending on the size of the data, extracts the text from the Clipboard as text or as a
BLOB:
$vlSize:=Test clipboard ("TEXT")
Case of
: ($vlSize<=0)
ALERT ("There is no text in the clipboard.")
: ($vlSize<=32000)
⇒ $vtClipData:=Get text from clipboard
If (OK=1)
` Do something with the text
End if
See Also
GET CLIPBOARD, GET PICTURE FROM CLIPBOARD, Test clipboard.
System Variables
If the text is correctly extracted, OK is set to 1; otherwise OK is set to 0 and an error is
generated.
Error Handling
• If there is not enough memory to extract the text, an error -108 is generated.
• If there is no text in the Clipboard, an error -102 is generated.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET PICTURE TO CLIPBOARD clears the Clipboard and puts a copy of the picture you passed
in picture into the Clipboard.
After you have put a picture into the Clipboard, you can retrieve it using the command
GET PICTURE FROM CLIPBOARD or by calling GET CLIPBOARD ("PICT";...).
If the picture is correctly put in the Clipboard, the OK variable is set to 1. If there is not
enough memory to put a copy of the picture into the Clipboard, the OK variable is set to
0, but no error is generated.
Example
Using a floating window, you display a form that contains the array asEmployeeName,
which lists the names of the employees from an [Employees] table. Each time you click
on a name, you want to copy the employee's picture to the Clipboard. In the object
method for the array, you write:
If (asEmployeeName#0)
QUERY ([Employees];[Employees]Last name=asEmployeeName{asEmployeeName})
If (Picture size ([Employees]Photo)>0)
⇒ SET PICTURE TO CLIPBOARD ([Employees]Photo) ` Copy the employee's photo
Else
CLEAR CLIPBOARD ` No photo or no record found
End if
End if
See Also
APPEND TO CLIPBOARD, GET PICTURE FROM CLIPBOARD.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET TEXT TO CLIPBOARD clears the clipboard and then puts a copy of the text you passed
in text into the Clipboard.
After you have put some text into the Clipboard, you can retrieve it using the Get text
from clipboard command or by calling GET CLIPBOARD ("TEXT";...).
If the text is correctly put in the Clipboard, the OK variable is set to 1. If there is not
enough memory to put a copy of the text into the Clipboard, the OK variable is set to 0,
but no error is generated.
4th Dimension text expressions can contain up to 32,000 characters. To copy larger text
values, accumulate the text into a BLOB, call CLEAR CLIPBOARD, then call APPEND TO
CLIPBOARD ("TEXT";...).
Example
See the example for the APPEND TO CLIPBOARD command.
See Also
APPEND TO CLIPBOARD, Get text from clipboard.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Test clipboard command allows you to test if there is data of the type you passed in
dataType present in the Clipboard.
WARNING: The value you pass in dataType is case sensitive, i.e., “abcd” is not equal to
“ABCD.”
If the Clipboard is empty or does not contain any data of the specified type, the
command returns an error -102 (see the table of predefined constants). If the Clipboard
contains data of the specified type, the command returns the size of this data, expressed
in bytes.
After you have detected that the Clipboard contains data of the type in which you are
interested, you can extract that data from the Clipboard using one the following
commands:
• If the Clipboard contains type TEXT data, you can obtain that data using the
Get text from clipboard command, which returns a text value, or the GET CLIPBOARD
command, which returns the text into a BLOB.
• If the Clipboard contains type PICT data, you can obtain that data using the
GET PICTURE FROM CLIPBOARD command, which returns the picture into a picture field
or variable, or the GET CLIPBOARD command, which returns the picture into a BLOB.
• For any other data type, use the GET CLIPBOARD command, which returns the data into
a BLOB.
(2) Usually, applications cut and copy data of type TEXT or PICT into the Clipboard,
because most applications recognize two standard data types. However, an application can
append to the Clipboard several instances of the same data in different formats. For
example, each time you cut or copy a part of a spreadsheet, the spreadsheet application
could append the data under the hypothetical ‘SPSH’ format, as well as in SYLK and TEXT
formats. The ‘SPSH’ instance would contain the data formatted using the application’s
data structure. The SYLK form would contain the same data, but using the SYLK format
recognized by most of the other spreadsheet programs. Finally, the TEXT format would
contain the same data, without the extra information included in the SYLK or the
hypothetical ‘SPSH’ format. At this point, while writing Cut/Copy/Paste routines between
4th Dimension and that hypothetical spreadsheet application, assuming you know the
description of the ‘SPSH’ format and that you are ready to parse SYLK data, you could
write something like:
Case of
` First, check whether the clipboard contains data
` from the hypothetical spreadsheet application
⇒ : (Test clipboard ('SPSH') > 0)
` ...
` Second, check whether the clipboard contains Sylk data
⇒ : (Test clipboard ('SYLK') > 0)
` ...
` Finally check whether the clipboard contains Text data
⇒ : (Test clipboard ('TEXT') > 0)
` ...
End case
In other words, you try to extract from the Clipboard the instance of the data that carries
most of the original information.
See Also
GET CLIPBOARD, GET PICTURE FROM CLIPBOARD, Get text from clipboard.
Communications
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET CHANNEL command opens a serial port or a document. You can open only one
serial port or one document at a time with this command. To close an opened serial port,
pass SET CHANNEL (11).
Historical Note: This command was originally the first 4D command used for working
with serial ports and documents on disks. Since that time, new commands have been
added. Today, you will typically work with documents on disk using the commands Open
document, Create document and Append document. With these commands, you can read
and write characters to and from documents using SEND PACKET or RECEIVE PACKET
(these commands work with SET CHANNEL, too). However, if you want to use the
commands SEND VARIABLE, RECEIVE VARIABLE, SEND RECORD and RECEIVE RECORD, you
must use SET CHANNEL to access the document on disk.
The first form of the SET CHANNEL command opens a serial port, setting the protocol and
other port information. Data can be sent with SEND PACKET, SEND RECORD or SEND
VARIABLE, and received with RECEIVE BUFFER, RECEIVE PACKET, RECEIVE RECORD or RECEIVE
VARIABLE.
Examples :
(1) If you want to use the printer/COM2 port with no protocol, you can use one of the
following syntaxes:
(3) If you want to use the COM 25 port with the RTS/CTS protocol, you need to use the
following syntax:
The second form of the SET CHANNEL command allows you to create, open, and close a
document. Unlike the System documents commands, it can open only one document at a
time. The document can be read from or written to.
For example, to display an Open File dialog box to open a text file, you would use the
following line:
All of the operations in this table set the Document system variable if appropriate. They
also set the OK system variable to 1 if the operation was successful. Otherwise, the OK
system variable is set to 0.
Examples
See examples for the commands RECEIVE BUFFER, SET TIMEOUT and RECEIVE RECORD.
See Also
Append document, Create document, Open document, RECEIVE BUFFER, RECEIVE PACKET,
RECEIVE RECORD, RECEIVE VARIABLE, SEND PACKET, SEND RECORD, SEND VARIABLE, SET
TIMEOUT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET TIMEOUT specifies how much time a serial port command has to complete. If the
serial port command does not complete within the specified time, seconds, the serial port
command is canceled, an error -9990 is generated, and the OK system variable is set to 0.
You can catch the error with an error-handling method installed using ON ERR CALL.
Note that the time is the total time allowed for the command to execute, not the time
between characters received. To cancel a previous setting and stop monitoring serial port
communication, use a setting of 0 for seconds.
Example
The following example sets the serial port to receive data. It then sets a time-out. The data
is read with RECEIVE PACKET. If the data is not received in time, an error occurs:
SET CHANNEL (MacOS Serial Port; Speed 9600 + Data Bits 8 + Stop Bits One + Parity
None) ` Open Serial Port
⇒ SET TIMEOUT (10) ` Set the timeout for 10 seconds
ON ERR CALL ("CATCH COM ERRORS") ` Do not let the method being interrupted
RECEIVE PACKET (vtBuffer; Char (13)) ` Read until a carriage return is met
If (OK=0)
ALERT ("Error receiving data.")
Else
[People]Name:=vtBuffer ` Save received data in a field
End if
ON ERR CALL("")
See Also
ON ERR CALL, RECEIVE BUFFER, RECEIVE PACKET, RECEIVE RECORD, RECEIVE VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
USE ASCII MAP has two forms. The first form loads the ASCII map named map from disk
and uses that ASCII map. If mapInOut is 0, the map is loaded as the output map. If
mapInOut is 1, the map is loaded as the input map.
The ASCII map must have been previously created with the ASCII map dialog box in the
User environment. After an ASCII map is loaded, 4th Dimension uses the map during
transfer of data between the database and a document or a serial port. Transfer operations
include the import and export of text (ASCII), DIF, and SYLK files. An ASCII map also
works on data transferred with SEND PACKET, RECEIVE PACKET, and RECEIVE BUFFER. It has
no effect on transfers of data done with SEND RECORD, SEND VARIABLE, RECEIVE RECORD,
and RECEIVE VARIABLE.
If you give an empty string for map, USE ASCII MAP displays a standard Open File dialog
box so that the user can specify an ASCII map document. Whenever you execute USE
ASCII MAP, the OK system variable is set to 1 if the map is successfully loaded, and to 0 if
it is not.
The second form of USE ASCII MAP, with the asterisk (*) parameter instead of map, restores
the default ASCII map. If mapInOut is 0, the map is reset for output. If mapInOut is 1, the
map is reset for input. The default ASCII map has no translation between characters.
Example
The following example loads a special ASCII map from disk. It then exports data. Finally,
the default ASCII map is restored:
See Also
EXPORT DIF, EXPORT SYLK, EXPORT TEXT, IMPORT DIF, IMPORT SYLK, IMPORT TEXT, Mac
to Win, RECEIVE BUFFER, RECEIVE PACKET, SEND PACKET, Win to Mac.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SEND PACKET sends a packet to a serial port or to a document. If docRef is specified, the
packet is written to the document referenced by docRef. If docRef is not specified, the
packet is written to the serial port or document previously opened by the SET CHANNEL
command. A packet is just a piece of data, generally a string of characters.
Before you use SEND PACKET, you must open a serial port or a document with SET
CHANNEL, or open a document with one of the document commands.
When writing to a document, the first SEND PACKET begins writing at the beginning of
the document unless the document was opened with Append document. Until the
document is closed, each subsequent packet is appended to any previously sent packets.
Version 6 Note: This command is still useful for a document opened with SET CHANNEL.
On the other hand, for a document opened with Open document, Create document and
Append document, you can now use the new commands Get document position and SET
DOCUMENT POSITION to get and change the location in the document where the next
writing (SEND PACKET) or reading (RECEIVE PACKET) will occur.
Important: SEND PACKET writes Mac OS ASCII data on both Windows and Macintosh
platforms. Mac OS ASCII data uses eight bits. Standard ASCII uses only the lower seven
bits. Many devices do not use the eighth bit in the same way as does
Windows/Macintosh. If the string to be sent contains data that uses the eighth bit, be
sure to create an ASCII map to translate the ASCII characters, and execute USE ASCII MAP
before using SEND PACKET. You can also use the Mac to Win function (for more
information, refer to the example for this function). Protocols like XON/XOFF use some
low ASCII codes to establish communication between machines. Be careful to not send
such ASCII codes, as this may interfere with the protocol or even break communication.
See Also
Get document position, RECEIVE PACKET, SET DOCUMENT POSITION.
Description
RECEIVE PACKET reads characters from a serial port or from a document.
If docRef is specified, this command reads characters from a document opened using Open
document, Create document or Append document. If docRef is omitted, this command
reads characters from the serial port or the document opened using SET CHANNEL.
Whatever the source, the characters read are returned in receiveVar, which must be a Text
or String variable. To read a particular number of characters, pass this number in
numChars. To read characters until a particular string (composed of one or more
characters) is encountered, pass this string in stopChar (the string is not returned in
receiveVar).
When reading a document, if stopChar | numChars is not specified, RECEIVE PACKET will
stop reading at the end of the document. However, remember that while a string variable
has a fixed length, a text variable accepts up to 32000 characters. When reading from a
serial port, RECEIVE PACKET will attempt to wait indefinitely until the timeout (if any) has
elapsed (see SET TIMEOUT) or until the user interrupts the reception (see below).
During execution of RECEIVE PACKET, the user can interrupt the reception by pressing
Ctrl-Alt-Shift (Windows) or Command-Option-Shift (Macintosh). This interruption
generates an error -9994 that you can catch with an error-handling method installed
using ON ERR CALL. Usually, you will only have to handle interruption of a reception
when communicating over a serial port.
When reading a document, the first RECEIVE PACKET begins reading at the beginning of
the document. The reading of each subsequent packet begins at the character following
the last character read.
Version 6 Note: This command is still useful for document opened with SET CHANNEL. On
the other hand, for a document opened with Open document, Create document and
Append document, you can now use the new commands Get document position and SET
DOCUMENT POSITION to get and change the location in the document where the next
writing (SEND PACKET) or reading (RECEIVE PACKET) will occur.
Note: When you use the RECEIVE PACKET command to read characters from a Windows
document and do not want to use ASCII maps to convert Windows characters into
Mac OS characters, you can use the Win to Mac function.
Examples
1. The following example reads 20 characters from a serial port into the variable
getTwenty:
2. The following example reads data from the document referenced by the variable
myDoc into the variable vData. It reads until it encounters a carriage return:
3. The following example reads data from the document referenced by the variable
myDoc into the variable vData. It reads until it encounters the </TD> (end of table cell)
HTML tag:
4. The following example reads data from a document into fields. The data is stored as
fixed-length fields. The method calls a subroutine to strip any trailing spaces (spaces at the
end of the string). The subroutine follows the method:
$vhDocRef := Open document ("";"TEXT") ` Open a TEXT document
If (OK=1) ` If the document was opened
Repeat ` Loop until no more data
⇒ RECEIVE PACKET ($vhDocRef; $Var1; 15) ` Read 15 characters
⇒ RECEIVE PACKET ($vhDocRef; $Var2; 15) ` Do same as above for second field
If (OK = 1) ` If we are not beyond the end of the document
CREATE RECORD([People]) ` Create a new record
[People]First := Strip ($Var1) ` Save the first name
[People]Last := Strip ($Var2) ` Save the last name
SAVE RECORD([People]) ` Save the record
End if
Until (OK =0)
CLOSE DOCUMENT ($vhDocRef) ` Close the document
End if
See Also
Get document position, RECEIVE PACKET, SEND PACKET, SET DOCUMENT POSITION, SET
TIMEOUT.
Description
RECEIVE BUFFER reads the serial port that was previously opened with SET CHANNEL. The
serial port has a buffer that fills with characters until a command reads from the buffer.
RECEIVE BUFFER gets the characters from the serial buffer, put them into receiveVar then
clears the buffer. If there are no characters in the buffer, then receiveVar will contain
nothing.
On Windows
The Windows serial port buffer is limited in size to 10 Kbytes. This means that the buffer
can overflow. When it is full and new characters are received, the new characters replace
the oldest characters. The old characters are lost; therefore, it is essential that the buffer is
read quickly when new characters are received.
On MacOS
The MacOS 9.x serial port buffer is limited in size to 10 Kbytes. Under MacOS X, its
capacity is, in theory, unlimited (depending on the available memory). If the buffer is full
and new characters are received, the new characters replace the oldest characters. The old
characters are lost; therefore, it is essential that the buffer is read quickly when new
characters are received.
Note: There are 4D plug-ins that enable you to increase the size of the serial buffer.
RECEIVE BUFFER is different from RECEIVE PACKET in that it takes whatever is in the buffer
and then immediately returns. RECEIVE PACKET waits until it finds a specific character or
until a given number of characters are in the buffer.
During the execution of RECEIVE BUFFER, the user can interrupt the reception by pressing
Ctrl-Alt-Shift (Windows) or Command-Option-Shift (Macintosh). This interruption
generates an error -9994 that you can catch with an error-handling method installed
using ON ERR CALL.
At this point, any other process can read the interprocess ◊vtBuffer to work with the data
coming from the serial port.
See Also
ON ERR CALL, RECEIVE PACKET, Semaphore, SET CHANNEL, Variables.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SEND VARIABLE sends variable to the document or serial port previously opened by SET
CHANNEL. The variable is sent with a special internal format that can be read only by
RECEIVE VARIABLE. SEND VARIABLE sends the complete variable (including its type and
value).
Notes
1. If you send a variable to a document using this command, the document must have
been opened using the SET CHANNEL command. You cannot use SEND VARIABLE with a
document opened with Open document, Append document or Create document.
2. This command does not support array variables. If you want to send and receive arrays
from a document or over a serial port, use the new BLOB commands introduced in version
6.
Example
See example for the command RECEIVE RECORD.
See Also
RECEIVE RECORD, RECEIVE VARIABLE, SEND RECORD, SET CHANNEL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
RECEIVE VARIABLE receives variable, which was previously sent by SEND VARIABLE from the
document or serial port previously opened by SET CHANNEL.
In interpreted mode, if the variable does not exist prior to the call to RECEIVE VARIABLE,
the variable is created, typed and assigned according to what has been received. In
compiled mode, the variable must be of the same type as what is received. In both cases,
the contents of the variable are replaced with what is received.
Notes
1. If you receive a variable from a document using this command, the document must
have been opened using the SET CHANNEL command. You cannot use RECEIVE VARIABLE
with a document opened with Open document, Append document or Create document.
2. This command does not support array variables. If you want to send and receive arrays
from a document or over a serial port, use the new BLOB commands introduced in version
6.
3. During the execution of RECEIVE VARIABLE, the user can interrupt the reception by
pressing Ctrl-Alt-Shift (Windows) or Command-Option-Shift (Macintosh). This
interruption generates an error -9994 that you can catch with an error-handling method
installed using ON ERR CALL. Usually, you only need to handle the interruption of a
reception while communicating over a serial port.
Example
See example for the command RECEIVE RECORD.
See Also
ON ERR CALL, RECEIVE RECORD, SEND RECORD, SEND VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SEND RECORD sends the current record of table to the serial port or document opened by
the SET CHANNEL command. The record is sent with a special internal format that can be
read only by RECEIVE RECORD. If no current record exists, SEND RECORD has no effect.
The complete record is sent. This means that all subrecords, pictures and BLOBs stored in
the record are also sent.
Important: When records are being sent and received using SEND RECORD and RECEIVE
RECORD, the source table structure and the destination table structure must be
compatible. If they are not, 4D will convert values according to the table definitions
when RECEIVE RECORD is executed.
Note: If you send a record to a document using this command, the document must have
been opened using the SET CHANNEL command. You cannot use SEND RECORD with a
document opened with Open document, Append document or Create document.
Example
See example for the command RECEIVE RECORD.
See Also
RECEIVE RECORD, RECEIVE VARIABLE, SEND VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
RECEIVE RECORD receives a record into table from the serial port or document opened by
the SET CHANNEL command. The record must have been sent with SEND RECORD. When
you execute RECEIVE RECORD, a new record is automatically created for table. If the record
is received correctly, you must then use SAVE RECORD to save the new record.
The complete record is received. This means that all subrecords, pictures and BLOBs stored
in the record are also received.
Important: When records are being sent and received using SEND RECORD and RECEIVE
RECORD, the source table structure and the destination table structure must be
compatible. If they are not, 4D will convert values according to the table definitions
when RECEIVE RECORD is executed.
Notes
1. If you receive a record from a document using this command, the document must
have been opened using the SET CHANNEL command. You cannot use RECEIVE RECORD
with a document opened with Open document, Append document or Create document.
2. During the execution of RECEIVE RECORD, the user can interrupt the reception by
pressing Ctrl-Alt-Shift (Windows) or Command-Option-Shift (Macintosh). This
interruption generates an error -9994 that you can catch with an error-handling method
installed using ON ERR CALL. Usually, you only need to handle the interruption of a
reception while communicating over a serial port.
Example
A combined use of SEND VARIABLE, SEND RECORD, RECEIVE VARIABLE and RECEIVE RECORD
is ideal for archiving data or for exchanging data between identical single-user databases
used in different places. You can exchange data between 4D databases using the
import/export commands such as EXPORT TEXT and IMPORT TEXT. However, if your data
contains graphics, subtables and/or related tables, using SEND RECORD and RECEIVE
RECORD is far more convenient.
For instance, the documentation you are currently reading has been created using 4D and
4D Write. Because several writers in different locations wordwide were working on it, we
needed a simple way to exchange data between the different databases.
The table [Commands] contains the description of each command or topic. The tables [CM
US Params] and [CM FR Params] respectivily contain the parameter list for each command
in English and in French. The table [CM See Also] contains the commands listed as
reference (See Also section) for each command. Exchanging documentation between
databases therefore consists in sending the [Commands] records and their related records.
To do so, we use SEND RECORD and RECEIVE RECORD. In addition, we use SEND VARIABLE
and RECEIVE VARIABLE in order to mark the import/export document with tags.
Note that we do not test the OK variable while receiving the data nor try to catch the
errors. However, because we stored variables in the document that describes the document
itself, if these variables, once received, made sense, the probability for an error is very low.
If for instance a user opens a wrong document, the first test stops the operation right
away.
See Also
RECEIVE VARIABLE, SEND RECORD, SEND VARIABLE.
Compiler
The integrated compiler of 4th Dimension translates your database applications into
assembly level instructions. The advantages of the compiler are:
• Speed: Your database can run from 3 to 1,000 times faster.
• Code checking: Your database application is scanned for the consistency of code. Both
logical and syntactical conflicts are detected.
• Protection: once your database is compiled, you can delete the interpreted code, Then,
the compiled database is functionally identical to the original, except that the structure
and procedures cannot be viewed or modified, deliberately or inadvertently.
• Stand-alone double-clickable applications: compiled databases can also be transformed
into stand-alone applications (.EXE files) with their own icon.
The commands in this theme relate to the use of the compiler. They enable you to
normalize data types throughout your database. The IDLE command is specifically used in
compiled databases.
These commands, except IDLE, declare variables and cast them as a specified data type.
Declaring variables resolves ambiguities concerning a variable’s data type. If a variable is
not declared with one of these commands, the compiler attempts to determine a
variable’s data type. The data type of a variable used in a form is often difficult for the
compiler to determine. Therefore, it is especially important that you use these commands
to declare a variable used in a form.
Note: To save time, you can use the option for generating and updating typing methods
found in the compiler window. This option automatically creates typing methods that
take stock of and assign a type to all of the variables used in the database.
• The Undefined function will always return False. Variables are always defined.
• Numeric operations on long integer and integer variables are usually much faster than
operations on the default numeric type (real).
Examples
(1) The following are some basic variable declarations for the compiler:
` The process variable vxMyBlob is declared as a variable of type BLOB
⇒ C_BLOB(vxMyBlob)
` The interprocess variable ◊OnWindows is declared as a variable of type Boolean
⇒ C_BOOLEAN(◊OnWindows)
` The local variable $vdCurDate is declared as a variable of type Date
⇒ C_DATE($vdCurDate)
` The 3 process variables vg1, vg2 and vg3 are declared as variables of type Graph
⇒ C_GRAPH(vg1;vg2;vg3)
` ...
⇒ C_STRING(255;$0;$1)
$0:=Uppercase(Substring($1;1;1))+Lowercase(Substring($1;2))
(4) In the following example, the project method SEND PACKETS accepts a time parameter
followed by a variable number of text parameters:
` SEND PACKETS Project Method
` SEND PACKETS ( Time ; Text { ; Text2... ; TextN } )
` SEND PACKETS ( docRef ; Data { ; Data2... ; DataN } )
⇒ C_TIME ($1)
⇒ C_TEXT (${2})
⇒ C_LONGINT ($vlPacket)
See Also
C_BLOB, C_BOOLEAN, C_DATE, C_GRAPH, C_INTEGER, C_LONGINT, C_PICTURE,
C_POINTER, C_REAL, C_STRING, C_TEXT, C_TIME, IDLE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
C_BLOB casts each specified variable as a BLOB variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_BLOB(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_BLOB(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_BOOLEAN command casts each specified variable as a Boolean variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_BOOLEAN(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_BOOLEAN(${5}) tells 4D and the compiler
that starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_DATE command casts each specified variable as a Date variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_DATE(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_DATE(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_GRAPH command casts each specified variable as a Graph variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_GRAPH(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_GRAPH(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Note: This command is still present in 4th Dimension for compatibility with old
databases. In fact, 4D and the compiler retype Integers into Longints internally. For
example :
C_INTEGER($MyVar)
$TheType:=Type($MyVar) `$TheType = 9 (Is Longint)
Description
The C_INTEGER command casts each specified variable as an Integer variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_INTEGER(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_INTEGER(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler commands, Count parameters, C_LONGINT, C_REAL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_LONGINT command casts each specified variable as a Long Integer variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_LONGINT(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_LONGINT(${5}) tells 4D and the compiler
that starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters, C_INTEGER, C_REAL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_PICTURE command casts each specified variable as a Picture variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_PICTURE(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_PICTURE(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler commands, Count parameters.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_POINTER command casts each specified variable as a Pointer variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_POINTER(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_POINTER(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_REAL command casts each specified variable as a Real variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_REAL(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_REAL(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters, C_INTEGER, C_LONGINT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_STRING command casts each specified variable as a String variable.
The size parameter specifies the maximum length of the strings that the variable can
contain. Strings are limited to 255 characters. If speed is a concern, use string variables
rather than text variables wherever possible.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_STRING(...;${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_STRING(...;${5}) tells 4D and the compiler
that starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler commands, Count parameters, C_TEXT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_TEXT command casts each specified variable as a Text variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_TEXT(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_TEXT(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler Commands, Count parameters, C_STRING.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The C_TIME command casts each specified variable as a Time variable.
The first form of the command, in which the optional method parameter is NOT passed,
is used to declare and type any process, interprocess, or local variable.
The second form of the command, in which the optional method parameter IS passed, is
used to predeclare to the compiler the result and/or the parameters ($0, $1, $2 etc) for a
method. Use this form of the command in order to skip the Typing variables phase while
compiling a database, saving compilation time.
WARNING: The second form cannot be executed in interpreted mode. For this reason, if
you are using this syntax, keep it in a method that is not executed in interpreted mode.
The name of this method must start with “COMPILER.”
Advanced Tip: The syntax C_TIME(${...}) allows you to declare a variable number of
parameters of the same type, under the condition that these are the last parameters for
the method. For example, the declaration C_TIME(${5}) tells 4D and the compiler that
starting with the fifth parameter, the method can receive a variable number of
parameters of that type. For more information, see the Count parameters command.
Examples
See examples in the section Compiler Commands.
See Also
Compiler commands, Count parameters.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
IDLE
Description
The IDLE command is designed only for use with the compiler. This command is only
used in compiled databases in which user-defined methods are written so that no calls are
made back to the 4th Dimension engine. For example, if a method has a For loop in
which no 4th Dimension commands are executed, the loop could not be interrupted by a
process installed with ON EVENT CALL, nor could a user switch to another application. In
this case, you should insert IDLE to allow 4th Dimension to trap events. If you do not
want any interruptions, omit IDLE.
Example
In the following example, the loop would never terminate in a compiled database without
the call to IDLE:
` Do Something Project Method
ON EVENT CALL ("EVENT METHOD")
◊vbWeStop:=False
MESSAGE ("Processing..."+Char(13)+"Type any key to interrupt...")
Repeat
` Do some processing that doesn’t involve a 4D command
⇒ IDLE
Until (◊vbWeStop)
ON EVENT CALL ("")
with:
Database Methods
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Database methods are methods that are automatically executed by 4th Dimension when a
general session event occurs.
You edit a database method in the same way as any other method.
You cannot call a database method from another method. Database methods are
automatically invoked by 4th Dimension at certain points in a working session. The
following table summarizes execution of database methods:
Database Method 4th Dimension 4D Server 4D Client
On Startup Yes, Once No Yes, Once
On Exit Yes, Once No Yes, Once
On Web Connection Yes, Multiple Yes, Multiple No
On Server Startup No Yes, Once No
On Server Shutdown No Yes, Once No
On Server Open Connection No Yes, Multiple No
On Server Close Connection No Yes, Multiple No
See Also
Methods.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The On Startup Database Method is called once when you open a database.
The On Startup Database Method is automatically invoked by 4D; unlike project methods,
you cannot call this database method yourself. To call and perform tasks from within the
On Startup Database Method, as well as from project methods later on, use subroutines.
See Also
Database Methods, Methods, On Exit Database Method, QUIT 4D.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The On Exit Database Method is called once when you quit a database.
The On Exit Database Method is automatically invoked by 4D; unlike project methods, you
cannot call this database method yourself. To call and perform tasks from within the On
Exit Database Method, as well as from project methods, use subroutines.
No matter how the exit from the database was initiated, 4D performs the following
actions:
• If there is no On Exit Database Method, 4D aborts each running process one by one,
without distinction. If the user is performing data entry, the records will be cancelled and
not saved.
• If there is an On Exit Database Method, 4D starts executing this method within a newly
created local process. You can therefore use this database method to inform other
processes, via interprocess communication, that they must close (data entry) or stop
executing. Note that 4D will eventually quit—the On Exit Database Method can perform
all the cleanup or closing operations you want, but it cannot refuse the quit, and will at
some point end.
Example
The following example covers all the methods used in a database that tracks the
significant events that occur during a working session and writes a description in a text
document called “Journal.”
• The On Startup Database Method initializes the interprocess variable ◊vbQuit4D, which
tells all the use processes whether or not the database is being exited. It also creates the
journal file, if it does not already exist.
` On Startup Database Method
C_TEXT(◊vtIPMessage)
C_BOOLEAN(◊vbQuit4D)
◊vbQuit4D:=False
While (Semaphore("$Journal"))
DELAY PROCESS(Current process;1)
End while
$vhDocRef:=Append document("Journal")
If (OK=1)
PROCESS PROPERTIES(Current process;$vsProcessName;$vlState;$vlElapsedTime;
$vbVisible)
SEND PACKET($vhDocRef;String(Current date)+Char(9)+String(Current time)+
Char(9)+String(Current process)+Char(9)+
$vsProcessName+Char(9)+$1+Char(13))
CLOSE DOCUMENT($vhDocRef)
End if
CLEAR SEMAPHORE("$Journal")
Note that the document is open and closed each time. Also note the use of a semaphore
as “access protection” to the document—we do not want two processes trying to access
the journal file at the same time.
• The M_ADD_RECORDS project method is executed when a menu item Add Record is
chosen in Custom menus:
` M_ADD_RECORDS Project Method
MENU BAR(1)
Repeat
ADD RECORD([Table1];*)
If (OK=1)
WRITE JOURNAL ("Adding record #"+String(Record number([Table1]))+
" in Table1")
End if
Until ((OK=0) | ◊vbQuit4D)
This method loops until the user cancels the last data entry or exits the database.
• The M_QUIT project method is executed when Quit is chosen from the File menu in the
Custom Menus environment:
` M_QUIT Project Method
$vlProcessID:=New process("DO_QUIT";32*1024;"$DO_QUIT")
The method uses a trick. When QUIT 4D is called, the command has an immediate effect.
Therefore, the process from which the call is issued is in “stop mode” until the database is
actually exited. Since this process can be one of the processes in which data entry occurs,
the call to QUIT 4D is made in a local process that is started only for this purpose. Here is
the DO_QUIT method:
` DO_QUIT Project Method
CONFIRM("Are you sure you want to quit?")
If (OK=1)
WRITE JOURNAL ("Quitting Database")
QUIT 4D
` QUIT 4D has an immediate effect, any line of code below will never be executed
` ...
End if
Note: Processes that have names beginning with "ML_..." or "M_..." are started by menu
commands for which the Start a New Process property has been selected. In this
example, these are the processes started when the menu command Add record was
chosen.
The test (Current time-$vhStart)>=?00:01:00? allows the database method to get out of the
“waiting the other process” Repeat loop if the other process does not act immediately.
• The following is a typical example of the Journal file produced by the database:
2/6/03 15:47:25 1 User/Custom Menus process Opening Session
2/6/03 15:55:43 5 ML_1 Adding record #23 in Table1
2/6/03 15:55:46 5 ML_1 Adding record #24 in Table1
2/6/03 15:55:54 6 $DO_QUIT Quitting Database
2/6/03 15:55:58 7 $xx Closing session
Note: The name $xx is the name of the local process started by 4D in order to execute the
On Exit Database Method.
See Also
On Startup Database Method, QUIT 4D.
Data Entry
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ADD RECORD lets the user add a new record to the database for the table
table or for the default table, if you omit the table parameter.
ADD RECORD creates a new record, makes the new record the current record for the
current process, and displays the current input form. In the Custom Menus environment,
after the user has accepted the new record, the new record is the only record in the
current selection.
The form is displayed in the frontmost window of the process. The window has scroll bars
and a size box. Specifying the optional * parameter causes the window to be drawn
without scroll bars or a size box.
ADD RECORD displays the form until the user accepts or cancels the record. If the user is
adding several records, the command must be executed once for each new record.
The record is saved (accepted) if the user clicks an Accept button or presses the Enter key
(numeric keypad), or if the ACCEPT command is executed.
Note: Even when canceled, the record remains in memory and can be saved if SAVE
RECORD is executed before the current record pointer is changed.
Examples
1. The following example is a loop commonly used to add new records to a database:
INPUT FORM ([Customers];"Std Input") ` Set input form for [Customers] table
Repeat ` Loop until the user cancels
⇒ ADD RECORD ([Customers];*) ` Add a record to the [Customers] table
Until (OK=0) ` Until the user cancels
2. The following example queries the database for a customer. Depending on the results of
the search, one of two things may happen. If no customer is found, then the user is
allowed to add a new customer with ADD RECORD. If at least one customer is found, the
user is presented with the first record found, which can be modified with MODIFY
RECORD:
READ WRITE([Customers])
INPUT FORM([Customers];"Input") ` Set the input form
vlCustNum:=Num(Request ("Enter Customer Number:")) ` Get the customer number
If (OK=1)
QUERY ([Customers];[Customers]CustNo=vlCustNum) ` Look for the customer
If (Records in selection([Customers])=0) ` If no customer is found…
⇒ ADD RECORD([Customers]) ` Add a new customer
Else
If(Not(Locked([Customers])))
MODIFY RECORD([Customers]) ` Modify the record
UNLOAD RECORD([Customers])
Else
ALERT("The record is currently being used.")
End if
End if
End if
See Also
ACCEPT, CANCEL, CREATE RECORD, MODIFY RECORD, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command MODIFY RECORD lets the user modifies the current record for the table
table or for the default table if you omit the table parameter. MODIFY RECORD loads the
record, if it is not already loaded for the current process, and displays the current input
form. If there is no current record, then MODIFY RECORD does nothing. MODIFY
RECORD does not affect the current selection.
The form is displayed in the frontmost window of the process. The window has scroll bars
and a size box. Specifying the optional * parameter causes the window to be drawn
without scroll bars or a size box.
To use MODIFY RECORD, the current record must have read-write access and should not
be locked.
If the form contains buttons for moving within the selection of records, MODIFY
RECORD lets the user click the buttons to modify records and move to other records.
The record is saved (accepted) if the user clicks an Accept button or presses the Enter key
(numeric key pad), or if the ACCEPT command is executed.
The record is not saved (canceled) if the user clicks a Cancel button or presses the cancel
key combination (Ctrl-Period on Windows, Command-Period on Macintosh), or if the
CANCEL command is executed. Even when canceled, the record remains in memory and
can be saved if SAVE RECORD is executed before the current record pointer is changed.
Note: Even when canceled, the record remains in memory and can be saved if SAVE
RECORD is executed before the current record pointer is changed.
If you are using MODIFY RECORD and the user does not change any of the data in the
record, the record is not considered to be modified, and accepting the record does not
cause it to be saved again. Actions such as changing variables, checking check boxes, and
selecting radio buttons do not qualify as modifications. Only changing data in a field,
either through data entry or through a method, causes the record to be saved.
See Also
ADD RECORD, Locked, Modified record, READ WRITE, UNLOAD RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ADD SUBRECORD lets the user add a new subrecord to subtable, using the
form form. ADD SUBRECORD creates a new subrecord in memory, makes it the current
subrecord, and displays form. A current record for the parent table must exist. If a current
parent record does not exist for the process, ADD SUBRECORD has no effect. The form
must belong to subtable.
The subrecord is kept in memory (accepted) if the user clicks an Accept button or presses
the Enter key (numeric pad), or if the ACCEPT command is executed. After the subrecord
has been added, the parent record must be explicitly saved in order for the subrecord to be
saved.
The subrecord is not saved if the user clicks a Cancel button or presses the cancel key
combination (Ctrl-Period on Windows, Command-Period on Macintosh), or if the
CANCEL command is executed.
The form is displayed in the frontmost window of the process. The window has scroll bars
and a size box. Specifying the optional * parameter causes the window to be drawn
without scroll bars or a size box.
See Also
ACCEPT, CANCEL, MODIFY SUBRECORD, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command MODIFY SUBRECORD displays the current subrecord of subtable for
modification using the form form. The form must belong to subtable.
A current record for the parent table must exist. If a current parent record does not exist
for the process, MODIFY SUBRECORD has no effect. In addition, if there is no current
subrecord, then MODIFY SUBRECORD does nothing.
The subrecord is kept in memory (accepted) if the user clicks an Accept button or presses
the Enter key (numeric pad), or if the ACCEPT command is executed. After the subrecord
has been modified, the parent record must be explicitly saved in order for the subrecord
to be saved.
The subrecord is not modified if the user clicks a Cancel button or presses the cancel key
combination (Ctrl-Period on Windows, Command-Period on Macintosh), or if the
CANCEL command is executed.
The form is displayed in the frontmost window of the process. The window has scroll bars
and a size box. Specifying the optional * parameter causes the window to be drawn
without scroll bars or a size box.
See Also
ACCEPT, ADD SUBRECORD, CANCEL, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DIALOG presents the form form to the user. This command is often used to
get information from the user through the use of variables, or to present information to
the user, such as options for performing an operation.
It is common to display the form inside a modal window created with the Open window
command.
In a dialog, data entry can be performed only by using variables. Fields can be displayed
with the current values, but are not enterable.
Tip: Sometimes dialogs can be simulated by ADD RECORD, if you need the capabilities
provided by field data entry. In this case, if the form is accepted, a record is added to the
table.
Tip: Conversely, data entry can be performed using the DIALOG command. In this case,
you must create and save the record. DIALOG does not manipulate records.
Use DIALOG instead of ALERT, CONFIRM, or Request when the information that must be
presented or gathered is more complex than those commands can manage.
The dialog is accepted if the user clicks an Accept button or presses the Enter key
(numeric key pad), or if the ACCEPT command is executed.
The dialog is canceled if the user clicks a Cancel button or presses the cancel key
combination (Ctrl-Period on Windows, Command-Period on Macintosh), or if the
CANCEL command is executed.
Example
The following example shows the use of DIALOG to specify search criteria. A custom form
containing the variables vName and vState is displayed so the user can enter the search
criteria.
Open window (10;40;370;220) ` Open a modal window
⇒ DIALOG([Company];"Search Dialog") ` Display a custom search dialog
CLOSE WINDOW ` No longer need the modal window
If (OK=1) ` If the dialog is accepted
QUERY ([Company];[Company]Name=vName;*)
QUERY ([Company];&;[Company]State=vState)
End if
See Also
ACCEPT, ADD RECORD, CANCEL, Open window.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Function result Boolean ← True if the field has been assigned a new value,
otherwise False
Description
Modified returns True if field has been programmatically assigned a value or has been
edited during data entry. The command Modified must be used in a form method (or a
subroutine called by a form method) only.
During data entry, a field is considered modified if the user has edited the field (whether
or not the original value is changed) and then left it by going to another field or by
clicking on a control. Note that just tabbing out of a field does not set Modified to True.
The field must have been edited in order for Modified to be True.
In any cases, use the Old command to detect if the field value has been actually changed.
Note: Although modified can be applied to any type of field, if you use it in combination
with the old command, be aware of the restrictions that apply to the old command. For
details, see the description of the Old command.
During data entry, it is usually easier to perform operations in object methods than to use
Modified in form methods. Since an object method is sent an On Data Change event
whenever a field is modified, the use of an object method is equivalent to using Modified
in a form method.
Note: To operate properly, the Modified command is to be used only in a form method or
in a method called by a form method.
Note that the same thing could be accomplished by using the second line as a subroutine
called by the object methods for the [Orders]Quantity field and the [Orders]Price field.
2. You select a record for the table [anyTable], then you call multiple subroutines that may
modify the field [anyTable]Important field, but do not save the record. At the end of the
main method, you can use the Modified command to detect if you must save the record:
` Here the record has been selected as current record
` Then you perform actions using subroutines
DO SOMETHING
DO SOMETHING ELSE
DO NOT FORGET TO DO THAT
` ...
` At then you test the field to detect if the record has to be saved
⇒ If (Modified([anyTable]Important field))
SAVE RECORD([anyTable])
End if
See Also
Old.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Old returns the value held in field before the field was programmatically
assigned a value or modified in data entry.
Each time you change the current record for a table, 4D creates and maintains in memory
a duplicated “image” of the new current record when it is loaded in memory. (For
optimization, 4D disregards Text, Picture and BLOB fields.) When modifying a record, you
work with the actual image of the record, not this duplicated image. This image is then
discarded when you change the current record again.
Old returns the value from the duplicated image. In other words, for an existing record, it
returns the value of the field as it is stored on disk. If a record is new, Old returns the
default empty value for field according to its type. For example, if field is an Alpha field,
Old returns an empty string. If field is a numeric field, Old returns zero (0), and so on.
Old works on field whether the field has been modified by a method or by the user during
data entry.
Old cannot be applied to Text, Picture or BLOB fields. It can be applied to all other field
types, including subfields, but has no meaning when applied to a subtable field itself.
To restore the original value of a field, assign it the value returned by Old.
See Also
Modified.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Current date returns the current date as kept by the system clock.
4D Server: If you use the asterisk (*) parameter when executing this function on a 4D
Client machine, it returns the current date from the server.
Examples
1. The following example displays an alert box containing the current date:
2. If you write an application for the international market, you may need to know if the
version of 4D that you run works with dates formatted as MM/DD/YYYY (US version) or
DD/MM/YYYY (French version). This is useful to know for customizing data entry fields.
C_STRING(31;$0;$vsDate;$vsMDY;$vsMonth;$vsDay;$vsYear)
C_LONGINT($1;$vlPos)
C_DATE($vdDate)
` Get a Date value where the month, day and year values are all different
⇒ $vdDate:=Current date
Repeat
$vsMonth:=String(Month of($vdDate))
$vsDay:=String(Day of($vdDate))
$vsYear:=String(Year of($vdDate)%100)
See Also
Date Operators, Day of, Month of, Year of.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Day of returns the day of the month of date.
Note: Day of returns a value between 1 and 31. To get the day of the week for a date, use
the command Day number.
Examples
1. The following example illustrates the use of Day of. The results are assigned to the
variable vResult. The comments describe what is put in vResult:
⇒ vResult := Day of (!12/25/92!) ` vResult gets 25
⇒ vResult := Day of (Current date) ` vResult gets day of current date
See Also
Day number, Month of, Year of.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Month of returns the month of date.
Note: Month of returns the number of the month, not the name (see Example 1).
Examples
1. The following example illustrates the use of Month of. The results are assigned to the
variable vResult. The comments describe what is put in vResult:
The following project method returns the name of the month for a date:
` Month name of project method
` Month name of ( Date ) -> String
` Month name of ( Date ) -> Name of the month
The following project method returns the abbreviation of the month for a date:
` Month abbr of project method
` Month abbr of ( Date ) -> String
` Month abbr of ( Date ) -> Name of the month
See Also
Day of, Year of.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Year of returns the year of date.
Examples
1. The following example illustrates the use of Year of. The results are assigned to the
variable vResult.
See Also
Day of, Month of.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Day number returns a number representing the weekday on which date
falls.
Note: Day number of returns a value between 1 and 7. To get the day number within the
month for a date, use the command Day of.
See Also
Day of.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Add to date adds years, months, and days to the date you pass in date, then
returns the result.
Although you can use the Date Operators to add days to a date, Add to date allows you to
quickly add months and years without having to deal with the number of days per
month or leap years (as you would when using the + date operator).
Examples
See Also
Date Operators.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Date evaluates dateString and returns a date.
The dateString parameter must follow the normal rules for the date format.
In the US version of 4D, the date must be in the order MM/DD/YY (month, day, year).
The month and day can be one or two digits. The year can be two or four digits. If the
year is two digits, then Date adds 19 to the beginning of the year, unless you have
change this default using the command SET DEFAULT CENTURY. The following characters
are valid date separators: slash (/), space, period (.), and comma (,).
Date does not check whether or not dateString is a valid date. If an invalid date (such as
"13/35/94") is passed, Date will return the invalid date. However, if dateString could not
possibly be interpreted as a date (for example, "aa/12/94"), the null date value (!00/00/00!)
is returned.
⇒ vdDate:=Date("12/12/94")
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Current time returns the current time from the system clock.
The current time is always between 00:00:00 and 23:59:59. Use String or Time string to
obtain the string form of the time expression returned by Current time.
4D Server: If you use the asterisk (*) parameter when executing this function on a 4D
Client machine, it returns the current time from the server.
Examples
1. The following example shows you how to time the length of an operation. Here,
LongOperation is a method that needs to be timed:
2. The following example extracts the hours, minutes, and seconds from the current time:
⇒ $vhNow:=Current time
ALERT("Current hour is: "+String($vhNow\3600))
ALERT("Current minute is: "+String(($vhNow\60)%60))
ALERT("Current second is: "+String($vhNow%60))
See Also
Milliseconds, String, Tickcount, Time Operators.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Time string returns the string form of the time expression you pass in
seconds.
If you go beyond the number of seconds in a day (86,400), Time string continues to add
hours, minutes, and seconds. For example, Time string (86401) returns 24:00:01.
Note: If you need the string form of a time expression in a variety of formats, use String.
Example
The following example displays an alert box with the message, “46800 seconds is
13:00:00.”
See Also
String, Time.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Time returns a time expression equivalent to the time specified as a string
by timeString.
The timeString parameter must follow the HH:MM:SS format and be in 24-hour format.
Example
The following example displays an alert box with the message “1:00 P.M. = 13 hours 0
minute”:
See Also
String, Time string.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Tickcount → Number
Description
Tickcount returns the number of ticks (60th of a second) elapsed since the machine was
started.
Example
See example for the command Milliseconds.
See Also
Current time, Milliseconds.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Milliseconds → Longint
Description
Milliseconds returns the number of milliseconds (1000th of a second) elapsed since the
machine was started.
Example
The following code displays the “Chronometer” window for one minute:
Open window (100;100;300;200;0;"Chronometer")
$vhTimeStart:=Current time
$vlTicksStart:=Tickcount
⇒ $vrMillisecondsStart:=Milliseconds
Repeat
GOTO XY (2;1)
MESSAGE ("Time...........:"+String (Current time -$vhTimeStart))
GOTO XY (2;3)
MESSAGE ("Ticks..........:"+String (Tickcount -$vlTicksStart))
GOTO XY (2;5)
⇒ MESSAGE ("Milliseconds...:"+String (Milliseconds -$vrMillisecondsStart))
Until ((Current time -$vhTimeStart)>=†00:01:00†)
CLOSE WINDOW
See Also
Current time, Tickcount.
Description
The command SET DEFAULT CENTURY allows you to specify the default century and the
pivot year used by 4D when you enter a date with only two digits for the year.
The pivot year value defines the way 4D will interpret data entry of a date with a two-digit
year:
• If the year is greater than or equal to the pivot year, 4D uses the current default century.
• If the year is less than the pivot year, 4D uses the next century (relative to the current
default).
By default, 4D sets the century to be the 20th century and uses 30 as pivot year. For
example:
• 01/25/97 means January 25, 1997.
• 01/25/30 means January 25, 1930.
• 01/25/29 means January 25, 2029.
• 01/25/07 means January 25, 2007.
To change this default, execute the SET DEFAULT CENTURY command. The effect of the
command is immediate. You can pass a new default century only, or a new default
century and a pivot year.
If you pass only a new default century minus one in century, 4D will interpret data entry
of a date with a two-digit year as belonging to this century.
For example, after the call:
SET DEFAULT CENTURY(20) ` Switch to 21st century for default century
• 01/25/97 means January 25, 2097
• 01/25/07 means January 25, 2007
Note: This command only affects how 4D interprets dates entered with a two-digit year.
In all cases:
• 01/25/1997 means January 25, 1997
• 01/25/2097 means January 25, 2097
• 01/25/1907 means January 25, 1907
• 01/25/2007 means January 25, 2007
This command only affects data entry. It has no effect on date storage, computation, and
so on.
Debugging
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
When developing and testing your methods, it is important that you find and fix the
errors they may contain.
There are several types of errors you can make when using the language: typing errors,
syntax errors, environmental errors, design or logic errors, and runtime errors.
Typing Errors
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Typing errors are detected by the Method editor and are marked with bullets (•) and a
message is displayed in the information area at the top of the method window. The
following window shows a typing error:
Note: The comments have been manually inserted for the purpose of this manual. 4D
only inserts the (•) at the location of the error.
Such typing errors usually cause syntax errors (in this case, the name of the table is
unknown). The information area displays a description of the error when you validate the
line of code.
When this occurs, fix the typing error and type Enter (on the numeric pad) to validate
the fix. For more information about the Method editor, refer to the 4th Dimension Design
Reference.
Some syntax errors can be caught only when you execute the method. The Syntax Error
window is displayed when a syntax error occurs. For example:
In this window, the error is that a table name is passed to the Uppercase command, which
expects a text expression. To learn about this window and its button, see the section
Syntax Error window.
Environmental Error
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Occasionally, there there may not be enough memory to create an array or a BLOB.
When you access a document on disk, the document may not exist or may already open
by another application. In such cases, the Error window appears, describing the error and
the action that could not be performed. For example:
These errors do not directly occur because of your code or the way you wrote it; they
occur because sometimes “bad things just happen.” Most of the time, these errors are easy
to treat with an error catching method installed using the command ON ERR CALL. For
more information, see the description of ON ERR CALL.
These are generally the most difficult type of error to find—use the Debugger to detect
them. Note that, other than typing errors, all the previous error types are to a certain
extent covered by the expression “Design or logic error.” For example:
• A syntax error may occur because you try to use a variable that has not yet been
initialized.
• An environmental error may occur because you try to open a document whose name is
received by a subroutine which does not get the right value in the parameter. Note that
in this example, the piece of code that actually “breaks” may be different than the code
that is actually the origin of the problem.
Runtime Error
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In compiled mode, you can obtain errors that you never saw in interpreted mode. Here is
an example:
This says “You are trying to access a character whose position is beyond the length of a
string.” To quickly find the origin of the problem, note the name of the method and the
line number, reopen the interpreted version of the structure file, and go to that method
at the indicated line.
Errors are common. It would be unusual to write a substantial number of lines of code
(let’s say several hundred) without generating any errors. Conversely, treating and/or
fixing errors is normal, too!
A common beginner mistake in dealing with error detection is to click Abort in the
Syntax Error Window, go back to the Method Editor, and try to figure out what's going
by looking at the code. Do not do that! You will save plenty of time and energy by
always using the Debugger.
• If an unexpecting syntax error occurs, use the Debugger.
• If an environmental error occurs, use the Debugger.
• If any other type of error occurs, use the Debugger.
In 99% of the cases, the Debugger displays the information you need in order to
understand why an error occurred. Once you have this information, you know how to fix
the error.
Tip: A few hours spent in learning and experimenting with the Debugger can save days
and weeks in the future when you have to track down errors.
Another reason to use the Debugger is for developing code. Sometimes you may write an
algorithm that is more complex than usual. Despite all feelings of accomplishment, you
are not totally sure that your coding is correct, even before trying it. Instead of running it
“blind,” use the TRACE command at the beginning of your code. Then, execute it step by
step to control what happens and to check whether your suspicion was correct or not. A
purist may dislike this method, but somethimes pragmatism pays off more quickly.
Anyway... use the Debugger.
General Conclusion
Use the Debugger.
See Also
Break List, Catching Commands, Debugger, Debugger Shortcuts, ON ERR CALL, Syntax Error
Window, Tracing a Process not visible or not executing code.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Syntax Error Window is displayed when method execution is halted. Method
execution can be halted for either of two reasons:
• 4th Dimension halts execution because there is a syntax error preventing further
method execution.
• You generate a user interrupt by pressing Alt+Click (Windows) or Option+Click
(Macintosh) while a method is executing.
The upper text area of the Syntax Error window displays a message describing the error.
The lower text area shows the line that was executing when the error occurred; the area
where the error occurred is highlighted.
There are four option buttons at the bottom of the window: Abort, Trace, Continue, and
Edit.
• Abort: The method is halted, and you return to where you were before you started
executing the method. If a form or object method is executing in response to an event, it
is stopped and you return to the form. If the method is executing from within the
Custom Menu environment, you return to the Custom Menu environment.
• Trace: You enter Trace/Debugger mode, and the Debugger window is displayed. If the
current line has been partially executed, you may have to click the Trace button several
times. Once the line finishes, you end up in the Debugger window.
See Also
Debugger, ON ERR CALL, Why a Debugger?.
The term Debugger comes from the term bug. A bug in a method is a mistake that you
want to eliminate. When an error has occurred, or when you need to monitor the
execution of your methods, you use the debugger. A debugger helps you find bugs by
allowing you to slowly step through your methods and examine method information.
This process of stepping through methods is called tracing.
You can cause the Debugger window to display and then trace the methods in the
following ways:
• Clicking the Trace button in the Syntax Error Window
• Using the TRACE command
• Clicking the Debug button in the Execute Method window (User environment).
• Pressing Alt+Shift+Right click (Windows) or Control+Option+Command+Click
(Macintosh) while a method is executing, then selecting the process to trace in the pop-
up menu:
• Clicking the Trace button when a process is selected in the Process page of the Runtime
Explorer.
• Creating or editing a break point in the Method Editor window, or in the Break and
Catch pages of the Runtime Explorer.
Note: If a password system exists for the database, only the designer and users belonging
to the group that has structure access privileges can trace methods.
4D is a multi-tasking environment. If you run several user processes, you can trace them
independently. You can have one debugger window open for each process.
Nine buttons are located in the Execution Control Tool Bar at the top of the Debugger
window:
No Trace Button
Tracing is halted and normal method execution resumes.
Note: Shift+F5 or Shift+click on the No Trace button resumes execution. It also disables
all the subsequent TRACE calls for the current process.
Abort Button
The method is halted, and you return to where you were before you started executing the
method. If you were tracing a form or object method executing in response to an event,
it is stopped and you return to the form. If you were tracing a method executing from
within the Custom Menu environment, you return to the Custom Menu environment.
Edit Button
Clicking the Edit button does the same as Clicking Abort and Edit button, but does not
abort the current execution. The method execution is paused at that point. If necessary,
4th Dimension opens and brings the Design environment process to the front, then
opens a Method Editor window for the method that was executing at the time the Edit
button was clicked.
Important: You can modify this method; however, these modifications will not appear or
execute in the instance of the method currently being traced in the debugger window.
After the method has either aborted or completed successfully, the modifications will
appear on the next execution of this method. In other words, the method must be
reloaded so its modifications will be taken into account.
Tip: Use this button when you know which changes are required in your code and when
they do not interfere with the rest of the code to be executed or traced.
Tip: Object Methods are reloaded for each event. If you are tracing an object method (i.e.,
in response to a button click), you do not need to leave the form. You can edit the object
method, save the changes, then switch back to the form and retry. For tracing/changing
form methods, you must exit the form and reopen it in order to reload the form method.
When doing extensive debugging of a form, a trick is to put the code (that you are
debugging) into a project method that you use as subroutine from within a form method.
In doing so, you can stay in the form while you trace, edit, and retest your form, because
the subroutine is reloaded each time it is called by the form method.
On the right side of the execution control tool bar, the debugger provides the following
information:
• The name of the method you are currently tracing (displayed in black)
• The problem caused the appearance of the Debugger window (displayed in red)
Using the example window shown above, the following information is displayed:
• The method DE_DebugDemo is the method being traced.
• The debugger window appeared because it detected a call to the command C_DATE and
this command was one of the commands to be caught.
Here are the possible reasons for the debugger to appear and for the message (displayed in
red):
• TRACE Command: A call to TRACE has been issued.
• Break Point Reached: A temporary or persistent break point has been encountered.
The Debugger window consists of the previously described Execution Control Tool Bar
and four resizable panes:
• Watch Pane
• Call Chain Pane
• Custom Watch Pane
• Source Code Pane
The first three panes use easy-to-navigate hierarchical lists to display pertinent debugging
information. The fourth one, Source Code Pane, displays the source code of the method
being traced. Each pane has its own function to assist you in your debugging efforts. You
can use the mouse to vertically and horizontally resize the debugger window and also
each pane. In addition, the first three panes include a dotted separation line between the
two columns they display. Using the mouse, you can move this dotted line to
horizontally resize the columns, at your convenience.
See Also
Break List, Call Chain Pane, Catching Commands, Custom Watch Pane, Debugger Shortcuts,
ON ERR CALL, Source Code Pane, Syntax Error Window, TRACE, Watch Pane, Why a
Debugger?.
The Watch pane is displayed in the top left corner of the Debugger window, below the
Execution Control Tool Bar. Here is an example:
The Watch pane displays useful general information about the system, the 4D
environment, and the execution environment.
The Expression column displays the names of the objects or expressions. The Value
column displays the current value of corresponding the object or expression.
Clicking on any value on the right side of the pane allows you to modify the value of the
object, if this is permitted for that object.
The multi-level hierarchical lists are organized by theme at the main level. The themes
are:
• Line Objects
• Variables
• Constants
• Fields
• Semaphores
• Sets
• Processes
• Named Selections
• Information
• Cache Statistics
At any point, you can drag and drop themes, theme sublists (if any), and theme items to
the Custom Watch pane.
Cache Statistics: Displays statistics regarding the use of tables, index pages, and named
selections that are loaded in 4D’s cache. The expressions from this theme cannot be
modified.
Information: Displays general information, such the current Default Table (if any). The
expressions from this theme cannot be modified.
Named Selections: Lists the process named selections that are defined in the current
process (the one you’re currently tracing); it also lists the interprocess named selections.
For each named selection, the Value column displays the number of records and the table
name. This list may be empty if you do not use named selections. The expressions from
this theme cannot be modified.
Processes: Lists the processes started since the beginning of the working session. The
value column displays the time used and the current state for each process (i.e.,
Executing, Paused, and so on). The expressions from this theme cannot be modified.
Sets: Lists the sets defined in the current process (the one you're currently tracing); it also
lists the interprocess sets. For each set, the Value column displays the number of records
and the table name. This list may be empty if you do not use sets. The expressions from
this theme cannot be modified.
Semaphores: Lists the local semaphores currently being set. For each semaphore, the
Value column provides the name of the process that sets the semaphore. This list may be
empty if you do not use semaphores. The expressions from this theme cannot be
modified. Global semaphores are not displayed.
Tables & Fields: This theme lists the tables and fields in the database; it does not list
subfields. For each Table item, the Value column displays the size of the current selection
for the current process as well as (if the Table item is expanded) the number of locked
records. For each Field item, the Value column displays the value of the field (except
picture, subtable, and BLOB) for the current record, if any. In this theme, the field values
can be modified (there is no undo), but the table information cannot.
Constants: Displays predefined constants provided by 4D. like the Constants page of the
Explorer window. The expressions from this theme cannot be modified.
Line Objects
This theme displays the values of the objects or expressions that are:
• used in the line of code to be executed (the one marked with the program counter—the
yellow arrow in the Source Code pane), or
• used in the previous line of code.
Since the previous line of code is the one that was just executed before, the Line Objects
theme therefore shows the objects or expressions of the current line before and after that
the line was executed. Let's say you execute the following method:
TRACE
a:=1
b:=a+1
c:=a+b
` ...
The a variable is shown because it is used in the line to be executed (but has not yet been
initialized).
2. You step one line. The program counter is now set to the line b:=a+1. At this point, the
Line Objects theme displays:
a: 1
b: Undefined
The a variable is shown because it is used in the line that was just executed and was
assigned the numeric value 1. It is also shown because it is used in the line to be executed
as the expression to be assigned to the variable b. The b variable is shown because it is
used in the line to be executed (but has not yet been initialized).
3. Again, you step one line. The program counter is now set to the line c:=a+b. At this
point the Line Objects theme displays:
c: Undefined
a: 1
b: 2
The c variable is shown because it is used in the line to be executed (but has not yet been
initialized). The a and b variables are shown because there were used in the previous line
and are used in the line to be executed. And so on...
The Line Objects theme is a very convenient tool—each time you execute a line, you do
not need to enter an expression in the Custom Watch pane, just watch the values
displayed by the Line Objects theme.
Speed Menu
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Addtional options are provided by the Speed Menu of the Watch pane. To display this
menu:
• On Windows, click anywhere in the Watch pane using the right mouse button.
• On Macintosh, Control-Click anywhere in the Watch pane.
• Show Types: Displays the object type for each object (when appropriate).
• Show Field and Table Numbers: Displays the number of each table or field of the Fields.
If you work with table or field numbers, or with pointers using the commands such as
Table or Field, this option is very useful.
• Show Icons: Displays an icon denoting the object type for each object. You can turn this
option off in order to speed up the display, or just because you prefer to use only the
Show Types option.
• Sorted Tables and Fields: Forces the table and fields to be displayed in alphabetical order,
within their respective lists.
• Show Integers in Hexadecimal: Numbers are usually displayed in decimal notation. This
option displays them in hexadecimal notation. Note: To enter a numeric value in
hexadecimal, type 0x (zero + "x"), followed by the hexadecimal digits.
See Also
Call Chain Pane, Custom Watch Pane, Debugger, Debugger Shortcuts, Source Code Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
One method may call other methods, which may call other methods. For this reason, it
is very helpful to see the chain of methods, or Call Chain, during the debugging process.
The Call Chain pane, which provides this useful function, is the top right pane of the
Debugger window. This pane is displayed using a hierarchical list. Here is an example of
the Call Chain pane:
• Each main level item is a name of a method. The top item is the method you are
currently tracing, the next main level item is the name of the caller method (the method
that called the method you are currently tracing), the next one is the caller's caller
method, and so on. In the example above, the method M_BitTestDemo is being traced; it
has been called by the method DE_LInitialize, which has been called by DE_DebugDemo.
• Double-clicking the name of a method in the Call Chain pane “transports” you back to
the caller method, displaying its source code in the Source code pane. In doing so, you
can quickly see “how” the caller method made its call to the called method. You can
examine any stage of the call chain this way.
• Clicking the node next to a Method name expands or collapses the parameter ($1, $2...)
and the optional function result ($0) list for the method. The values appear on the right
side of the pane. Clicking on any value on the right side allows you to change the value
of any parameter or function result. In the figure above:
1. M_BitTestDemo has not received any parameter.
2. M_BitTestDemo's $0 is currently undefined, as the method did not assign any value to
$0 (because it has not executed this assignment yet or because the method is a subroutine
and not a function).
3. DE_LInitialize has received three parameters from DE_DebugDemo. $1 is a pointer to the
table [Customers], $2 is a pointer to the field [Customers]Company, and $3 is an
alphanumeric parameter whose value is "Z".
• After you have deployed the parameter list for a method, you can also drag and drop
parameters and function results to the Custom Watch pane.
See Also
Custom Watch Pane, Debugger, Debugger Shortcuts, Source Code Pane, Watch Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Directly below the Call Chain pane is the Custom Watch pane. This pane is used to
evaluate expressions. Any type of expression can be evaluated, including fields, variables,
pointers, calculations, built-in functions, your own functions, and anything else that
returns a value.
You can evaluate any expression that can be shown in text form. This does not cover
picture and BLOB fields or variables. On the other hand, the Debugger uses deployed
hierarchical lists to let you display arrays and pointers. To display BLOB contents, you can
use BLOB commands, such as BLOB to text.
In the following example, you can see several of these items: two variables, a field pointer
variable and the result of a built-in function, and a calculation.
You can add an expression to be evaluated in the Custom Watch pane in the following
way:
• Drag and drop an object or expression from the Watch pane
• Drag and drop an object or expression from the Call Chain pane
• In the Source Code pane, click on an expression that can be evaluated
To create a blank expression, double-click somewhere in the empty space of the Custom
Watch pane. This adds an expression ` New expression and then goes into editing mode so
you can edit it. You can enter any 4D formula that returns a result.
After you have entered the formula, type Enter or Return (or click somewhere else in the
pane) to evaluate the expression.
To change the expression, click on it to select it, then click again (or press Enter
—numeric key pad) to go into editing mode.
Warning: Be careful when you evaluate a 4D expression modifying the value of one of the
system variables (for instance, the OK variable) because the execution of the rest of the
method may be altered.
To help you enter and edit an expression, the Custom Watch Pane’s Speed menu gives
you access the 4D formula editor. In fact, the speed menu also proposes additional
options.
For more information about the Formula Editor, See the 4th Dimension User Reference
Manual.
• Insert Command: This hierarchical menu item is a shortcut for inserting a command as
a new expression, without using the Formula Editor.
• Collapse All/Expand All: Collapses or Expands all the expressions whose evaluation is
done by the means of a hierarchical list (i.e., pointers, arrays,...)
• Show Types: Displays the object type for each object (when appropriate).
• Show Field and Table Numbers: Displays the number of each table or field of the Fields.
If you work with table or field number or pointers using the commands such as Table or
Field, this option is very useful.
• Show Icons: Displays an icon denoting the object type for each object. You can turn this
option off in order to speed up the display, or just because you prefer to use only the
Show Types option.
• Show Integers in Hexadecimal: Numbers are displayed using the decimal notation. This
option displays them hexadecimal notation. Note: To enter a numeric value in
hexadecimal, type 0x (zero + "x"), followed by the hexadecimal digits.
See Also
Call Chain Pane, Debugger, Debugger Shortcuts, Source Code Pane, Watch Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Source Code pane shows the source code of the method being traced.
• If the method is too long to fit in the text area, you can scroll to view other parts of the
method.
• Moving the mouse pointer over any expression that can be evaluated (field, variable,
pointer, array,...) will cause a Tool Tip to display the current value of the object or
expression and its declared type.
Here is an example of the Source Code pane:
A tool tip is displayed because the mouse pointer was over the variable pTable which,
according to the tool tip, is a pointer to the table [Customers].
• You can also select a portion of the text in the area displaying the code being executed.
In this case, when the cursor is placed above the selected text, a tip displays the selected
object’s value:
Program Counter
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A yellow arrow in the left margin of the Source Code pane (see the figure above) marks
the next line that will be executed. This arrow is called the program counter. The
program counter always indicates the line that is about to be executed.
For debugging purposes, you can change the program counter for the method being on
top of the call chain (the method actually being executed). To do so, click and drag the
yellow arrow vertically, to the line you want.
Moving the program counter forward does NOT mean that the debugger is rapidly
executing the lines you skip. Similarily, moving the program counter backward does NOT
mean that the debugger is reversing the effect of the lines that has already been executed.
Moving the program counter simply tells the debugger to “pursue tracing or executing
from here.” All current settings, fields, variables, and so on are not affected by the move.
Here is an example of moving the program counter. Let’s say you are debugging the
following code:
` ...
If (This condition)
DO SOMETHING
Else
DO SOMETHING ELSE
End if
` ...
The program counter is set to the line If (This condition). You step once and you see that
the program counter moves to the line DO SOMETHING ELSE. This is unfortunate, because
you wanted to execute the other alternative of the branch. In this case, and provided that
the expression This condition does not perform operations affecting the next steps in your
testing, just move the program counter back to the line DO SOMETHING. You can now
continuing tracing the part of the code in which you are interested.
In the debugging process, you may need to skip the tracing of some parts of the code.
The debugger offers you several ways to execute code up to a certain point:
• While stepping, you can click on the Step Over button instead of Step Into button. This
is useful when you do not want to enter into possible subroutines or functions called in
the program counter line.
• If you mistakenly entered into a subroutine, you can execute it and directly go back to
the caller method by clicking on the Step Out button.
• If you have a TRACE call placed at some point, you can click the No Trace button, which
resumes the execution up to that TRACE call.
Now, let’s say you are executing the following code, with the program counter set to the
line ALL RECORDS([ThisTable]):
` ...
ALL RECORDS([ThisTable])
$vrResult:=0
For($vlRecord;1;Records in selection([ThisTable]))
$vrResult:=This Function([ThisTable]))
NEXT RECORD([ThisTable])
End for
If ($vrResult>=$vrLimitValue)
` ...
Your goal is to evaluate the value of $vrResult after the For loop has been completed. Since
it takes quite some execution time to reach this point in your code, you do not want to
abort the current execution, then edit the method in order to insert a TRACE call before
the line If ($vrResult....
One solution is to step through the loop, however, if the table [ThisTable] contains several
hundreds records, you are going to spend the entire day for this operation. In this type of
situation, the debugger offers you break points. You can insert break points by clicking in
the left margin of the Source Code pane.
For example:
You click in the left margin of the Source Code pane at the level of the line If ($vrResult...:
This resumes the normal execution up to the line marked with the break point. That line
is not executed itself—you are back to the trace mode. In this example, the whole loop
has consequently been executed normally. Then, when reaching the break point, you just
need to move the mouse button over $vrResult to evaluate its value at the exit point of
the loop.
Setting a break point beyond the program counter and clicking the No Trace button
allows you to skip portions of the method being traced.
Note: You can also set break points directly in 4D's Method Editor. Please refer to the
section Break Points.
A red break point is a persistent break point. Once you created it, it “stays.” Even though
you quit the database, then reopen it later on, the break point will be there.
See Also
Break Points, Call Chain Pane, Custom Watch Pane, Debugger, Watch Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
As explained in the Source Code pane section, you set a break point by clicking in the left
margin of the Source Code pane or of the Method Editor window, at the same level as the
line of code on which you want to create the break.
Note: Since you can insert, modify or delete break points either in the debugger's Source
Code pane or directly in the Method Editor, there is a dynamic interaction between the
Method Editor and the debugger (as well as the Runtime Explorer) in regards to break
points. However, temporary break points can be defined in the debugger only (see below).
In the following figure, a break point has been set, in the debugger, on the line
If($vrResult>=$vrLimitValue):
If you click again on the red bullet, the break point is deleted.
Pressing Alt-click (Windows) or Option-click (Macintosh) in the left margin of the Source
code pane or of the Method Editor window for a line of code, gives you access to the
Break Point Properties window.
• If you click on an existing break point, the window is displayed for that break point.
• If you click on a line where no break point was set, the debugger creates one and
displays the window for the newly created break point.
Location: This tells you the name of the method and the line number where the break
point is set. You cannot change this information.
Type: By default, the debugger lets you create persistent break points, depicted by a red
bullet in the source code pane of the debugger window. To create a temporary break
point, select the Temporary option. A temporary break point is useful when you want to
break just once in a method. A temporary break point is identified by a green bullet in the
source code pane of the Debugger window. You can also set a temporary break point
directly in the source code pane by clicking in the left margin while pressing Alt+Shift
(Windows) or Option+Shift (Macintosh).
Note: Temporary break points can be set in the debugger only.
Break when following expression is true: You can create conditional break points by
entering a 4D formula that returns True or False. For example, if you want to break at a
line only when Records in selection([aTable])=0, enter this formula, and the break will
occur only if there no record selected for the table [aTable], when the debugger
encounters the line with this break point. If you are not sure about the syntax of your
formula, click the Check Syntax button.
Number of times to skip before breaking: You can set a break point to a line of code
located in a loop structure (While, Repeat, or For) or located in subroutine or function
called from within a loop. For example, you know that the “problem” you are tracking
does not occur before at least the 200th iteration of the loop. Enter 200, and the break
point will activate at the 201st iteration.
You create and edit break point from within the Debugger or the Method Editor window.
You can also edit existing break points using the Break page of the Runtime Explorer. For
more information, see the section Break List window.
See Also
Break List, Catching Commands, Debugger, Source Code Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Break List is a page of the Runtime Explorer that enables you to manage the
persistent Break Points created in the Debugger Window or in the Method Editor.
See Also
Break Points, Catching Commands, Debugger, Source Code Pane, Why a Debugger?.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Caught Commands List is a page of the Runtime Explorer that enables you to add
additional breaks to your code by catching calls to 4D commands.
Catching a command enables you to start tracing the execution of any process as soon as
a command is called by that process. Unlike a break point, which is located in a particular
project method (and therefore triggers a trace exception only when it is reached), the
scope of catching a command includes all the processes that execute 4D code and call that
command.
Catching a command is a convenient way to trace large portions of code without setting
break points at arbitrary locations. For example, if a record that should not be deleted is
deleted after you have executed one or several processes, you can try to reduce the field of
your investigation by catching commands such as DELETE RECORD and DELETE
SELECTION. Each time these commands are called, you can check if the record in
question has been deleted, and thus isolate the faulty part of the code.
With some experience, you can combine the use of Break points and command catching.
This page lists the commands to be caught during execution. It is composed of two
columns:
• The left column displays the Enable/Disable status of the caught command, followed by
the name of the command.
• The right column displays the condition associated with the caught command, if any.
OR
1. Press the right mouse button (Control+Click on Macintosh) to display the speed menu.
2. Select Add New Catch, then select the desired command from the command themes
and names submenus. A new entry is added with the command you selected.
Tips
• Adding conditions to caught commands slows the execution, because the condition has
to be evaluated each time an exception is met. On the other hand, adding conditions
accelerates the debugging process, because it automatically skips occurrences that do not
match the conditions.
• Disabling a caught command has almost the same effect as deleting it. During
execution, the debugger spends almost no time on the entry. The advantage of disabling
an entry is that you do not have to recreate it when you need it again.
See Also
Break List, Break Points, Debugger.
This section lists all the shortcuts provided by the Debugger window.
→ Shift+F5 or Shift+click on the No Trace button resumes execution. Also, they disable
all the next TRACE calls for the current process.
Watch Pane
→ Right mouse button click (Windows) or Control-Click (Macintosh) in the Watch pane
pulls down the Watch Speed menu.
→ Double-click on an item of the Watch pane copies the item to the Custom Watch pane.
Call Chain Pane
→ Double-Click on a method name in the Call chain pane displays the method in the
Source Code pane at the line corresponding to the call in the call chain.
All Panes
→ Ctrl+* (Windows) or Command+* (MacOS) forces the updating of the Watch pane.
→ When no item is selected in any pane, typing Enter steps by one line.
→ When an item value is selected, use the arrows keys to navigate through the list.
→ When an item is being edited, use the arrow keys to move the cursor; use Ctrl-
A/X/C/V (Windows) or Command-A/X/C/V (Macintosh) as shortcuts to the Select
All/Cut/Copy/Paste menu commands of the Edit menu.
See Also
Call Chain Pane, Custom Watch Pane, Debugger, Source Code Pane, Watch Pane.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension allows built-in drag and drop capability between objects in your forms.
You can drag and drop one object to another, in the same window or in another window.
In other words, drag and drop can be performed within a process or from one process to
another.
4th Dimension does not include built-in drag and drop to and from the desktop or
another application. However, this functionality is provided by plug-ins developed by
4D Partners.
Note: As an introduction, we assume that a drag and drop action “transports” some data
from one point to another. Later, we will see that drag and drop can also be a metaphor
for an operation.
To drag and drop an object to another object, you must select the Draggable property for
that object in the Object Properties window. In a drag and drop operation, the object that
you drag is the source object.
To make an object the destination of a drag and drop operation, you must select the
Droppable property for that object in the Object Properties window. In a drag and drop
operation, the object that receives data is the destination object.
By default, newly created objects can be neither dragged nor dropped. It is up to you to
set these properties.
All objects in an input or dialog form can be made to be dragged and dropped. Individual
elements of an array (i.e., scrollable area) or items of a hierarchical list can be dragged and
dropped. Conversely, you can drag and drop an object over an individual element of an
array or item of a hierarchical list. However, you cannot drag and drop objects from the
detail area of an output form.
You can easily create a drag and drop user interface, because 4D allows you to use any type
of active object (field or variable) as source or destination objects. For example, you can
drag and drop a button.
Note: To drag a button labeled "draggable", you must first press the Alt (Windows) or
Option (MacOS) keys. Only 3D type buttons can de dragged directly.
An object that is capable of being both dragged and dropped can also be dropped onto
itself, unless you reject the operation. For details, see the discussion below.
4th Dimension insures the user interface part of the drag and drop capability. If you click
on a draggable object and then drag the mouse, 4D drags the object; it reflects this
operation on the screen with a dotted rectangle that follows the movements of the
mouse.
Note the reverse gray frame highlight around the text field area. The highlight indicates
the destination object (in this case, the text field). If you release the mouse button at this
point, 4D assumes that you want to drop the dragged object onto the highlighted
destination object.
In the Database Properties dialog box, you can set the drag and drop highlight of the
destination object to be a frame or a pattern (or both):
Note: The highlight of the destination object “follows” elements or items when the
destination object is an array (scrollable area) or a hierarchical list.
4th Dimension performs the user interface part of a drag and drop—it is up to you to
perform the programmatical part. To enable you to do so, 4D provides you with two form
events: On Drag Over and On Drop. Both events are sent to the destination object. During
a drag and drop operation, the object method of the source object is never involved.
In order to accept On Drag Over and On Drop, the destination object must have these two
events activated in their properties, as shown here:
• Property List:
• Object Properties:
To accept the drag, the destination object method must return 0 (zero), so you write
$0:=0. To reject the drag, the object method must return -1 (minus one), so you write
$0:=-1. During an On Drag Over event, 4D treats the object method as a function. If no
result is returned, 4D assumes that the drag is accepted.
If you accept the drag, the destination object is highlighted. If you reject the drag, the
destination is not highlighted. Accepting the drag does not mean that the dragged data is
going to be inserted into the destination object. It only means that if the mouse button
was released at this point, the destination object would accept the dragged data.
If you do not process the On Drag Over event for a droppable object, that object will be
highlighted for all drag over operations, no matter what the nature and type of the
dragged data.
The On Drag Over event is the means by which you control the first phase of a drag and
drop operation. Not only can you test if the dragged data is of a type compatible with the
destination object, and then accept or reject the drag; you can simultaneously notify the
user of this fact, because 4D highlights (or not) the destination object, based on your
decision.
The code handling an On Drag Over event should be short and execute quickly, because
that event is sent repeatedly to the current destination object, due to the movements of
the mouse.
WARNING: If the drag and drop is an interprocess drag and drop, which means the source
object is located in a process (window) other than that of the destination object, the
object method of the destination object for an On Drag Over event is executed within the
context of the source process (the source object's process), and not in the process of the
destination object. This is the only case in which such an execution occurs. The
advantages of this type of execution are described at the end of this section.
This event is not sent to the object if the drag was not accepted during the On Drag Over
events. If you process the On Drag Over event for an object and reject a drag, the On Drop
event does not occur. Thus, if during the On Drag Over event you have tested the data
type compatibility between the source and destination objects and have accepted a
possible drop, you do not need to re-test the data during the On Drop. You already know
that the data is suitable for the destination object.
An interesting aspect of the 4D drag and drop implementation is that 4D lets you do
whatever you want. Examples:
• If a hierarchical list item is dropped over a text field, you can insert the text of the list
item at the beginning, at the end, or in the middle of the text field.
• Your form contains a two-state picture button, which could represent an empty or full
trash can. Dropping an object onto that button could mean (from the user interface
standpoint) “delete the object that has been dragged and dropped into the trash can.”
Here, the drag and drop does not transport data from one point to another; instead, it
performs an action.
• Dragging an array element from a floating window to an object in a form could mean
“in this window, show the Customer record whose name you just dragged and dropped
from the floating window listing the Customers stored in the database.”
• And so on.
So, the 4D drag and drop interface is a framework which enables you to implement any
user interface metaphor you may devise.
The Drop position command returns the element number of the item position of the
target element or list item, if the destination object is an array (i.e., scrollable area) or a
hierarchical list,
Commands like RESOLVE POINTER and Type are useful for testing the nature and type of
the source object.
If the drag and drop is not intended to move data, but is instead a user interface
metaphor for a particular operation, you can perform whatever you want.
See Also
DRAG AND DROP PROPERTIES, Drop position, Form event, GET PROCESS VARIABLE, Is a list,
RESOLVE POINTER, Type.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Drop position command returns the array element number or list item position onto
which an object has been dragged and dropped.
Typically, you will use Drop position while handling a drag and drop event that occurred
over an array or a hierarchical list.
If the destination object is an array, the command returns an element number. If the
destination object is a hierarchical list, the command returns an item position. In both
cases, the command may return -1 if the source object has been dropped beyond the last
element or the last item.
If you call Drop position while handling an event that is not a drag and drop event and
that occurred over an array or a hierarchical list, the command returns -1.
Important: A form object accepts dropped data if its Droppable property has been
selected. Also, its object method must be activated for On Drag Over and/or On Drop, in
order to process these events.
Example
See examples for the command DRAG AND DROP PROPERTIES.
See Also
Drag and drop, DRAG AND DROP PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The DRAG AND DROP PROPERTIES command enables you to obtain the information
about the source object when an On Drag Over or On Drop event occurs for an object.
Typically, you use DRAG AND DROP PROPERTIES from within the object method of the
object (or from one of the subroutines it calls) for which the On Drag Over or On Drop
event occurs (the destination object).
Important: A form object accepts dropped data if its Droppable property has been
selected. Also, its object method must be activated for On Drag Over and/or On Drop, in
order to process these events.
If you call DRAG AND DROP PROPERTIES while there is no drag and drop event, srcObject
returns a NIL pointer, srcElement returns -1 and srcProcess returns 0.
Tip: 4th Dimension automatically handles the graphical aspect of a drag and drop. You
must then respon to the event in the appropriate way. In the following examples, the
response is to copy the data that has been dragged. Alternatively, you can implement
sophisticated user interfaces where, for example, dragging and dropping an array element
from a floating window will fill in the destination window (the window where the
destination object is located) with structured data (i.e., several fields coming from a record
uniquely identified by the source array element).
You use DRAG AND DROP PROPERTIES during an On Drag Over event in order to decide
whether the destination object accepts the drag and drop operation, depending on the
type and/or the nature of the source object (or any other reason). If you accept the drag
and drop, the object method must return $0:=0. If you do not accept the drag and drop,
the object method must return $0:=-1. Accepting or refusing the drag and drop is
reflected at the screen—the object is or is not highlighted as the potential destination of
the drag and drop operation.
Tip: During an On Drag Over event, the object method of the destination object is
executed within the context of the source object’s process. If the source object of an
interprocess drag and drop is a field, you can use the opportunity of this event to copy
the source data into an interprocess variable. In doing so, then later on, during the On
Drop event, you will not have to initiate an interprocess communication with the source
process in order to get the value of the field that was dragged. If an interprocess drag and
drop involves a variable as source object, you can use the GET PROCESS VARIABLE
command during the On Drop event.
Examples
1. In several of your database forms, there are scrollable areas in which you want to
manually reorder the elements by simple drag and drop from one part of the scrollable
area into another within it. Rather than writing specific code for each case, you may
implement a generic project method that will handle any one of these scrollable areas.
You could write something like:
Case of
: (Form event=On Drag Over)
DRAG AND DROP PROPERTIES($vpSrcObj;$vlSrcElem;$vlPID)
If ($vpSrcObj=$1)
Once you have implemented this project method, you can use it in the following way:
` anArray Scrollable Area Object Method
Case of
`...
: (Form event=On Drag Over)
$0:=Handle self array drag and drop (Self)
: (Form event=On Drop)
Handle self array drag and drop (Self)
` ...
End case
Case of
` Use this event for accepting or rejecting the drag and drop
: (Form event=On Drag Over)
` Initialize $0 for rejecting
$0:=-1
` Get the information about the drag and drop source object
DRAG AND DROP PROPERTIES($vpSrcObj;$vlSrcElem;$vlPID)
` In this example, we do not allow drag and drop from an object to itself
If ($vpSrcObj # $1)
` Get the type of the data which is being dragged
$vlSrcType:=Type($vpSrcObj->)
Case of
: ($vlSrcType=Is Alpha Field)
` Alphanumeric Field is OK
$0:=0
` Copy the value now into an IP variable
<>vtDraggedData:=$vpSrcObj->
: ($vlSrcType=Is Text)
` Text Field or Variable is OK
$0:=0
RESOLVE POINTER($vpSrcObj;$vsVarName;$vlTableNum;$vlFieldNum)
` If it is a field
If (($vlTableNum>0) & ($vlFieldNum>0))
` Copy the value now into an IP variable
<>vtDraggedData:=$vpSrcObj->
End if
: ($vlSrcType=Is String Var)
` String Variable is OK
$0:=0
: (($vlSrcType=String array) | ($vlSrcType=Text array))
` String and Text Arrays are OK
$0:=0
: (($vlSrcType=Is LongInt) | ($vlSrcType=Is Real)
If (Is a list($vpSrcObj->))
` Hierarchical list is OK
$0:=0
End if
End case
End if
End case
Once you have implemented this project method, you can use it in the following way:
` [anyTable]aTextField Object Method
Case of
` ...
: (Form event=On Drag Over)
$0:=Handle dropping to text area (Self)
See Also
Drag and Drop, Drop position, Form event, GET PROCESS VARIABLE, Is a list, RESOLVE
POINTER.
Entry Control
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
ACCEPT
Description
The command ACCEPT is used in form or object methods (or in subroutines) to:
• accept a new or modified record or subrecord, for which data entry has been initiated
using ADD RECORD, MODIFY RECORD, ADD SUBRECORD, or MODIFY SUBRECORD.
• accept a form displayed with the DIALOG command.
• exit a form displaying a selection of records, using DISPLAY SELECTION or MODIFY
SELECTION.
ACCEPT performs the same action as if a user had pressed the Enter key. After the form is
accepted, the OK system variable is set to 1.
It is also often used in the optional close box method for the Open window command. If
there is a Control-menu box on a window, ACCEPT or CANCEL can be called, in the
method to be executed, when the Control-menu box is double-clicked or the Close menu
command is chosen.
ACCEPT cannot be queued up. In response to an event, executing two ACCEPT commands
in a row from within a method would have the same effect as executing one.
See Also
CANCEL.
CANCEL
Description
The CANCEL command is used in form or object methods (or in a subroutine) to:
• cancel a new or modified record or subrecord, for which data entry has been initiated
using ADD RECORD, MODIFY RECORD, ADD SUBRECORD, or MODIFY SUBRECORD.
• cancel a form displayed with the DIALOG command.
• exit a form displaying a selection of records, using DISPLAY SELECTION or MODIFY
SELECTION.
• cancel the printing of a form that is about to be printed using the Print form command
(see below).
In the context of data entry, CANCEL performs the same action as if the user had pressed
the cancel key (Esc).
It is also often used in the optional close box method for the Open window command. If
there is a Control-menu box on a window, ACCEPT or CANCEL can be called, in the
method to be executed, when the Control-menu box is double-clicked or the Close menu
command is chosen.
CANCEL cannot be queued up. Executing two CANCEL commands in a row from within a
method in response to an event would have the same effect as executing only one.
Finally, this command can be used in the On Printing Detail form event, when using the
Print form command. In this context, the CANCEL command suspends the printing of the
form that is about to be printed, then resumes it on the next page. This mechanism can
be used to manage form printing when there is a lack of space or if a page break is
required.
Note: This operation differs from that of the PAGE BREAK(*) command that cancels ALL
the forms waiting to be printed.
See Also
ACCEPT, PAGE BREAK, Print form.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Keystroke → String
Description
Keystroke returns the character entered by the user into a field or an enterable area.
Usually, you will call Keystroke within a form or object method while handling an On
Before Keystroke event form. To detect keystroke events, use the command Form event.
To replace the character actually entered by the user with another character, use the
command FILTER KEYSTROKE.
IMPORTANT NOTE: If you want to perform some “on the fly” operations depending on
the current value of the enterable area being edited, as well as the new character to be
entered, remember that the text you see on screen is NOT YET the value of the data
source field or variable for the area being edited. The data source field or variable is
assigned the entered value after the data entry for the area is validated (e.g., tabulation to
another area, click on a button, and so on). It is therefore up to you to “shadow” the data
entry into a variable and then to work with this shadow value. You must do so if you
need to know the current text value for executing any particular actions. You can also use
the function Get edited text.
Examples
1. See examples for the command FILTER KEYSTROKE.
C_POINTER ($1;$2)
C_TEXT ($vtNewValue)
After this project method is added to your application, you can use it as follows:
` myObject enterable area object method
Case of
: (Form event=On Load)
MyObject:=""
MyShadowObject:=""
: (Form event=On Before Keystroke)
If (Handle keystroke (->MyObject;->MyShadowObject))
` Perform appropriate actions using the value stored in MyShadowObject
End if
End case
Using the interprocess communication capabilities of 4th Dimension, you can similarily
build user interfaces in which Lookup features are provided in floating windows that
communicate with processes in which records are listed or edited.
See Also
FILTER KEYSTROKE, Form event, Get edited text.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
FILTER KEYSTROKE enables you to replace the character entered by the user into a field or
an enterable area with the first character of the string filteredChar you pass.
Usually, you will call FILTER KEYSTROKE within a form or object method while handling
an On Before Keystroke form event. To detect keystroke events, use the command Form
event. To obtain the actual keystroke, use the command Keystroke.
IMPORTANT NOTE: The command FILTER KEYSTROKE allows you to cancel or replace the
character entered by the user with another character. On the other hand, if you want to
insert more than one character for a specific keystroke, remember that the text you see
on the screen is NOT YET the value of the data source field or variable for the area being
edited. The data source field or variable is assigned the entered value after the data entry
for the area is validated. It is therefore up to you to “shadow” the data entry into a
variable and then to work with this shadow value and reassign the enterable area (see the
example in this section).
WARNING: If you call the command Keystroke after calling FILTER KEYSTROKE, the
character you pass to this command is returned instead of the character actually entered.
All the digits entered in the area myObject are transformed into star characters.
2. This code implements the behavior of a Password enterable area in which all the
entered characters are replaced (on the screen) by random characters:
` vsPassword enterable area object method
Case of
: (Form event=On Load )
vsPassword:=""
vsActualPassword:=""
: (Form event=On Before Keystroke )
Handle keystroke (->vsPassword;->vsActualPassword)
If (Position(Keystroke;Char(Backspace )+Char(Left Arrow Key )+
Char(Right Arrow Key )+Char(Up Arrow Key )+Char(Down Arrow Key ))=0)
⇒ FILTER KEYSTROKE(Char(65+(Random%26)))
End if
End case
After the data entry is validated, you retrieve the actual password entered by the user in
the variable vsActualPassword. Note: The method Handle keystroke is listed in the Example
section for the command Keystroke.
3. In your application, you have some text areas into which you can enter a few
sentences. Your application also includes a dictionary table of terms commonly used
throughout your database. While editing your text areas, you would like to be able to
quickly retrieve and insert dictionary entries based on the selected characters in a text
area. You have two ways to do this:
- Provide some buttons with associated keys, or
- Intercept special keystrokes during the editing of the text area
This example implements the second solution, based on the Help key.
After you have added these project methods to your project, you can use them in this
way:
` vsDescription enterable area object method
Case of
: (Form event=On Load )
vsDescription:=""
vsShadowDescription:=""
` Establish the list of the “forbidden” characters to be treated as special keys
` ( here, in this example, only the Help Key is filtered)
vsSpecialKeys:=Char(HelpKey)
: (Form event=On Before Keystroke )
$vsKey:=Shadow keystroke (->vsDescription;->vsShadowDescription;vsSpecialKeys)
Case of
: (Ascii($vsKey)=Help Key )
` Do something when the Help key is pressed
` Here, in this example, a Dictionary entry must be searched and inserted
LOOKUP DICTIONARY (->vsDescription;->vsShadowDescription)
End case
End case
C_POINTER($1;$2)
C_LONGINT($vlStart;$vlEnd)
See Also
Form event, Keystroke.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GOTO AREA is used to select the data entry object object as the active area
of the form. It is equivalent to the user’s clicking on or tabbing into the field or variable.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
specify a field or variable reference (field or variable objects only) instead of a string. For
more information about object names, see the section Object Properties.
Note: This command only functions in input forms. It has no effect on data entry areas
located in subform List forms.
Examples
(1) The GOTO AREA command can be used in both ways:
See Also
REJECT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
REJECT {(field)}
Description
REJECT has two forms. The first form has no parameters. It rejects the entire data entry
and forces the user to stay in the form. The second form rejects only the field and forces
the user to stay in the field.
Note: You should consider the built-in data validation tools before using this command.
The first form of REJECT prevents the user from accepting a record that is not complete.
You can achieve the same result without using REJECT—you associate the Enter key with a
No Action button and use the ACCEPT and CANCEL commands to accept or cancel the
record, after the fields have been entered correctly. It is recommended that you use this
second technique and do not use the first form of REJECT.
If you use the first form, you execute REJECT to prevent the user from accepting a record,
usually because the record is not complete or has inaccurate entries. If the user tries to
accept the record, executing REJECT prevents the record from being accepted; the record
remains displayed in the form. The user must continue with data entry until the record is
acceptable, or cancel the record.
The best place to put this form of REJECT is in the object method of an Accept button
associated with the Enter key. This way, validation occurs only when the record is
accepted, and the user cannot bypass the validation by pressing the Enter key.
The second form of REJECT is executed with the field parameter. The cursor stays in the
field area. This form of REJECT forces the user to enter a correct value. It must be used
immediately following a modification to the field. You can test for modification by using
the Modified function. You can also use REJECT in the object method for the data entry
area. This command has no effect on fields in subform areas.
You must put either form of the REJECT command in the form method or object method
for the form that is being modified. If you are using REJECT for the subform’s Detail Form
for a table, put it in the form method or object method for the Detail Form.
You can use HIGHLIGHT TEXT to select the data in the field that is being rejected.
2. The following example is part of an object method for an [Employees]Salary field. The
object method tests the [Employees]Salary field and rejects the field if it is less than
$10,000. You could perform the same operation by specifying a minimum value for the
field in the form editor:
If ([Employees]Salary<10000)
ALERT ("Salary must be greater than $10,000")
⇒ REJECT ([Employees]Salary)
End if
See Also
ACCEPT, CANCEL, GOTO AREA.
Form Events
Description
Form event returns a numeric value identifying the type of form event that has just
occurred. Usually, you will use Form event from within a form or object method.
When a form event occurs, 4th Dimension performs the following actions:
• First, it browses the objects of the form and calls the object method for any object
(involved in the event) whose corresponding object event property has been selected.
• Second, it calls the form method if the corresponding form event property has been
selected.
Do not assume that the object methods, if any, will be invoked in a particular order. The
rule of thumb is that the object methods are always called before the form method. If an
object is a subform, the object methods of the subform’s list form are called, then the
form method of the list form is called. 4D then continues to call the object methods of
the parent form. In other words, when an object is a subform, 4D uses the same rule of
thumb for the object and form methods within the subform object.
Except for the On Load and On Unload events, if the form event property is not selected
for a given event, this does not prevent calls to the object methods for the objects whose
same event property is selected. In other words, enabling or disabling an event at the
form level has no effect on the object event properties.
The number of objects involved in an event depends on the nature of the event:
• On Load event - All the objects of the form (from any page) whose On Load object event
property is selected will have their object method invoked. Then, if the On Load form
event property is selected, the form will see its form method invoked.
• On Activate or On Resize event - No object method will be invoked, because this event
applies to the form as a whole and not to a particular object. Consequently, if the On
Activate form event property is selected, only the form will see its form method invoked.
• On Drag Over event - Only the droppable object involved in the event will see its object
method invoked if its On Drag Over object event property is selected. The form method
will not be called.
• On Open Detail and On Close Detail events - These events are triggered only in the
context of an output form displayed using DISPLAY SELECTION or MODIFY SELECTION,
when an existing record is displayed or modified. These events must be placed in the
output form method.
WARNING: Unlike all other events, during an On Drag over event, the object method for
an object is executed in the context of the process of the drag and drop source object, not
in the context of the process of the drag and drop destination object. For more
information, see the commands DRAG AND DROP PROPERTIES and Drag and drop
position.
The following table summarizes how object and form methods are called for each event
type:
Event Object Methods Form Method Which Objects
On Load Yes Yes All objects
On Unload Yes Yes All objects
On Validate Yes Yes All objects
On Clicked Yes (if clickable) (*) Yes Involved object only
On Double Clicked Yes (if clickable) (*) Yes Involved object only
On Before Keystroke Yes (if keyboard enterable) (*) Yes Involved object only
On After Keystroke Yes (if keyboard enterable) (*) Yes Involved object only
On Getting Focus Yes (if tabbable) (*) Yes Involved object only
On losing Focus Yes (if tabbable) (*) Yes Involved object only
On Activate Never Yes None
On Deactivate Never Yes None
On Outside Call Never Yes None
On Drop Yes (if droppable) (*) Yes Involved object only
On Drag Over Yes (if droppable) (*) Never Involved object only
On Menu Selected Never Yes None
On Data Change Yes (if modifiable) (*) Yes Involved object only
On Plug in Area Yes Yes Involved object only
On Header Yes Yes All objects
On Printing Detail Yes Yes All objects
On Printing Break Yes Yes All objects
On Printing Footer Yes Yes All objects
On Close Box Never Yes None
On Display Detail Yes Yes All objects
On Open Detail Never Yes None
On Close Detail Never Yes None
On Resize Never Yes None
On Timer Never Yes None
(*) For more infomation, see the section Events, Objects and Properties below.
IMPORTANT: Always keep in mind that, for any event, the method of a form or an object
is called if the corresponding event property is selected for the form or objects. The
benefit of disabling events in the Design environment (using the Form and Object
Properties windows) is that you can greatly reduce the number of calls to methods and
therefore significantly optimize the execution speed of your forms.
An object method is called if the event can actually occur for the object, depending on its
nature and properties. The following section details the events you will generally use to
handle the various types of objects.
Clickable Objects
Clickable objects are mainly handled using the mouse. They include:
• Boolean enterable fields or variables
• Buttons, default buttons, radio buttons, check boxes, button grid
• 3D Buttons, 3D radio buttons, 3D check boxes
• Pop-up menus, hierarchical pop-up menus, picture menus
• Drop-down lists, menus/drop-down lists
• Scrollable areas, hierarchical lists
• Invisible buttons, highlight buttons, radio pictures
• Thermometers, rulers, dials (also known as slider objects)
• Tab controls
• Splitters
After the On Clicked or On Double Clicked object event property is selected for one of these
objects, you can detect and handle the clicks within or on the object, using the Form
event command that returns On Clicked or On Double Clicked, depending on the case.
If both events are selected for an object, the On Clicked and then the On Double Clicked
events will be generated when the user double-clicks the object.
For all these objects, the On Clicked event occurs once the mouse button is released.
However, there are two exceptions:
• Invisible buttons - The On Clicked event occurs as soon as the click is made and does not
wait for the mouse button to be released.
• Slider objects (thermometers, rulers, and dials) - If the display format indicates that the
object method must be called while you are sliding the control, the On Clicked event
occurs as soon as the click is made.
Note: Some of these objects can be activated with the keyboard. For example, once a
check box gets the focus, it can be entered using the space bar. In such a case, an On
Clicked event is still generated.
WARNING: Combo boxes are not considered to be clickable objects. A combo box must be
treated as an enterable text area whose associated drop-down list provides default values.
Consequently, you handle the data entry within a combo box through the On Before
Keystroke, On After Keystroke and On Data Change events.
Modifiable Objects
Modifiable objects have a data source whose value can be changed using the mouse or the
keyboard; they are not truly considered as user interface controls handled through the On
Clicked event. They include:
• All enterable field objects (except Subtable and BLOB)
• All enterable variables (except BLOB, Pointer, and Array)
• Combo boxes
• External objects (for which full data entry is accepted by the 4D Extension)
These objects receive On Data Change events. After the On Data Change object event
property is selected for one of these objects, you can detect and handle the change of the
data source value, using the command Form event that will return On Data Change.
Tabbable Objects
Tabbable objects get the focus when you use the Tab key to reach them and/or click on
them. The object having the focus receives the characters (typed on the keyboard) that
are not accelerators (Windows) or shortcuts (MacOS) to a menu item or to an object such
as a button.
All objects are tabbable, EXCEPT the following:
• Non-enterable fields or variables
• Buttons (when used on MacOS)
• Button grid
• 3D buttons, 3D radio buttons, 3D check boxes
• Pop-up menus, hierarchical pop-up menus
• Menus/drop-down lists (when used on MacOS)
• Picture menus
After the On Getting Focus and/or On losing Focus object event properties are selected for a
tabbable object, you can detect and handle the change of focus, using the command
Form event that will return On Getting Focus or On losing Focus, depending on the case.
Event Categories
Form events can be classified in the following categories:
• General events: On Load, On Unload, On Validate, On Display Detail, On Open Detail,
On Close Detail
• Events proper to the form: On Activate, On Deactivate, On Outside Call, On Close Box,
On Menu Selected, On Timer, On Resize
• Events related to user actions: On Clicked, On Double Clicked, On Before Keystroke, On
After Keystroke, On Getting Focus, On losing Focus, On Data Change, On Plug in Area
• Drag and drop events: On Drop, On Drag Over
• Printing Events: On Header, On Printing Detail, On Printing Break, On Printing Footer
When you open a V3 database using 4th Dimension V6, the program performs two
operations:
• Converts the structure file to the new format.
• Converts the data file to the new format.
When using the database after the conversion, if a form has not been edited or modified
in the Design environment, it is still stored in the structure file in the way it was with V3.
In order to insure compatibility with your existing V3 applications, the form and object
event properties are automatically set to reflect the settings “ala V3”. This means that the
V6 event properties will be automatically selected and the “old V3 commands” will act as
they did with version 3:
Once you start editing a form and its objects in V6, the form and object event properties
are, by default, set according to the same scheme. To take advantage of the new events
introduced by V6, select the event properties for the form and objects in the Design
environment, and modify the form and object methods using the new Form event
command.
The new events that allow you to perform actions better tuned to the nature of the
events are:
V6 Events V3 Layout Execution cycles V3 command
On Clicked Generic During phase During
On Double Clicked Generic During phase During
On Menu Selected Generic During phase During plus Menu selected
On Data Change Generic During phase During
On Plug in Area Generic During phase During
On Printing Detail Generic During phase During
On Display Detail Before and During phase Before & During
On Open Detail Generic During phase During
On Close Detail Generic During phase During
2. This example shows the On Validate event being used to automatically assign (to a field)
the date that the record is modified:
` Method of a form
Case of
` ...
⇒ : (Form event=On Validate)
[aTable]Last Modified On:=Current date
End case
3. In this example, the complete handling of a drop-down list (initialization, user clicks,
and object release) is encapsulated in the method of the object:
` asBurgerSize Drop-down list Object Method
Case of
⇒ : (Form event=On Load)
ARRAY STRING(31;asBurgerSize;3)
asBurgerSize{1}:="Small"
asBurgerSize{1}:="Medium"
asBurgerSize{1}:="Large"
⇒ : (Form event=On Clicked)
If (asBurgerSize#0)
ALERT("You chose a "+asBurgerSize{asBurgerSize}+" burger.")
End if
⇒ : (Form event=On Unload)
CLEAR VARIABLE(asBurgerSize)
End case
Note: For other examples showing how to handle On Drag Over and On Drop events, see
the examples of the command DRAG AND DROP PROPERTIES.
5. This example is a template for a form method. It shows each of the possible events that
can occur while a summary report uses a form as an output form:
` Method of a form being used as output form for a summary report
$vpFormTable:=Current form table
Case of
` ...
⇒ : (Form event=On Header)
` A header area is about to be printed
Case of
: (Before selection($vpFormTable->))
` Code for the first break header goes here
: (Level = 1)
` Code for a break header level 1 goes here
: (Level = 2)
` Code for a break header level 2 goes here
` ...
End case
⇒ : (Form event=On Printing Detail)
` A record is about to be printed
` Code for each record goes here
⇒ : (Form event=On Printing Break)
` A break area is about to be printed
Case of
6. This example shows the template of a form method that handles the events that can
occur for a form displayed using the commands DISPLAY SELECTION or MODIFY
SELECTION. For didactic purposes, it displays the nature of the event in the title bar of the
form window.
` A Form method
Case of
⇒ : (Form event=On Load)
$vsTheEvent:="The form is about to be displayed"
⇒ : (Form event=On Unload)
$vsTheEvent:="The output form has been exited and is about to disappear from
the screen"
⇒ : (Form event=On Display Detail)
$vsTheEvent:="Displaying record #"+String(Selected record
number([TheTable]))
⇒ : (Form event=On Menu Selected)
$vsTheEvent:="A menu item has been selected"
⇒ : (Form event=On Header")
$vsTheEvent:="The header area is about to be drawn"
⇒ : (Form event=On Clicked")
$vsTheEvent:="A record has been clicked"
⇒ : (Form event=On Double Clicked")
$vsTheEvent:="A record has been double clicked"
⇒ : (Form event=On Open Detail)
$vsTheEvent:="The record #"+String(Selected record number([TheTable]))+" is
double-clicked"
⇒ : (Form event=On Close Detail)
$vsTheEvent:="Going back to the output form"
⇒ : (Form event=On Activate)
$vsTheEvent:="The form's window just become the frontmost window"
⇒ : (Form event=On Deactivate)
$vsTheEvent:="The form's window is no longer the frontmost window"
7. For examples on how to handle On Before Keystroke and On After Keystroke events, see
examples for the commands Get edited text, Keystroke and FILTER KEYSTROKE.
8. This example shows how to treat clicks and double clicks in the same way as a scrollable
area:
` asChoices scrollable area object method
Case of
⇒ : (Form event=On Load)
ARRAY STRING (...;asChoices;...)
` ...
asChoices:=0
⇒ : ((Form event=On Clicked) | (Form event=On Double Clicked))
If (asChoices#0)
` An item has been clicked, do something here
` ...
End if
` ...
End case
9. This example shows how to treat clicks and double clicks using a different response.
Note the use of the element zero for keeping track of the selected element:
` asChoices scrollable area object method
Case of
⇒ : (Form event=On Load)
ARRAY STRING (...;asChoices;...)
` ...
asChoices:=0
asChoices{0}:="0"
⇒ : (Form event=On Clicked)
If (asChoices#0)
If (asChoices#Num(asChoices))
` A new item has been clicked, do something here
` ...
` Save the new selected element for the next time
asChoices{0}:=String (asChoices)
End if
Else
10. This example shows how to maintain a status text information area from within a
form method, using the On Getting Focus and On losing Focus events:
` [Contacts];"Data Entry" form method
Case of
⇒ : (Form Event=On Load)
C_TEXT(vtStatusArea)
vtStatusArea:=""
⇒ : (Form Event=On Getting Focus)
RESOLVE POINTER (Last object;$vsVarName;$vlTableNum;$vlFieldNum)
If (($vlTableNum#0) & ($vlFieldNum#0))
Case of
: ($vlFieldNum=1) ` Last name field
vtStatusArea:="Enter the Last name of the Contact, it will be
automatically capitalized"
` ...
: ($vlFieldNum=10) ` Zip Code field
vtStatusArea:="Enter a 5-digit zip code, it will be automatically checked
and validated"
` ...
End case
End if
⇒ : (Form Event=On Losing Focus)
vtStatusArea:=""
` ...
End case
11. This example shows how to respond to a close window event with a form used for
record data entry:
` Method for a data entry form
$vpFormTable:=Current form table
Case of
` ...
⇒ : (Form Event=On Close Box)
If (Modified record($vpFormTable->))
CONFIRM ("This record has been modified. Save Changes?")
If (OK=1)
ACCEPT
12. This example shows how to capitalize a text or alphanumeric field each time its data
source value is modified:
` [Contacts]First Name Object method
Case of
` ...
: (Form event=On Data Change)
[Contacts]First Name:= Uppercase(Substring([Contacts]First Name;1;1))
+Lowercase(Substring([Contacts]First Name;2))
` ...
End case
See Also
CALL PROCESS, Current form table, DRAG AND DROP PROPERTIES, FILTER KEYSTROKE, Get
edited text, Keystroke, SET TIMER.
version 3
Compatibility Note
This command has been kept in 4D for compatibility reasons. Starting with version 6,
you should consider using the command Form event and checking if it returns an On
Load event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Before → Boolean
Description
In order for the Before execution cycle to be generated, make sure that the On Load event
property for the form and/or the objecs has been selected in the Design environment.
See Also
Form event.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an event such
as On Clicked.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
During → Boolean
Description
In order for the During execution cycle to be generated, make sure that the appropriate
event properties, such as On Clicked, for the form and/or the objects have been selected in
the Design environment.
See Also
Form event.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On Validate
event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
After → Boolean
Description
In order for the After execution cycle to be generated, make sure that the On Validate
event property for the form and/or the objects has been selected in the Design
environment.
See Also
Form event.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On Header
event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In header → Boolean
Description
In order for the In header execution cycle to be generated, make sure that the On Header
event property for the form and/or the objects has been selected in the Design
environment.
See Also
During, In break, In footer.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On Printing
Break event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In break → Boolean
Description
In order for the In break execution cycle to be generated, make sure that the On Printing
Break event property for the form and/or the objects has been selected in the Design
environment.
See Also
During, In footer, In header.
version 3
Compatibility Note
This command has been kept for compatibility reason. Starting with version 6, you may
want to start using the command Form event and check if it returns an On Printing Footer
event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In footer → Boolean
Description
In order for the In footer execution cycle to be generated, make sure that the On Printing
footer event property for the form and/or the objects has been selected in the Design
environment.
See Also
During, In break, In header.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On Activate
event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Activated → Boolean
Description
The command Activated returns TRUE in a form method when the window containing
the form becomes the frontmost window of the frontmost process.
WARNING: Do not place a command such as TRACE or ALERT in the Activated phase of the
form, as this will cause an endless loop.
Note: In order for the Activated execution cycle to be generated (for compatibility with
V3 databases), make sure that the On Activate event property of the form has been
selected in the Design environment. This is done automatically when a database is
converted.
See Also
Deactivated, Form event.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On
Deactivate event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Deactivated → Boolean
Description
The command Deactivated returns TRUE in a form or object method when the frontmost
window of the frontmost process, containing the form, moves to the back.
In order for the Deactivated execution cycle to be generated, make sure that the On
Deactivate event property of the form and/or the objects has been selected in Design
environment.
See Also
Activated, Form event.
version 3
Compatibility Note
This command has been kept for compatibility reasons. Starting with version 6, you
should consider using the command Form event and checking if it returns an On Outside
call event.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
In order for the Outside call execution cycle to be generated, make sure that the On
Outside call event property for the form and/or the objects has been selected in the Design
environment.
See Also
CALL PROCESS, Form event.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get edited text is mainly to be used with the form event On After Keystroke
to retrieve the text as it is being entered. It can also be used with the On Before Keystroke
form event. For more information about those form events, please refer to the description
of the command Form event.
Note: To be in accordance with the new form event On After Keystroke (introduced in
version 6.5 of 4D), the existing event On Keystroke has been renamed, and is now called
On Before Keystroke.
When used in a context other than text entry in a form object, this function returns an
empty string.
Examples
(1) The following method automatically puts the characters being entered in capitals:
If (Form event=On After Keystroke)
⇒ [Trips]Agencies:=Uppercase(Get edited text)
End if
(2) Here is an example of how to process on the fly characters entered in a text field. The
idea consists of placing in another text field (called “Words”) all the words of the
sentence being entered. To do so, write the following code in the object method of the
field:
If (Form event=On After Keystroke)
⇒ $RealTimeEntry:=Get edited text
PLATFORM PROPERTIES($platform)
If ($platform#3) ` MacOS
Repeat
$DecomposedSentence:=Replace string($RealTimeEntry;Char(32);Char(13))
Until (Position(" ";$DecomposedSentence)=0)
Else ` Windows
Repeat
Note: This example is not comprehensive because we have assumed that words are
separated uniquely by spaces (Char (32)). For a complete solution you will need to add
other filters to extract all the words (delimited by commas, semi-colons, apostrophes,
etc.).
See Also
Form event.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET TIMER allows you to activate the On Timer form event and to set, for
the current process, the number of ticks elapsed between each On Timer form event.
Note: For more information about this new form event, please refer to the description of
the command Form event.
If this command is called in a context in which it is not displaying a form, it will have no
effect.
4D’s Web server can take advantage of this command as well as the On Timer form event
to resend 4D forms. This feature allows you to obtain HTML pages updated in “real time”
while saving bandwidth. Actually, updating a form in this case is not automatic; you must
call the REDRAW command. You can then optimize the system by calling REDRAW only
when the data has been modified.
Only browsers that interpret JavaScript allow you to automatically redraw pages. The laps
defined by SET TIMER will be used by the browser and by the timeout of the Web process.
The laps must be a few seconds (5 being a practical value). For more information, please
refer to the second example shown below.
To procedurally disable the triggering of the On Timer form event, call SET TIMER again
and pass 0 in tickCount.
Examples
(1) Let’s imagine that you want, when a form is displayed on screen, the computer to
beep every three seconds. To do so, write the following form method:
If (Form event=On Load)
⇒ SET TIMER(60*3)
End if
See Also
Form event, REDRAW.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Right click returns True if the right button of the mouse has been clicked.
This command should be used only in the context of the On clicked form event. It is
therefore necessary to verify in Structure mode that the event has been properly selected
in the Form properties and/or in the specific object.
Note: This command only operates under Windows and MacOS X. It will always return
the value False under MacOS 9.
See Also
Contextual click, Form event.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Contextual click returns True if a contextual click has been made:
• Under Windows, contextual clicks are made using the right button of the mouse.
• Under MacOS, contextual clicks are made using a Control+click combination.
This command should be used only in the context of the On clicked form event. It is
therefore necessary to verify in Structure mode that the event has been properly selected
in the Form properties and/or in the specific object.
Example
This method, combined with a scrollable area, enables you to change the value of an array
element using a contextual menu:
⇒ If(Contextual click)
If (Pop up menu("True;False")=1)
myArray{myArray}:="True"
Else
myArray{myArray}:="False"
End if
End if
See Also
Form event, Right click.
Form Pages
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Automatic action buttons perform the same tasks as the FIRST PAGE, LAST PAGE, NEXT
PAGE, and PREVIOUS PAGE commands. In addition, version 6 introduces a new automatic
action equivalent to GOTO PAGE that you can apply to objects such as tab controls, drop-
down list boxes, and so on. Whenever appropriate, use automatic action buttons instead
of commands.
Page commands can be used with input forms or with forms displayed in dialogs. Output
forms use only the first page. A form always has at least one page—the first page.
Remember that regardless of the number of pages a form has, only one form method
exists for each form.
Use the Current form page command to find out which page is being displayed.
Note: When designing a form, you can work with pages 1 through N, as well as with page
0, in which you put objects that will appear in all of the pages. When using a form, and
therefore when calling the form pages commands, you work with pages 1 through N;
page 0 is automatically combined with the page being displayed.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
FIRST PAGE
Description
FIRST PAGE changes the currently displayed form page to the first form page. If a form is
not being displayed, or if the first form page is already displayed, FIRST PAGE does
nothing.
Example
The following example is a one-line method called from a menu command. It displays the
first form page:
⇒ FIRST PAGE
See Also
Current form page, GOTO PAGE, LAST PAGE, NEXT PAGE, PREVIOUS PAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
LAST PAGE
Description
LAST PAGE changes the currently displayed form page to the last form page. If a form is
not being displayed, or if the last form page is already displayed, LAST PAGE does nothing.
Example
The following example is a one-line method called from a menu command. It displays the
last form page:
⇒ LAST PAGE
See Also
Current form page, FIRST PAGE, GOTO PAGE, NEXT PAGE, PREVIOUS PAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
NEXT PAGE
Description
NEXT PAGE changes the currently displayed form page to the next form page. If a form is
not being displayed, or if the last form page is already displayed, NEXT PAGE does
nothing.
Example
The following example is a one-line method called from a menu command. It displays the
form page that follows the one currently displayed:
⇒ NEXT PAGE
See Also
Current form page, FIRST PAGE, GOTO PAGE, LAST PAGE, PREVIOUS PAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
PREVIOUS PAGE
Description
PREVIOUS PAGE changes the currently displayed form page to the previous form page. If a
form is not being displayed, or if the first form page is already displayed, PREVIOUS PAGE
does nothing.
Example
The following example is a one-line method called from a menu command. It displays the
form page that precedes the one currently displayed:
⇒ PREVIOUS PAGE
See Also
Current form page, FIRST PAGE, GOTO PAGE, LAST PAGE, NEXT PAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GOTO PAGE changes the currently displayed form page to the form page specified by
pageNumber.
If a form is not being displayed, GOTO PAGE does nothing. If pageNumber is greater than
the number of pages, the last page is displayed. If pageNumber is less than one, the first
page is displayed.
Examples
The following example is an object method for a button. It displays a specific page, page
3:
See Also
Current form page, FIRST PAGE, LAST PAGE, NEXT PAGE, PREVIOUS PAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Current form page command returns the number of the currently displayed form
page.
Example
In a form, when you select a menu item from the menu bar or when the form receives a
call from another process, you can perform different actions depending on the form page
currently displayed. In this example, you write:
` [myTable];"myForm" Form Method
Case of
: (Form event=On Load)
` ...
: (Form event=On Unload)
` ...
: (Form event=On Menu selected)
$vlMenuNumber:=Menu Selected >> 16
$vlItemNumber:=Menu Selected & 0xFFFF
Case of
: ($vlMenuNumber=...)
Case of
: ($vlItemNumber=...)
⇒ : (Current form page=1)
` Do appropriate action for page 1
⇒ : (Current form page=2)
` Do appropriate action for page 2
` ...
: ($vlItemNumber=...)
` ...
End case
: ($vlMenuNumber=...)
` ...
End case
See Also
FIRST PAGE, GOTO PAGE, LAST PAGE, NEXT PAGE, PREVIOUS PAGE.
Graphs
Description
GRAPH draws a graph for a Graph area located in a form. The data can come from either
arrays or subfields.
The graphArea parameter is the name of the Graph area that displays the graph. The
Graph area is created in the Form editor, using the graph object type. The graph name is
the name entered for the variable name. For information about creating a Graph area, see
the 4th Dimension Design Reference.
The xLabels parameter defines the labels that will be used to label the x-axis (the bottom of
the graph). This data can be of string, date, time, or numeric type. There should be the
same number of subrecords or array elements in xLabels as there are subrecords or array
elements in each of the yElements.
The data specified by yElements is the data to graph. The data must be numeric. Up to
eight data sets can be graphed. Pie charts graph only the first yElements.
Examples
1. The following example shows how to use arrays to create a graph. The code would be
inserted in a form method or object method. It is not intended to be realistic, since the
data is constant:
ARRAY STRING (4; X; 2) ` Create an array for the x-axis
X{1}:="1995" ` X Label #1
X{2}:="1996" ` X Label #2
ARRAY REAL (A; 2) ` Create an array for the y-axis
A{1}:=30 ` Insert some data
A{2}:=40
ARRAY REAL (B; 2) ` Create an array for the y-axis
B{1}:=50 ` Insert some data
B{2}:=80
⇒ GRAPH (vGraph;vType; X; A; B) ` Draw the graph
GRAPH SETTINGS (vGraph;0;0;0;0;False;False;True;"France";"USA")
` Set the legends for the graph
2. The following example graphs the sales in dollars for sales people in a subtable. The
subtable has three fields: Name, LastYearTot, and ThisYearTot. The graph will show the
sales for each of the sales people for the last two years:
⇒ GRAPH (vGraph;1;[Employees]Sales'Name;[Employees]Sales'LastYearTot;
[Employees]Sales'ThisYearTot)
See Also
GRAPH SETTINGS, GRAPH TABLE.
GRAPH SETTINGS (graph; xmin; xmax; ymin; ymax; xprop; xgrid; ygrid; title{; title2; ...;
titleN})
Description
GRAPH SETTINGS changes the graph settings for graph displayed in a form. The graph
must have already been displayed with the GRAPH command. GRAPH SETTINGS has no
effect on a pie chart.
The xmin, xmax, ymin, and ymax parameters all set the minimum and maximum values for
their respective axes of the graph. If the value of any pair of these parameters is a null
value (0, ?00:00:00?, or !00/00/00!, depending on the data type), the default graph values
will be used.
The xgrid and ygrid parameters display or hide grid lines. A grid for the x-axis will be
displayed only when the plot is a proportional scatter or line graph.
Example
See example for the command GRAPH.
See Also
GRAPH, GRAPH TABLE.
or:
Description
GRAPH TABLE has two forms. The first form displays the Chart Wizard and allows the user
to select the fields to be graphed. The second form specifies the fields to be graphed and
does not display the Chart Wizard.
GRAPH TABLE graphs data from a table’s fields. Only data from the current selection of the
current process is graphed.
Using the first form is equivalent to choosing Graph from the Report menu in the User
environment.
The second form of the command graphs the fields specified for table.
The graphType parameter defines the type of graph that will be drawn. It must be a
number from 1 to 8. See the graph types listed in the example for the command Graph.
The x field defines the labels that will be used to label the x-axis (the bottom of the graph).
The field type can be Alpha, Integer, Long integer, Real or Date.
The y field is the data to graph. The field type must be Integer, Long integer or Real. Up to
eight y fields can be graphed, each set off by a semicolon.
In either form, GRAPH TABLE opens a Chart window for working with the newly created
graph. For more information about using the Chart window, see the 4th Dimension User
Reference manual.
Note: You can also use the Quick Report editor to generate graphs from field data, by
using the Print Destination menu.
2. The following example illustrates the use of the second form of GRAPH TABLE. It first
queries and orders records from the [People] table. It then graphs the salaries of the
people:
QUERY([People];[People]Title="Manager")
ORDER BY([People];[People]Salary;>)
⇒ GRAPH TABLE([People];1;[People]Last Name;[People]Salary)
See Also
Graph.
Hierarchical Lists
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Load list creates a new hierarchical list whose contents are copied from the
list and whose name you pass in listName. It then returns the list reference number to the
newly created list.
If the list specified by listName does not exist, the list is not created and Load list returns
zero (0).
Note that the new list is a copy of the list defined in the Design environment.
Consequently, any modifications made to the new list will not affect the list defined in
the Design environment. Conversely, any subsequent modifications made to the list
defined in the Design environment will not affect the list that you just created.
If you modify the newly created list and want to permanently save the changes, call SAVE
LIST.
Remember to call CLEAR LIST in order to dispose of the newly created list when you have
finished with it. Otherwise, it will stay in memory until the end of the working session or
until the process in which it was created ends or is aborted.
Tip: If you associate a list to a form object (hierarchical list, tab control, or hierarchical
pop-up menu) using the Choice List property within the Form Editor Object Properties
window, you do not need to call Load list or CLEAR LIST from the method of the object.
4th Dimension loads and clears the list automatically for you.
See Also
CLEAR LIST, SAVE LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SAVE LIST saves the list whose reference number you pass in list, within the
Design environment List Editor, under the name you pass in listName.
If there is already a list with this name, its contents are replaced.
See Also
Load list.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
New list creates a new, empty hierarchical list in memory and returns its unique list
reference number.
WARNING: Hierarchical lists are held in memory. When you are finished with a
hierarchical list, it is important to dispose of it and free the memory, using the command
CLEAR LIST.
After you have created a hierarchical list using New list, you can:
• Add items to that list, using the command APPEND TO LIST or INSERT LIST ITEM.
• Delete items from that list, using the command DELETE LIST ITEM.
Example
See example for the command APPEND TO LIST.
See Also
APPEND TO LIST, BLOB to list, CLEAR LIST, Copy list, DELETE LIST ITEM, INSERT LIST ITEM,
Load list.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Copy list duplicates the list whose reference number you pass in list, and
returns the list reference number of the new list.
After you have finished with the new list, call CLEAR LIST to delete it.
See Also
CLEAR LIST, Load list, New list.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CLEAR LIST disposes of the hierarchical list whose list reference number you
pass in list.
Usually you will pass the optional * parameter, so all the sublists, if any, attached to items
or subitems of the list will be disposed of too.
You do not need to clear a list attached to a form object via the Object Properties window.
4D loads and clears the list for you. On the other hand, each time you load, copy, extract
from a BLOB, or create a list programmatically, call CLEAR LIST when you are through
with the list.
To clear a sublist attached to an item (of any level) of another list currently displayed in a
form, proceed as follows:
1. Call GET LIST ITEM on the parent item to get the list reference of the sublist.
2. Call SET LIST ITEM on the parent item to detach the sublist from the list item before
clearing it.
3. Call CLEAR LIST to clear the sublist whose reference number you obtained with GET LIST
ITEM.
4. Call REDRAW LIST for the list displayed in the form, to recalculate its items and sublists.
See Also
BLOB to list, Load list, New list.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count list items returns the number of items currently “visible” in the list
whose reference number you pass in list.
Count list items does not return the total number of items in the list. It returns the
number of items that are visible, depending on the current expanded/collapsed state of
the list and its sublists.
Examples
Here a list named hList shown in the User environment:
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is a list returns TRUE if the value you pass in list is a valid reference to a
hierarchical list. Otherwise, it returns FALSE.
Examples
1. See example for the command CLEAR LIST.
2. See examples for the command DRAG AND DROP PROPERTIES.
See Also
DRAG AND DROP PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command REDRAW LIST recalculates the positions of all the items and sublists (if any)
of the list whose reference number you pass in list.
You MUST call this command at least once when you modify one or several aspects of a
list or one of its sublists in a form.
Warning: Pass the actual variable instance of the list, not an expression or variable. For
example, if you have a list named hList in a form:
$vlList:=hList
` ...
` Recalculate the list after changes were made
REDRAW LIST ($vlList) ` WRONG
` ...
Description
The command SET LIST PROPERTIES sets the appearance of the hierarchical list whose list
reference you pass in list.
The parameter appearance can be one of the following predefined constants provided by
4th Dimension:
Constant Type Value
ala Macintosh Long Integer 1
ala Windows Long Integer 2
In the Windows appearance, the list has connecting dotted lines between the nodes and
branches. One icon denotes the collapsed nodes, a second one the expanded nodes, a
third one the nodes without child items. Here is a default hierarchical list in Windows
appearance:
Note: If you display a hierarchical list object without calling SET LIST PROPERTIES, the list
appears with the default Windows or Macintosh appearances, depending on the Platform
Interface property choosen for the object in the Design environment's Form Editor.
The parameter icon indicates the icons that will be displayed for each node. The value
passed in icon sets the icon for collapsed nodes, icon+1 sets the icon for expanded nodes,
and icon+2 sets the icon for nodes without child items (if the appearance is set to
Windows).
For example, if you pass 15000, the color icon 'cicn' ID=15000 will be displayed for each
collapsed node, the color icon 'cicn' ID=15001 will be displayed for each expanded node,
and the color icon 'cicn' ID=15002 will be displayed for each node without child items.
It is therefore important to have these 'cicn' color icon resources present in your database
structure file. If a color icon resource is missing, the corresponding nodes are displayed
with no icons. (You can actually take advantage of this to display a list with no icons.)
WARNING: When creating 'cicn' color icon resources, use resource IDs greater than or
equal to 15000. Resource IDs less than 15000 are reserved for 4th Dimension.
The resource IDs of the default Macintosh and Windows nodes are expressed by the
following predefined constants provided by 4th Dimension:
Constant Type Value
Macintosh node Long Integer 860
Windows node Long Integer 138
If you do not pass the parameter icon, the nodes are displayed with the default icons of
the chosen appearance type.
Color icon resources can be of various sizes. For example, you can create 16x16 or 32x32
color icons.
If you do not pass the parameter lineHeight, the line height of a hierarchical list is
determined by the font and font size used for the object. If you use a color icons that is
too tall or too wide, it will be displayed truncated and/or will be overidden by the
connecting dotted lines (if appearance is Windows), as well as by the text of the nodes
above or below it.
Choose color icon size, font, and font size accordingly, otherwise pass in the parameter
lineHeight the minimal line height of the hierarchical list. If the value you pass is greater
than the line height derived from the font and font size used, the line height of the
hierarchical list will be forced to the value you pass.
Note: SET LIST PROPERTIES affects the way nodes are displayed in the hierarchical list. If
you would rather customize the icon of each item in the list, use the command SET LIST
ITEM PROPERTIES.
The optional parameter doubleClick allows you to define that a double-click on a parent list
item will not provoke the sublist to expand or to collapse. By default, a double-click on a
parent list item provokes its child list to expand or to collapse. However, some user
interfaces may need to deactivate this behavior. To do this, the doubleClick parameter
should be set to 1.
Only double-click will be deactivated. Users will still be able to expand or collapse sublists
by clicking on the list node.
If you omit the doubleClick parameter or pass 0, default behavior will be applied.
Within a form, the hierarchical list object hlCities reuses that list with this object method:
Case of
: (Form event=On Load)
hlCities:=Load list("Cities")
⇒ SET LIST PROPERTIES(hlCities;vlAppearance;vlIcon)
: (Form event=On Unload)
CLEAR LIST(hlCities;*)
End case
In addition, the structure file of the database has been edited so it contains the following
'cicn' color icon resources:
The 'cicn' color icon resources shown are then added to the structure file of the database:
See Also
GET LIST ITEM PROPERTIES, GET LIST PROPERTIES, SET LIST ITEM PROPERTIES.
Description
The command GET LIST PROPERTIES returns information about the list whose reference
number you pass in list.
The parameter icon returns the resource IDs of the node icons displayed in the list.
If doubleClick is set to 1, double-clicking on a parent list item does not provoke its child
list to expand or to collapse. If doubleClick is set to 0, this behavior is active (defaut value).
These properties can be set using the command SET LIST PROPERTIES and/or in the Design
environment List Editor, if the list was created there or saved using the command SAVE
LIST.
For a complete description of the appearance, node icons, minimal line height and
double-click management of a list, see the command SET LIST PROPERTIES.
will alternately display the list as shown above and here (in Windows appearance):
See Also
SET LIST PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SORT LIST sorts the list whose reference number is passed in list.
To sort in ascending order, pass >. To sort in descending order, pass <. If you omit the
sorting order parameter, SORT LIST sorts in ascending order by default.
SORT LIST sorts all levels of the list; it first sorts the items of the list, then it sorts the
items in each sublist (if any), and so on, through all the levels of the list. This is why you
will usually apply SORT LIST to a list in a form. Sorting a sublist is of little interest because
the order will be changed by a call to a higher level.
SORT LIST does not change the selected list items or the current expanded/collapsed state
of the list and sublists. However, because the selected item can be moved by the sorting
operation, Selected list item may return a different position before and after the sort.
Example
Given the list named hList, shown here in the User environment (in Macintosh
appearance):
See Also
Selected list item.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command APPEND TO LIST appends a new item to the hierarchical list whose list
reference number you pass in list.
You pass the text of the item in itemText. You can pass a string or text expression of up to
255 characters. If you pass a longer value, it will be truncated.
You pass the unique reference number of the item in itemRef. Although we qualify this
item reference number as unique, you can actually pass the value you want. See the Item
Reference Numbers section below.
If you also want an item to have child items, pass a valid list reference to the child
hierarchical list in sublist. To expand or collapse the child list, pass TRUE or FALSE in
expanded.
The list reference you pass in sublist must refer to an existing list. The existing list may be
empty, a one-level list, or a list with sublists. If you do not want to attach a child list to
the new item, omit the parameter or pass 0. If you pass the sublist parameter and do not
pass the expanded parameter, the sublist is not expanded, by default. Even if they are both
optional, both the sublist and expanded parameters must be passed jointly.
Tips
• To insert a new item in a list, use INSERT LIST ITEM. To change the text of an existing
item or modify its child list as well as it expanded state, use SET LIST ITEM.
• To change the appearance of the new appended item use SET LIST ITEM PROPERTIES.
WARNING: If you append an item to a list currently displayed in a form or to a list that is
attached to an item (through one or several levels) whose list is currently displayed in a
form, you MUST call REDRAW LIST; 4D recalculates the list and displays it, reflecting your
changes. The rule is simple: whatever the level of the list you act on, apply REDRAW LIST
to the main list, which is list referenced by the object in the form.
Basically, you need to deal with item reference numbers when you want programmatical
direct access to any item of the list and not necessarily the one currently selected in the
list.
Example
Here is a partial view of a database structure:
Case of
End case
In this example, there is only one reason to distinguish [Departments] items and
[Employees] items:
1. We store record numbers in the item reference numbers, therefore, we will probably
end up with [Departments] items whose item reference numbers are the same as
[Employees] items.
2. We use the command List parent item to retrieve the parent of the selected item. If we
click on an [Employees] item whose associated record number is #10, if there is also a
[Departments] item #10, the [Departments] item will be found first by List parent item
when it browses the lists to locate the item with the item reference number we pass. The
command will return the parent of the [Departments] item and not the parent of
[Employees] item.
Therefore, we made the item reference numbers unique, not because we wanted unique
numbers, but because we needed to distinguish [Departments] and [Employees] records.
In the User or Custom Menus environments, the list will look like this:
Note: This example is useful for user interface purposes if you deal with a reasonably small
number of records. Remember that lists are held in memory—do not build user interfaces
with hierarchical lists containing thousands of items.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command INSERT LIST ITEM inserts a new item in the list whose reference number
you pass in list.
If you pass * as second parameter, the item is inserted before the current selected item in
the list. In this case, the newly inserted item will also become the selected item.
Otherwise, if you want to insert an item before a specific item, you pass the item
reference number of that item. In this case, the newly inserted item is not automatically
selected. If there is no item with that item reference number, the command does
nothing.
You pass the text and the item reference number of the new item in itemText and itemRef.
Note: Even if they both are optional, the sublist and expanded parameters must be passed
jointly.
Example
The following code inserts an item (with no attached sublist) just before the item
currently selected in the list hList:
vlUniqueRef:=vlUniqueRef+1
⇒ INSERT LIST ITEM(hList;*;"New Item";vlUniqueRef)
REDRAW LIST(hList)
See Also
APPEND TO LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET LIST ITEM PROPERTIES modifies the item whose item reference number
is passed in itemRef within the list whose reference number is passed in list.
If there is no item with the item reference number that is passed, the command does
nothing. You can optionally pass 0 in itemRef to modify the last item added to the list
using APPEND TO LIST.
If you work with item reference numbers, build a list in which items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, refer to the description of thecommand APPEND TO LIST.
Note: To change the text of the item or its sublist, use the command SET LIST ITEM.
Important: In order for an item to be enterable, it must belong to a list that is enterable.
To make a whole list enterable, use the SET ENTERABLE command. To make an individual
list item enterable, use SET LIST ITEM PROPERTIES. Changing the enterable property at the
list level does not affect the enterable properties of the items. However, an item can be
enterable only if its list is enterable.
Note: On Windows, only the styles Plain or a combination of Bold, Italic, and Underline are
available.
To associate an icon to the item, pass one of the following numeric values:
• N, where N is the resource ID of MacOS-based ‘cicn’ resource
• Use PICT resource+N, where N is the the resource ID of a MacOS-based ‘PICT’ resource
• Use PicRef+N, where N is the reference number of a Picture from the Design
environment Picture Library
Pass zero (0), if you do not want any graphic for the item.
Note: Use PICT resource and Use PicRef are predefined constants provided by 4D.
Example
See the example for the command APPEND TO LIST.
See Also
GET LIST ITEM PROPERTIES, SET LIST ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET LIST ITEM PROPERTIES returns the properties of the item whose
reference number is passed in itemRef within the list whose list reference number is passed
in list.
For details about these properties, see the description of the command SET LIST ITEM
PROPERTIES.
If there is no item with the item reference number that is passed, the command leaves
the parameters unchanged.
If you work with item reference numbers, build a list in which items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, refer to the description of the command APPEND TO LIST.
See Also
GET LIST ITEM, SET LIST ITEM, SET LIST ITEM PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command List item position returns the position of the item whose item reference
number is passed in itemRef, within the list whose list reference number is passed in list.
The position is expressed relative to the top item of the main list, using the current
expanded/collapsed state of the list and its sublist.
The result is therefore a number between 1 and the value returned by Count list items.
If the item is not visible because it is located in a collapsed list, List item position expands
the appropriate list to make the item visible.
See Also
Count list items, SELECT LIST ITEM BY REFERENCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command List item parent returns the item reference number of a parent item.
You pass a list reference number in list; you pass the item reference number of an item of
the list in itemRef. In return, if the item reference number refers to an existing item in
the list and if this item is in a sublist (and therefore has a parent item), you obtain the
item reference number of a parent item.
If there is no item with the item reference number you passed or if the item has no
parent, List item parent returns 0 (zero).
If you work with item reference numbers, build a list in which the items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, see the description of the command APPEND TO LIST.
Examples
Given the list named hList shown here in the User environment:
• In the following code, if the item “b - 3” is selected, the variable $vlParentItemRef gets
200, the item reference number of the item “b”:
$vlItemPos:=Selected list item(hList)
GET LIST ITEM(hList;$vlItemPos;$vlItemRef;$vsItemText)
⇒ $vlParentItemRef:=List item parent(hList;$vlItemRef) ` $vlParentItemRef gets 200
• If the item “a - 1” is selected, the variable $vlParentItemRef gets 100, the item reference
number of the item “a”.
• If the item “a” or “b” is selected, the variable $vlParentItemRef gets 0, because these
items have no parent item.
See Also
GET LIST ITEM, List item position, SELECT LIST ITEM BY REFERENCE, SET LIST ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE LIST ITEM deletes an item from the list whose list reference number
is passed in list.
If you pass * as second parameter, you delete the current selected item in the list.
Otherwise, you specify the item reference number of the item you want to delete. If there
is no item with the item reference number you passed, the command does nothing.
If you work with item reference numbers, build a list in which the items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, see the description of the command APPEND TO LIST.
No matter which item you delete, you should specify the optional * parameter to let 4D
automatically delete the sublist attached to the item, if any. If you do not specify the *
parameter, it is a good idea to have previously obtained the list reference number of the
(possible) sublist attached to the item, because eventually you will have to delete it, using
the command CLEAR LIST.
Example
The following code deletes the current selected item of the list hList. If the item has an
attached sublist, the sublist (as well as any sub-sublist) is cleared:
See Also
CLEAR LIST, GET LIST ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET LIST ITEM returns information about the item whose position is passed
in itemPos within the list whose reference number is passed in list.
The position must be expressed relatively, using the current expanded/collaped state of
the list and its sublist. You pass a position value between 1 and the value returned by
Count list items. If you pass a value outside this range, GET LIST ITEM returns your
parameters unchanged.
See Also
GET LIST ITEM PROPERTIES, List item parent, List item position, Selected list item, SET LIST
ITEM, SET LIST ITEM PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET LIST ITEM command modifies the item whose item reference number is passed
in itemRef within the list whose reference number is passed in list.
If there is no item with the item reference number you passed, the command does
nothing. You can optionally pass 0 in itemRef to modify the last item added to the list
using APPEND TO LIST.
If you work with item reference numbers, build a list in which the items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, see the description of the command APPEND TO LIST.
You pass the new text for the item in newItemText. To change the item reference
number, pass the new value in newItemRef; otherwise, pass the same value as itemRef.
To attach a list to the item, pass the list reference number in subList. In this case, you also
specify if the newly sublist is expanded by passing TRUE in expanded; otherwise, pass
FALSE.
To detach a sublist already attached to the item, pass 0 (zero) in sublist. In this case, it is
a good idea to have previously obtained the reference number of that list using GET LIST
ITEM, so you can later delete the sublist using CLEAR LIST, if you no longer need it.
If you do not want to change the sublist property of the item, pass -1 in sublist.
Note: Even if they are optional, both the sublist and expanded parameters must be passed
jointly.
See Also
GET LIST ITEM, GET LIST ITEM PROPERTIES, SET LIST ITEM PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Selected list item returns the position of the selected item in the list whose
reference number you pass in list.
You apply this command to a list displayed in a form to detect which item the user has
selected.
If the list has sublists, you apply the command to the main list (the one actually defined
in the form), not one of its sublists. The position is expressed relative to the top item of
the main list, using the current expanded/collapsed state of the list and its sublist.
Examples
Here a list named hList, shown in User environment:
See Also
SELECT LIST ITEM, SELECT LIST ITEM BY REFERENCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SELECT LIST ITEM selects the item whose position is passed in itemPos
within the list whose reference number is passed in list. The parameter itemPos is a
position expressed using the current expanded/collapsed state of the list and its sublists.
You pass a position value between 1 and the value returned by Count list items. If you pass
a value outside this range, the first item is selected by default.
Examples
Given the list named hList, shown here in the User environment:
See Also
SELECT LIST ITEM BY REFERENCE, Selected list item.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SELECT LIST ITEM BY REFERENCE selects the item whose item reference
number is passed in itemRef within the list whose reference number is passed in list.
If there is no item with the item reference number you passed, the command does
nothing.
If the item is not currently visible (i.e., it is located in a collapsed sublist), the command
expands the required sublist(s) so that the new selected item becomes visible.
If you work with item reference numbers, builds a list in which the items have unique
reference numbers, otherwise you will not be able to distinguish the items. For more
information, see the description of the command APPEND TO LIST.
Example
hList is a list whose items have unique reference numbers. The following object method
for a button selects the parent item (if any) of the current selected item:
` Get position of selected item
$vlItemPos:=Selected list item(hList)
` Get item ref. num. of selected item
GET LIST ITEM(hList;$vlItemPos;$vlItemRef;$vsItemText)
` Get item ref. num. of parent item (if any)
$vlParentItemRef:=List item parent(hList;$vlItemRef)
If ($vlParentItemRef>0)
` Select the parent item
⇒ SELECT LIST ITEM BY REFERENCE(hList;List item parent(hList;$vlItemRef))
` Do NOT forget to call REDRAW LIST otherwise the list won't be updated
REDRAW LIST(hList)
End if
See Also
SELECT LIST ITEM, Selected list item.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command IMPORT TEXT reads data from document, a Windows or Macintosh text
document, into the table table by creating new records for that table.
The import operation is performed through the current input form. The import operation
reads fields and variables based on the layering of objects in the input form. For this
reason, you should be very careful about the front-to-back order of text objects (fields and
variables) in the form. The first object into which data will be imported should be in the
back of the form, and so on. If the number of fields or variables in the form does not
match the number of fields being imported, the extra ones are ignored. An input form
used for importing cannot contain any buttons. Subform objects are ignored.
Note: One way to ensure that the data is imported into the correct objects is to select the
object into which the first field should be imported and move it to the front. Continue to
move fields and variables to the front in order, making sure that you have one field or
variable for each field being imported.
An On Validate event is sent to the form method for each record that is imported. If you
use variables in the import form, use this event to copy data from variables to fields, .
The document parameter can include a path that contains volume and folder names. If
you pass an empty string, the standard Open File dialog box is displayed. If the user
cancels this dialog, the import operation is canceled, and the OK system variable is set to
0.
A progress thermometer is displayed during import. The user can cancel the operation by
clicking a button labeled Stop. Records that have already been imported will not be
removed if the user presses the Stop button. If the import is successfully completed, the
OK system variable is set to 1. If an error occurs or the operation was interrupted, the OK
variable is set to 0. The thermometer can be hidden with the MESSAGES OFF command.
Using IMPORT TEXT, the default field delimiter is the tab character (ASCII 9). The default
record delimiter is the carriage return character (ASCII 13). You can change these defaults
by assigning values to the two delimiter system variables: FldDelimit and RecDelimit. The
user can change the
defaults in the User environment’s Import Data dialog box. Text fields may contain
carriage returns, therefore, be careful when using a carriage return as a delimiter if you are
importing text fields.
Example
The following example imports data from a text document. The method first sets the
input form so that the data will be imported through the correct form, changes the 4D
delimiter variables, then performs the import:
INPUT FORM([People]; "Import")
FldDelimit:=27 ` Set field delimiter to Escape character
RecDelimit:=10 ` Set record delimiter to Line Feed character
⇒ IMPORT TEXT([People];"NewPeople") ` Import from “NewPeople” document
See Also
EXPORT TEXT, IMPORT DIF, IMPORT SYLK, USE ASCII MAP.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The EXPORT TEXT command writes data from the records of the current selection of table
in the current process. The data is written to document, a Windows or Macintosh text
document on the disk.
The export operation is performed through the current output form. The export
operation writes fields and variables based on the entry order of the output form. For this
reason, use an output form that contains only the fields or enterable objects that you
wish to export. Do not place buttons or other extraneous objects on the export form.
Subform objects are ignored.
An On Load event is sent to the form method for each record that is exported. Use this
event to set the variables you may use in the export form.
The document parameter can name a new or existing document. If document is given the
same name as an existing document, the existing document is overwritten. The document
can include a path that contains volume and folder names. If you pass an empty string,
the standard Save File dialog box is displayed. If the user cancels this dialog, the export
operation is canceled, and the OK system variable is set to 0.
A progress thermometer is displayed during export. The user can cancel the operation by
clicking a Stop button. If the export is successfully completed, the OK system variable is
set to 1. If the operation is canceled or an error occurs, the OK system variable is set to 0.
The thermometer can be hidden with the MESSAGES OFF command.
The export operation is made using the default ASCII map for the platform on which it is
executed, unless you change the ASCII map (using the command USE ASCII MAP) prior to
the export. An ASCII map can be used to convert the data for use on other platforms that
have a different ASCII table.
Example
This example exports data to a text document. The method first sets the output form so
that the data will be exported through the correct form, changes the 4D delimiter
variables, then performs the export:
OUTPUT FORM([People];"Export")
FldDelimit:=27 ` Set field delimiter to Escape character
RecDelimit:=10 ` Set record delimiter to Line Feed character
⇒ EXPORT TEXT([People];"NewPeople") ` Export to the "NewPeople" document
See Also
EXPORT DIF, EXPORT SYLK, IMPORT TEXT, USE ASCII MAP.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command IMPORT SYLK reads data from document, a Windows or Macintosh SYLK
document, into the table table by creating new records for that table.
The import operation is performed through the current input form. The import operation
reads fields and variables based on the layering of objects in the input form. For this
reason, you should be very careful about the front-to-back order of text objects (fields and
variables) in the form. The first object into which data will be imported should be in the
back of the form, and so on. If the number of fields or variables in the form does not
match the number of fields being imported, the extra ones are ignored. An input form
used for importing cannot contain any buttons. Subform objects are ignored.
Note: One way to ensure that the data is imported into the correct objects is to select the
object into which the first field should be imported and move it to the front. Continue to
move the fields and variables to the front, in order, making sure that you have one field
or variable for each field being imported.
An On Validate event is sent to the form method for each record that is imported. If you
use variables in the import form, use this event to copy data from variables to fields, .
The document parameter can include a path that contains volume and folder names. If
you pass an empty string, the standard Open File dialog box is displayed. If the user
cancels this dialog, the import operation is canceled, and the OK system variable is set to
0.
A progress thermometer is displayed during the import. The user can cancel the operation
by clicking a Stop button. Records that have already been imported will not be removed if
the user presses the Stop button. If the import is successfully completed, the OK system
variable is set to 1. If an error occurs or the operation was interrupted, the OK variable is
set to 0. The thermometer can be hidden with the MESSAGES OFF command.
Example
The following example imports data from a SYLK document. The method first sets the
input form so the data will be imported through the correct form, then performs the
import:
INPUT FORM([People]; "Import")
⇒ IMPORT SYLK([People];"NewPeople") ` Import from “NewPeople” document
See Also
EXPORT SYLK, IMPORT DIF, IMPORT TEXT, USE ASCII MAP.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command EXPORT SYLK writes data from the records of the current selection of table
in the current process. The data is written to document, a Windows or Macintosh Sylk
document on the disk.
The export operation is performed through the current output form. The export
operation writes fields and variables based on the entry order of the output form. For this
reason, you should use an output form that contains only the fields or enterable objects
that you wish to export. Do not place buttons or other extraneous objects on the export
form. Subform objects are ignored.
An On Load event is sent to the form method for each record that is exported. Use this
event to set the variables you may use in the export form.
The document parameter can name a new or existing document. If document is given the
same name as an existing document, the existing document is overwritten. The document
can include a path that contains volume and folder names. If you pass an empty string,
the standard Save File dialog box is displayed. If the user cancels this dialog, the export
operation is canceled, and the OK system variable is set to 0.
A progress thermometer is displayed during export. The user can cancel the operation by
clicking a Stop button. If the export is successfully completed, the OK system variable is
set to 1. If the operation is canceled or an error occurs, the OK system variable is set to 0.
The thermometer can be hidden with the MESSAGES OFF command.
The export operation is made using the default ASCII map for the platform on which it is
executed, unless you change the ASCII map (using the command USE ASCII MAP) prior to
the export. An ASCII map can be used to convert the data for use on platforms that have
a different ASCII table.
See Also
EXPORT DIF, EXPORT TEXT, IMPORT SYLK, USE ASCII MAP.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command IMPORT DIF reads data from document, a Windows or Macintosh DIF
document, into the table table by creating new records for that table.
The import operation is performed through the current input form. The import operation
reads fields and variables based on the layering of objects in the input form. For this
reason, you should be very careful about the front-to-back order of text objects (fields and
variables) in the form. The first object into which data will be imported should be in the
back of the form, and so on. If the number of fields or variables in the form does not
match the number of fields being imported, the extra ones are ignored. An input form
used for importing cannot contain any buttons. Subform objects are ignored.
Note: One way to ensure that the data is imported into the correct objects is to select the
object into which the first field should be imported and move it to the front. Continue to
move the fields and variables to the front, in order, making sure that you have one field
or variable for each field being imported.
An On Validate event is sent to the form method for each record that is imported. Use this
event to copy data from variables to fields, if you use variables in the import form.
The document parameter can include a path that contains volume and folder names. If
you pass an empty string, the standard Open File dialog box is displayed. If the user
cancels this dialog, the import operation is canceled, and the OK system variable is set to
0.
A progress thermometer is displayed during import. The user can cancel the operation by
clicking a Stop button. Records that have already been imported will not be removed if
the user presses the Stop button. If the import is successfully completed, the OK system
variable is set to 1. If an error occurs or the operation was interrupted, the OK variable is
set to 0. The thermometer can be hidden with the MESSAGES OFF command.
Example
The following example imports data from a DIF document. The method first sets the
input form so that the data will be imported through the correct form, then performs the
import:
INPUT FORM([People]; "Import")
⇒ IMPORT DIF([People];"NewPeople") ` Import from “NewPeople” document
See Also
EXPORT DIF, IMPORT SYLK, IMPORT TEXT, USE ASCII MAP.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command EXPORT DIF writes data from the records of the current selection of table
in the current process. The data is written to document, a Windows or Macintosh DIF
document on the disk.
The export operation is performed through the current output form. The export
operation writes fields and variables based on the entry order of the output form. For this
reason, you should use an output form that contains only the fields or enterable objects
that you wish to export. Do not place buttons or other extraneous objects on the export
form. Subform objects are ignored.
An On Load event is sent to the form method for each record that is exported. Use this
event to set the variables you may use in the export form.
The document parameter can name a new or existing document. If document is given the
same name as an existing document, the existing document is overwritten. The document
can include a path that contains volume and folder names. If you pass an empty string,
the standard Save File dialog box is displayed. If the user cancels this dialog, the export
operation is canceled, and the OK system variable is set to 0.
A progress thermometer is displayed during export. The user can cancel the operation by
clicking a Stop button. If the export is successfully completed, the OK system variable is
set to 1. If the operation is canceled or an error occurs, the OK system variable is set to 0.
The thermometer can be hidden with the MESSAGES OFF command.
The export operation is made using the default ASCII map for the platform on which it is
executed, unless you change the ASCII map (using the command USE ASCII MAP) prior to
the export. An ASCII map can be used to convert the data for use on platforms that have
a different ASCII table.
See Also
EXPORT SYLK, EXPORT TEXT, IMPORT DIF, USE ASCII MAP.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command IMPORT DATA allows you to import the data located in the fileName file.
4D can import the data in the following formats: Text, Fixed length text, XML, SYLK,
DIF, DBF (dBase), and 4th Dimension.
If you pass an empty string to fileName, IMPORT DATA displays the standard save file
dialog box, allowing the user to define the name, type, and location of the import file.
Once the dialog box has been accepted, the Document system variable contains the access
path and the name of the file. If the user clicks Cancel, the execution of the command is
stopped and the OK system variable is set to 0.
• If you do not pass the optional parameter project, the import dialog box is displayed.
The user can define then import parameters or load an existing import project.
Note: An import project contains all the import parameters such as the tables and fields in
which to import, the delimiters to use, and so on. Those parameters are defined in the
import dialog box. An import project can be saved to disk to be loaded and used later. For
more information about the import dialog box, please refer to the 4DUser Mode manual.
• If you pass a BLOB containing a valid import project in the project parameter, the
import will be directly performed and will not require the user's intervention. The project
must already be predefined in the import dialog box, then saved. To do so, you have two
possible solutions:
- Save the project to disk, then load it, using the DOCUMENT TO BLOB command, in a
BLOB field or a BLOB variable that you pass in project.
- Use the IMPORT DATA command with an empty project parameter and the optional
parameter *, then store the project parameter in a BLOB field (see below). This solution
allows you to save the project with the datafile without having to load it from a BLOB
located on the disk.
See Also
EXPORT DATA, IMPORT DIF, IMPORT SYLK, IMPORT TEXT.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command EXPORT DATA allows you to export data in the fileName file. 4D can export
data in the following formats: Text, Fixed length text, XML, SYLK, DIF, DBF (dBase), and
4th Dimension.
If you pass an empty string in fileName, EXPORT DATA displays the standard save file
dialog box, allowing the user to define the name, type, and location of the export file.
Once the dialog box has been accepted, the Document system variable contains the access
path and the name of the file. If the user clicks Cancel, the execution of the command is
stopped and the OK system variable is equal to 0.
• If you don’t pass the optional parameter project, the export dialog box is displayed. The
user can define the export parameters or load an existing export project.
Note: An export project contains all the export parameters such as the tables and fields to
export, delimiters, etc. You define these parameters in the export dialog box. A project
can be saved to disk and then loaded. For more information about the export dialog box,
please refer to the 4D User Mode manual.
• If you pass a BLOB containing a valid export project to the project parameter, the export
will be directly performed, without the user intervening. The project must already be
predefined in the export dialog box, then saved. To do so, you have two possible
solutions:
- Save the project to disk, then load it by using the DOCUMENT TO BLOB command, in a
field or a variable of type BLOB that you pass to the project parameter.
- Use the EXPORT DATA command with an empty project parameter and the optional
parameter *, then store the project parameter in a field of type BLOB (see below). This
solution allows you to save the project with the datafile without having to load it from a
BLOB on disk.
See Also
EXPORT DIF, EXPORT SYLK, EXPORT TEXT, IMPORT DATA.
Interruptions
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ON EVENT CALL installs the method, whose name you pass in
eventMethod, as the method for catching (trapping) events. This method is called the
event-handling method or event-catching method.
Tip: This command requires advanced programming knowledge. Usually, you do not need
to use ON EVENT CALL for working with events. While using forms, 4th Dimension
handles the events and sends them to the appropriate forms and objects.
Tip: Version 6 introduces new commands, such as GET MOUSE, Shift down, etc., for
getting information about events. These commands can be called from within object
methods to get the information you need about an event involving an object. Using
them spares you the writing of an algorithm based on the ON EVENT CALL scheme.
The scope of this command is the current working session. By default, the method is run
in a separate local process. You can have only one event-handling method at a time. To
stop catching events with a method, call ON EVENT CALL again and pass the empty string
in eventMethod.
The optional processName parameter names the process created by the ON EVENT CALL
command. If processName is prefixed with a dollar sign ($), a local process is started,
which is usually what you want. If you omit the processName parameter, 4D creates, by
default, a local process named $Event Manager.
Platform Modifiers
Windows Shift key, Caps Lock, Alt key, Ctrl key, Right mouse button
Macintosh Shift key, Caps Lock, Option key, Command key, Control key
Notes
- The Windows ALT key is equivalent to the Macintosh Option key
- The Windows Ctrl key is equivalent to the Macintosh Command key
- The Macintosh Control key has no equivalent on Windows. However, a right mouse
button click on Windows, is equivalent to a Control-Click on Macintosh.
The modifier keys do not generate an event; another key or the mouse button must also
be pressed. The Modifiers variable is a 4-byte Long Integer variable that should be seen as
an array of 32 bits. 4D provides predefined constants expressing bit positions or bit masks
for testing the bit corresponding to each modifier key. For example, to detect if the Shift
key was pressed for the event, you can write:
If (Modifiers ?? Shift key bit ) ` If the Shift key was down
or:
If ((Modifiers & Shift key mask)#0)` If the Shift key was down
Important: The system variables MouseDown, KeyCode, Modifiers, MouseX, MouseY, and
MouseProc contain significant values only within an event-hanlding method installed
with ON EVENT CALL.
Example
This example will cancel printing if the user presses Ctrl-period. First, the event-handling
method is installed. Then a message is displayed, announcing that the user can cancel
printing. If the interprocess variable ◊vbWeStop is set to True in the event-handling
method, the user is alerted to the number of records that have already been printed. Then
the event-handling method is deinstalled:
PAGE SETUP
If (OK=1)
◊vbWeStop:=False
⇒ ON EVENT CALL("EVENT HANDLER") ` Installs the event-handling method
ALL RECORDS([People])
MESSAGE("To interrupt printing press Ctrl-Period")
$vlNbRecords:=Records in selection([People])
For ($vlRecord;1;$vlNbRecords)
If (◊vbWeStop)
ALERT("Printing cancelled at record "+String($vlRecord)+
" of "+String($vlNbRecords))
$vlRecord:=$vlNbRecords+1
Else
PRINT FORM([People];"Special Report")
End if
End for
PAGE BREAK
⇒ ON EVENT CALL("") ` Deinstalls the event-handling method
End if
Note that this example uses ON EVENT CALL, because it performs a special printing report
using the commands PAGE SETUP, PRINT FORM and PAGE BREAK with a For loop.
If you print a report using PRINT SELECTION, you do NOT need to handle events that let
the user interrupt the printing; PRINT SELECTION does that for you.
See Also
FILTER EVENT, GET MOUSE, Shift down.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Method called on event returns the name of the method installed by the
ON EVENT CALL command.
See Also
ON EVENT CALL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
FILTER EVENT
Description
You call the FILTER EVENT command from within an event-handling project method
installed using the ON EVENT CALL command.
If an event-handling method calls FILTER EVENT, the current event is not passed to 4D.
This command allows you to remove the current event (i.e., click, keystroke) from the
event queue, so 4D will not perform any additional treatment to the one you made in the
event-handling project method.
WARNING: Avoid creating an event-handling method that only calls the FILTER EVENT
command, because all the events are going to be ignored by 4D. In case you have an
event-handling method with only the FILTER EVENT command, type
Ctrl+Shift+Backspace (on Windows) or Command-Option-Shift-Control-Backspace (on
Macintosh). This converts the On Event Call process into a normal process that does not
get any events at all.
Special case: The FILTER EVENT command can also be used within a standard output form
method when the form is displayed using the DISPLAY SELECTION or MODIFY SELECTION
commands. In this specific case, the FILTER EVENT command allows you to filter double-
clicks on the records (and in this way execute actions other than the opening of records
in page mode).
To do this, place the following lines in the output form method:
If(Form event=On Double Clicked)
FILTER EVENT
... `Process the double-click
End if
Example
See example for the command ON EVENT CALL.
See Also
ON EVENT CALL.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ON ERR CALL installs the project method, whose name you pass in
errorMethod, as the method for catching (trapping) errors. This project method is called
the error-handling method or error-catching method.
The scope of this command is the current process. You can have only one error-handling
method per process at a time, but you can have different error-handling methods for
several processes.
To stop the trapping of errors, call ON ERR CALL again and pass the empty string in
errorMethod.
Once an error-handling project is installed, 4th Dimension calls the method each time an
error occurs.
You can identify errors by reading the Error system variable, which contains the code
number of the error. Error codes are listed in the theme Error codes. For more
information, see the section Syntax Errors or Database Engine Errors. The Error variable
value is significant only within the error-handling method; if you need the error code
within the method that provoked the error, copy the Error variable to your own process
variable.
The error-handling method should manage the error in an appropriate way or present an
error message to the user. Errors can be generated by:
• The 4th Dimension database engine; for example, when saving a record tries to
duplicate a unique index key.
• The 4th Dimension environment; for example, when you do not have enough memory
for allocating an array.
• The operating system on which the database is runs; for example, disk full or I/O errors.
The ABORT command can be used to terminate processing. If you don’t call ABORT in the
error-handling method, 4th Dimension returns to the interrupted method and continues
to execute the method. Use the ABORT command when an error cannot be recovered.
Examples
1. The following project method tries to create a document whose name is received as
parameter. If the document cannot be created, the project metod returns 0 (zero) or the
error code:
` Create doc project method
` Create doc ( String ; Pointer ) -> LongInt
` Create doc ( DocName ; ->DocRef ) -> Error code result
gError:=0
⇒ ON ERR CALL("IO ERROR HANDLER")
$2->:=Create document($1)
⇒ ON ERR CALL("")
$0:=gError
Note the use of the gError process variable to get the error code result within the current
executing method. Once these methods are present in your database, you can write:
` ...
C_TIME(vhDocRef)
$vlErrCode:=Create doc($vsDocumentName;->vhDocRef)
If ($vlErrCode=0)
`...
CLOSE DOCUMENT($vlErrCode)
Else
ALERT ("The document could not be created, I/O error "+String($vlErrCode))
End if
You must initialize the array at the very beginning of the process execution:
` Do NOT forget to initialize the array at the beginning
` of the process method (the project method that runs the process)
ARRAY STRING(63;asErrorMethod;0)
C_STRING(63;$1;$ErrorMethod)
C_LONGINT($vlElem)
If (Count parameters>0)
$ErrorMethod:=$1
Else
$ErrorMethod:=""
End if
If ($ErrorMethod#"")
C_LONGINT(gError)
gError:=0
$vlElem:=1+Size of array(asErrorMethod)
INSERT ELEMENT(asErrorMethod;$vlElem)
asErrorMethod{$vlElem}:=$1
ON ERR CALL($1)
Else
ON ERR CALL("")
$vlElem:=Size of array(asErrorMethod)
If ($vlElem>0)
DELETE ELEMENT(asErrorMethod;$vlElem)
If ($vlElem>1)
ON ERR CALL(asErrorMethod{$vlElem-1})
End if
End if
End if
See Also
ABORT.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Method called on error returns the name of the method installed by the
ON ERR CALL command for the current process.
Example
This command is particularly useful in the context of components because it enables you
to temporarily change and then restore the error-catching methods:
See Also
ON ERR CALL.
version 3
Note: You will rarely call this command.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
ABORT
Description
The command ABORT is to be used from within an error-handling project method
installed using the command ON ERR CALL.
If you do not have an error-handling project method, when an error occurs (for example,
a database engine error) 4D displays its standard error dialog box and then interrupts the
execution of your code. If the code being executed is:
• An object method, form method (or a project method called by a form or object
method), the control returns to the form currently being displayed.
• A method called from a menu, the control returns to the menu bar or to the form
currently being displayed.
• The master method of a process, the process then ends.
• A method called directly or indirectly by an import or export operation, the operation is
stopped. The same is true for sequential queries or order by operations.
• And so on...
If you use an error-handling project method to catch errors, 4D neither displays its
standard error dialog box nor interrupts the execution of your code. Instead, 4D calls your
error-handling project method (that you can see as an exception handler), and resumes
the execution to the next line of code in the method that triggered the error.
There are errors you can treat programmatically; for example, during an import operation,
if you catch a database engine duplicated value error, you can “cover” the error and
pursue the import. However, there are errors that you cannot process and errors that you
should not “cover.” In these cases, you need to stop the execution by calling ABORT from
within the error-handling project method.
Historical Note
Although the ABORT command is intended to be used only from within a error-handling
project method, some members of the 4D community also use it to interrupt execution in
other project methods. The fact that it works is only a side effect. We do not recommend
the use of this command in methods other than error-handling methods.
Language
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count parameters returns the number of parameters passed to a project
method.
WARNING: Count parameters is meaningful only in a project method that has been called
by another method (project method or other). If the project method calling Count
parameters is associated with a menu, Count parameters returns 0.
Examples
1. 4th Dimension project methods accept optional parameters, starting from the right.
For example, you can call the method MyMethod(a;b;c;d) in the following ways:
MyMethod ( a ; b ; c ; d ) ` All parameters are passed
MyMethod ( a ; b ; c ) ` The last parameter is not passed
MyMethod ( a ; b ) ` The last two parameters are not passed
MyMethod ( a ) ` Only the first parameter is passed
MyMethod ` No Parameter is passed at all
Using Count parameters from within MyMethod, you can detect the actual number of
parameters and perform different operations depending on what you have received. The
following example displays a text message and can insert the text into a 4D Write area or
send the text into a document on disk:
` APPEND TEXT Project Method
` APPEND TEXT ( Text { ; Long { ; Time } } )
` APPEND TEXT ( Text { ; 4D Write Area { ; DocRef } } )
C_TEXT ($1)
C_TIME ($2)
C_LONGINT ($3)
MESSAGE ($1)
⇒ If (Count parameters>=3)
SEND PACKET ($3;$1)
Else
After this project method has been added to your application, you can write:
APPEND TEXT (vtSomeText) ` Will only display the text message
APPEND TEXT (vtSomeText;$wrArea) ` Will display the text message and append it to
$wrArea
APPEND TEXT (vtSomeText;0;$vhDocRef) ` Will display the text message and write it to
$vhDocRef
2. 4th Dimension project methods accept a variable number of parameters of the same
type, starting from the right. To declare these parameters, you use a compiler directive to
which you pass ${N} as a variable, where N specifies the first parameter. Using Count
parameters you can address those parameters with a For loop and the parameter
indirection syntax. This example is a function that returns the greatest number received
as parameter:
` Max of Project Method
` Max of ( Real { ; Real2... ; RealN } ) -> Real
` Max of ( Value { ; Value2... ; ValueN } ) -> Greatest value
C_REAL ($0;${1}) ` All parameters will be of type REAL as well as the function result
$0:=${1}
⇒ For ($vlParam;2;Count parameters)
If (${$vlParam}>$0)
$0:=${$vlParam}
End if
End for
After this project method has been added to your application, you can write:
vrResult:=Max of (Records in set("Operation A");Records in set("Operation B"))
or:
vrResult:=Max of (r1;r2;r3;r4;r5;r6)
See Also
Compiler commands, C_BLOB, C_BOOLEAN, C_DATE, C_GRAPH, C_INTEGER, C_LONGINT,
C_PICTURE, C_POINTER, C_REAL, C_STRING, C_TEXT, C_TIME.
Description
The command Type returns a numeric value that denotes the type of the field or variable
you pass as fieldVar.
You can apply Type to fields, interprocess variables, process variables, local variables, and
dereferenced pointers referring to these types of objects.
Version 6 Note: Starting with version 6, you can apply Type to parameters ($1,$2...,
${...}), or to project method or function results ($0).
Examples
1. See example for the APPEND TO CLIPBOARD command.
2. See example for DRAG AND DROP PROPERTIES command.
3. The following project method empties some or all of the fields for the current record of
the table whose a pointer is passed as parameter. It does this without deleting or changing
the current record:
C_POINTER ($1)
C_LONGINT ($2;$vlTypeFlags)
If (Count parameters>=2)
$vlTypeFlags:=$2
Else
$vlTypeFlags:=0xFFFFFFFF
End if
For ($vlField;1;Count fields($1))
$vpField:=Field(Table($1);$vlField)
$vlFieldType:=Type($vpField->)
If ( $vlTypeFlags ?? $vlFieldType )
Case of
: (($vlFieldType=Is Alpha Field)|($vlFieldType=Is Text))
$vpField->:=""
: (($vlFieldType=Is Real)|($vlFieldType=Is Integer)|($vlFieldType=Is LongInt))
$vpField->:=0
: ($vlFieldType=Is Date)
$vpField->:=!00/00/00!
: ($vlFieldType=Is Time)
$vpField->:=?00:00:00?
: ($vlFieldType=Is Boolean)
$vpField->:=False
After this project method is implemented in your database, you can write:
` Empty the whole current record of the table [Things To Do]
EMPTY RECORD (->[Things To Do])
` Empty Text, BLOB and Picture fields for the current record
` of the table [Things To Do]
EMPTY RECORD (->[Things To Do]; 0 ?+ Is Text ?+ Is BLOB ?+ Is Picture )
See Also
Is a variable, Undefined.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Self → Pointer
Description
The command Self returns a pointer to the object whose object method is currently being
executed.
Self is used to reference a variable within its own object method. It returns a valid pointer
only when it is called from within an object method. It cannot be used in a project
method, even when called from an object method. If Self is called out of context, it
returns a Nil pointer (->[]).
Tip: Self is useful when several objects on a form need to perform the same task, yet
operate on themselves.
Example
See the example for the RESOLVE POINTER command.
See Also
RESOLVE POINTER.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command RESOLVE POINTER retrieves the information of the object referenced by
the pointer expression pointer and returns it into the parameters varName, tableNum, and
fieldNum.
Depending on the nature of the referenced object, RESOLVE POINTER returns the
following values:
Referenced object Parameters
varName tableNum fieldNum
None (NIL pointer) "" (empty string) 0 0
Variable Name of the variable -1 0
Array Name of the array -1 0
Array element Name of the array Element number 0
Table "" (empty string) Table number 0
Field "" (empty string) Table number Field number
Note: If the value you pass in pointer is not a pointer expression, a syntax error occurs.
Examples
1. Within a form, you create a group of 100 enterable variables called v1, v2... v100. To
do so, you perform the following steps:
a. Create one enterable variable that you name v.
b. Set the properties of the object.
c. Attach the following method to that object:
DoSomething (Self) ` DoSomething being a project method in your database
d. At this point, you can either duplicate the variable as many times as you need, or use
the Objects on Grid feature in the Form Editor.
2. For debugging purposes, you need to verify that the second parameter ($2) to a
method is a pointer to a table. At the beginning of this method, you write:
` ...
If (<>DebugOn)
⇒ RESOLVE POINTER($2;$vsVarName;$vlTableNum;$vlFieldNum)
If (Not(($vlTableNum>0)&($vlFieldNum=0)&($vsVarName="")))
` WARNING: The pointer is not a reference to a table
TRACE
End
End if
` ...
See Also
DRAG AND DROP PROPERTIES, Field, Get pointer, Is a variable, Nil, Table.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Nil returns True if the pointer you pass in aPointer is Nil (->[]). It returns
False in all other cases (pointer to field, table or variable).
Starting with version 6, instead of using Nil, it will be more convenient to use RESOLVE
POINTER, which tells you about the nature of the referenced object, no matter what the
object is (including Nil pointers).
See Also
Is a variable, RESOLVE POINTER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is a variable returns True if the pointer you pass in aPointer references a
defined variable. It returns False in all other cases (pointer to field or table, Nil pointer,
and so on).
Starting with version 6, instead of using Is a variable, it will be more convenient to use
RESOLVE POINTER, which tells you about the nature of the referenced object, no matter
what the object is (including the case of Nil pointers).
See Also
Nil, RESOLVE POINTER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get pointer returns a pointer to the variable whose name you pass in
varName.
To get a pointer to a field, use Field. To get a pointer to a table, use Table.
Note: You cannot pass to Get pointer an expression such as $tTabNom+"{3}". Only
variable names are allowed.
Example
In a form, you build a 5 x 10 grid of enterable variables named v1, v2... v50. To initialize
all of these variables, you write:
` ...
For ($vlVar;1;50)
⇒ $vpVar:=Get pointer("v"+String($vlVar))
$vpVar->:=""
End for
See Also
Field, Table.
version 3
Note: You will rarely need to use this command.
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
EXECUTE (statement)
Description
EXECUTE executes statement as a line of code. The statement string must be one line. If
statement is an empty string, EXECUTE does nothing.
The rule of thumb is that if the statement can be executed as a one line method, then it
will execute properly.
In a compiled database, the line of code is not compiled. This means that statement will
be executed, but it will not have been checked by 4D Compiler at compilation time.
The statement can include process variables and interprocess variables. The statement
cannot contain control of flow statements, because it must be in one line of code.
Example
See examples for the Command Name command.
See Also
Command name.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Command name returns the literal name of the command whose
command number you pass in command.
However, 4th Dimension also includes a unique feature, the EXECUTE command, which
allows you to build code on the fly and then execute this code, even though the database
is compiled.
The example code, written with EXECUTE statements in English, looks like:
EXECUTE ( "DEFAULT TABLE([MyTable])")
EXECUTE ( "ALL RECORDS([MyTable])")
This same code, reopened with the French version of 4D, will then read:
EXECUTER ( "DEFAULT TABLE([MyTable])")
EXECUTER ( "ALL RECORDS([MyTable])")
Note: To know the number of a command, select its name in the Explorer window. The
command number is then displayed in the right pane of the window.
Examples
1. For all the tables of your database, you have a form called “INPUT FORM” used for
standard data entry in each table. Then, you want to add a generic project method that
will set this form as the current input form for the table whose pointer or name you pass.
You write:
` STANDARD INPUT FORM project method
` STANDARD INPUT FORM ( Pointer {; String })
` STANDARD INPUT FORM ( ->Table {; TableName })
C_POINTER ($1)
C_STRING (31;$2)
If (Count parameters>=2)
⇒ EXECUTE (Command name (55)+"(["+$2+"];"INPUT FORM")")
Else
If (Count parameters>=1)
INPUT FORM ($1->;"INPUT FORM")
End if
End if
After this project method has been added to your database, you write:
STANDARD INPUT FORM (->[Employees])
STANDARD INPUT FORM ("Employees")
Note: Usually, it is better to use pointers when writing generic routines. First, the code
will run compiled if the database is compiled. Second, 4D Insider will retrieve the
references to the object whose pointer you pass. Third, as in the previous example, your
code can cease to work correctly if you rename the table. However, in certain cases, using
EXECUTE will solve the problem.
In the English version of 4D, the drop-down list will read: Sum, Average, Min, and Max.
In the French version, the drop-down list will read: Somme, Moyenne, Min, and Max.
See Also
EXECUTE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Current method name returns the method name where it has been
invoked. This command is useful for debugging generic methods.
According to the calling method type, the returned string can be as follows:
Calling Method Returned string
Database Method MethodName
Trigger Trigger on [TableName]
Project Method MethodName
Form Method [TableName]FormName
Object Method [TableName]FormName.ObjectName
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
TRACE
Description
You use TRACE to trace methods during development of a database.
The TRACE command turns on the 4th Dimension debugger for the current process. The
debugger window is displayed before the next line of code is executed, and continues to
be displayed for each line of code that is executed. You can also turn on the debugger by
pressing the Alt key (Windows) or the Option key (Macintosh) and the mouse button
while code is executing.
4D Server: If you call TRACE from a project method executed within the context of a
Stored Procedure, the debugger window appears on the Server machine.
Tips
1. Do not place TRACE calls when using a form whose On Activate and On Deactivate
events have been enabled. Each time the debugger window appears, these events will be
invoked; you will then loop infinitely between these events and the debugger window. If
you end up in this situation, you can get out of it by switching to the Design
environment.
To do so, click in an event window or the debugger window. Then proceed as follows:
• If the call to TRACE is in a project method or an object method (methods reloaded at
execution), delete it. This will stop the infinite loop.
• If the call to TRACE is in the form method, it will not be reloaded until you exit the
form, which is impossible because you are stuck in a loop. So, either reopen the database
or abort the process in question. If the process cannot be aborted, then you have to
reopen the database.
2. If you call the TRACE command from within a form or an object method executed
during the update of the form at the screen, you will also end up in an infinite repetition
of updates and debugger window apparitions. At this point, press Alt + Shift (Windows) or
Option-Shift (Macintosh). This will disable the update events for the current window and
consequently stop to call TRACE via the form or object methods. Then, you can switch to
the Design environment and remove the call to TRACE.
Example
The following code expects the process variable BUILD_LANG to be equal to “US” or “FR”.
If this is not the case, it calls the project method DEBUG:
` ...
Case of
: (BUILD_LANG="US")
vsBHCmdName:=[Commands]CM US Name
: (BUILD_LANG="FR")
vsBHCmdName:=[Commands]CM FR Name
Else
DEBUG ("Unexpected BUILD_LANG value")
End case
C_TEXT ($1)
See Also
NO TRACE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
NO TRACE
Description
You use NO TRACE to trace methods during development of a database.
NO TRACE turns off the debugger engaged by TRACE, by an error, or by the user. Using
NO TRACE has the same effect as clicking the No Trace button in the debugger.
See Also
TRACE.
Math
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Abs returns the absolute (unsigned, positive) value of number. If number is negative, it is
returned as positive. If number is positive, it is returned unchanged.
Example
The following example returns the absolute value of –10.3, which is 10.3:
⇒ vlVector:=Abs(–10.3)
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Int returns the integer portion of number. Int truncates a negative number away from
zero.
Examples
The following example illustrates how Int works for both positive and negative numbers.
Note that the decimal portion of the number is removed:
See Also
Dec.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Dec returns the decimal (fractional) portion of number. The value returned is always
positive or zero.
Examples
The following example takes a monetary value expressed as a real number, and extracts
the dollar part and the cents part. If vrAmount is 7.31, then vlDollars is set to 7 and vlCents
is set to 31:
vlDollars:=Int (vrAmount) ` Get the dollars
⇒ vlCents:=Dec(vrAmount) * 100 ` Get the fractional part
See Also
Int.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Round returns number rounded to the number of decimal places specified by places.
If the digit following places is 5 though 9, Round rounds toward positive infinity for a
positive number, and toward negative infinity for a negative number. If the digit
following places is 0 through 4, Round rounds toward zero.
Examples
The following example illustrates how Round works with different arguments. Each line
assigns a number to the vlResult variable. The comments describe the results:
See Also
Trunc.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Function result Number ← Number with its decimal part truncated to the
number of decimal places specified by Places
Description
Trunc returns number with its decimal part truncated to the number of decimal places
specified by places. Trunc always truncates toward negative infinity.
Examples
The following example illustrates how Trunc works with different arguments. Each line
assigns a number to the vlResult variable. The comments describe the results:
See Also
Round.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Random → Number
Description
Random returns a random integer value between 0 and 32,767 (inclusive).
The value start is the first number in the range, and the value end is the last.
Example
The following example assigns a random integer between 10 and 30 to the vlResult
variable:
⇒ vlResult:=(Random%21)+10
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Mod returns the remainder of the Integer division of number1 by
number2.
Note: Mod accepts Integer, Long Integer, and Real expressions. However, if number1 or
number2 are real numbers, the numbers are first rounded and then Mod is calculated.
You can also use the % operator to calculate the remainder (see Numeric Operators).
WARNING: The % operator returns valid results with Integer and Long Integer
expressions. To calculate the modulo of real values, you must use the Mod command.
Examples
The following example illustrates how the Mod function works with different arguments.
Each line assigns a number to the vlResult variable. The comments describe the results:
See Also
Numeric Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Square root returns the square root of number.
Examples
1. The line:
2. The following method returns the hypotenuse of the right triangle whose two legs are
passed as parameters:
` Hypotenuse method
` Hypotenuse ( real ; real ) -> real
` Hypotenuse ( legA ; legB ) -> Hypotenuse
C_REAL($0;$1;$2)
⇒ $0 := Square root(($1^2)+($2^2))
See Also
Numeric Operators.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Log returns the natural (Napierian) log of number. Log is the inverse function of Exp.
Example
The following line displays 1:
⇒ ALERT(String(Log(Exp(1)))
See Also
Exp.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Exp raises the natural log base (e = 2.71828...) by the power of number. Exp is the inverse
function of Log.
Example
The following example assigns the exponential of 1 to vrE (the log of vrE is 1):
See Also
Log.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Sin returns the sine of number, where number is expressed in radians.
Note: 4D provides the predefined constants Pi, Degree, and Radian. Pi returns the Pi
number (3.14159...), Degree returns one degree expressed in radians (0.01745...), and
Radian returns one radian expressed in degrees (57.29577...).
See Also
Arctan, Cos, Tan.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Cos returns the cosine of number, where number is expressed in radians.
Note: 4D provides the predefined constants Pi, Degree, and Radian. Pi returns the Pi
number (3.14159...), Degree returns one degree expressed in radians (0.01745...), and
Radian returns one radian expressed in degrees (57.29577...).
See Also
Arctan, Sin, Tan.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Tan returns the tangent of number, where number is expressed in radians.
Note: 4D provides the predefined constants Pi, Degree, and Radian. Pi returns the Pi
number (3.14159...), Degree returns one degree expressed in radians (0.01745...), and
Radian returns one radian expressed in degrees (57.29577...).
See Also
Arctan, Cos, Sin.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Arctan returns the angle, expressed in radians, of the tangent number.
Note: 4D provides the predefined constants Pi, Degree, and Radian. Pi returns the Pi
number (3.14159...), Degree returns one degree expressed in radians (0.01745...), and
Radian returns one radian expressed in degrees (57.29577...).
Examples
The following example shows the value of Pi:
See Also
Cos, Sin, Tan.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET REAL COMPARISON LEVEL sets the epsilon value used by 4th Dimension
to compare real values and expressions for equality.
Given two real numbers a and b, if Abs(a-b) is greater than the epsilon, the numbers are
considered not equal; otherwise, the numbers are considered equal.
By default, 4th Dimension, sets the epsilon value to 10 power minus 6 (10^-6). Please
note that the epsilon value should always be positive. Examples:
• 0.00001=0.00002 returns False, because the difference 0.00001 is greater than 10^-6.
• 0.000001=0.000002 returns True, because the difference 0.000001 is not greater than
10^-6.
• 0.000001=0.000003 returns False, because the difference 0.000002 is greater than 10^-6.
Using SET REAL COMPARISON LEVEL, you can increase or decrease the epsilon value as you
require.
Note: If you want to execute a query or an "Order by" on a numeric indexed field whose
values are lower than 10^-6, make sure that the SET REAL COMPARISON LEVEL command is
executed before construction of the index.
WARNING: Typically, you will not need to use this command to change the default
epsilon value.
IMPORTANT: Changing the epsilon only affects real comparison for equality. It has no
effect on other real computations nor on the display of real values.
See Also
Comparison Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Preliminary Note
If you do not deal with cross-platform development, you can skip this section.
On 68K-based Macintosh, the precision number is 19; this means that 1/3 is calculated
with 19 significant digits. On Windows and Power Macintosh, this number is 15; so 1/3 is
displayed with 15 significant digits. If you display the expression 1/3 in the Debugger
window of 4th Dimension, you will get 0.3333333333333333333 on 68K-based
Macintosh and something like 0.3333333333333333148 on Windows or Power
Macintosh. Note that the last three digits are different because the precision on Windows
and Power Macintosh is less than on the 68K-based Macintosh. Yet, if you display the
expression (1/3)*3, the result is 1 on both machines.
If your floating point arithmetic computations deal with the number of square feet in
your backyard, you will say “Fine with me!” because you do not care about the digits after
the decimal point. On the other hand, if you are filling out an IRS form, you may, in
certain circumstances, care about the accuracy of your computer. However, remember
that 19 or 15 digits after the decimal point are quite sufficient even if you manage
billions of dollars of revenue.
Why does the value 1/3 seem different on 68K Macintosh and onWindows or Power
Macintosh?
On 68K-based Macintosh, the operating system stores real numbers on 10 bytes (80 bits),
while on Windows and Power Macintosh, it stores them on 8 bytes (64 bits). This is why
real numbers have up to 19 significant digits on 68K-based Macintosh and up to 15
significant digits on Windows and Power Macintosh.
There is dual behavior of real numbers, so we must make the distinction between:
• How they are calculated and compared
• How they are displayed on the screen or printer
Originally, 4th Dimension handled real numbers using the standard 10-byte data type
provided by the operating system of the 68K-based Macintosh. Consequently, real values
stored in the data file on disk are saved using this format. In order to maintain
compatibility between the 68K, Power Macintosh, and Windows versions of 4th
Dimension, the 4th Dimension data files still hold the real values using the 10-byte data
type. Because floating point arithmetic is performed on Windows or Power Macintosh
using the 8 byte format, 4th Dimension converts the values from 10 bytes to 8 bytes, and
vice versa. Therefore, if you load a record containing real values, which have been saved
on 68K-based Macintosh, onto Windows or Power Macintosh, it is possible to lose some
precision (from 19 to 15 significant digits). Yet, if you load a record containing real
values, which have been saved on Windows or Power Macintosh, on a 68K-based
Macintosh, there will be no loss of precision. Basically, if you use a database on 68K or
Power Macintosh and Windows, count on floating point arithmetic with 15 significant
digits, not 19.
Using Customizer Plus, you can set the number of digits to be skipped when simplifying
the display of real numbers on 68K or Power Macintosh and Windows. The default
settings are: no digits on 68K and five digits on Power Macintosh and Windows.
Description
The command Euro converter allows you to convert any value from and to the different
currencies belonging to the “Euroland” and the Euro currency itself.
To specify a Currency code, 4th Dimension proposes the following predefined constants,
placed in the “Euro Currencies” theme:
Constant Type Value
Austrian Schilling String ATS
Belgian Franc String BEF
Deutschemark String DEM
Euro String EUR
Finnish Markka String FIM
French Franc String FRF
Greek drachma String GRD
Irish Pound String IEP
Italian Lire String ITL
Luxembourg Franc String LUF
Netherlands Guilder String NLG
Portuguese Escudo String PTE
Spanish Peseta String ESP
The conversion rates between the Euro and the currencies of the 11 participating Member
States are fixed:
Currency Value for 1 Euro
Austrian Schilling 13.7603
Belgian Franc 40.3399
Deutschemark 1.95583
Finnish Markka 5.94573
French Franc 6.55957
Greek drachma 340.750
Irish Pound 0.787564
Italian Lire 1936.27
Luxembourg Franc 40.3399
Netherlands Guilder 2.20371
Portuguese Escudo 200.482
Spanish Peseta 166.386
Example
Here are some examples of conversions that can be done with this command:
$value:=10000 `Value expressed in French Francs
`Convert the value into Euros
⇒ $InEuros:=Euro converter($value;French Franc; Euro)
`Convert the value into Italian Lire
⇒ $InLires:=Euro converter ($value;French Franc; Italian Lire)
Menus
Terminology
The documentation of Menus commands uses the terms menu command and menu item
interchangeably when describing a line in a menu.
Menu Bars
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Menu bars are identified by number, rather than by name. The first menu bar is Menu Bar
#1. It is also the default menu bar. To open an application with a menu bar other than
Menu Bar #1, you must use the MENU BAR command in the On Startup database method.
Each menu command can have one project method attached to it. If you do not assign a
method to a menu command, choosing that menu command causes 4th Dimension to
exit the Custom Menus environment and go to the User environment. If the user is
working with the 4th Dimension Custom Menus version or does not have access to the
User environment, this means quitting to the Desktop.
Every menu bar comes equipped with three menus—the File, Edit and Help menus
(Windows) or the Apple, File and Edit menus (Macintosh).
• The File menu has only one menu command—Quit. Quit has no method associated
with it; that is how it signals 4th Dimension to exit the Custom Menus environment.
You can rename the File menu, add menu commands to it or keep it as is. If it is renamed,
it will no longer appear to the left of the Edit menu. It is recommended that you always
keep Quit as the last menu command in the File menu.
• The Edit menu contains the standard editing menu commands. The Edit menu is not
displayed in the Menu editor and cannot be modified.
• On Windows, the Help menu contains About 4th Dimension and any Windows Help
files that may be available for the application. The Help menu is not displayed in the
Menu editor and cannot be modified, except for the About menu command, which can
be modified using the SET ABOUT command.
• On Macintosh, the Apple menu contains About 4th Dimension and any applications
located in the Apple Menu Items system folder. The Apple menu is not displayed in the
Menu editor and cannot be modified, except for the About menu command, which can
be modified using the SET ABOUT command.
Like menu bars, menus are numbered. The Edit and Help or Apple menus are not included
in the count, because they cannot be modified. Instead, File is menu 1. Thereafter, menus
are numbered sequentially from left to right (2, 3, 4, and so on). Menu numbering is
important when you are working, for example, with the Menu selected function. When a
menu is associated with a form, the menu numbering scheme is different. The first
appended menu begins with the number 2049. To refer to an appended menu, add 2048
to the normal menu number.
The menu commands within each menu are numbered sequentially from the top of the
menu to the bottom. The topmost menu command is item 1.
You can associate a menu bar with a form by using the Menu Bar... menu command from
the Form menu in the Form editor. Such a menu bar is called a “form menu bar” in this
document.
The menus on a form menu bar are appended to the current menu bar when the form is
displayed. The menus are appended for input forms in both the User and Custom Menus
environments and for output forms in the Custom Menus environment.
Form menu bars are specified by a menu bar number. If the number of the menu bar
displayed with the current form is the same as the number of the menu bar appended to
the form, the menu bar is not appended.
If you specify a negative number for a form menu bar, 4th Dimension uses the absolute
value of the menu bar. For example, if you specify –3 as the menu bar, Menu Bar #3 is
used. When a form menu bar is specified with a negative number, the menu commands
for all the menus in the menu bar (splash screen and form) will execute the methods that
are attached to them.
If you do not specify a negative number for a form menu bar, choosing a menu
command from that appended menu bar will not execute its method. Instead, an On
Menu Selected event will be sent to the form method, and you can use Menu selected to
test for the selected menu.
4th Dimension provides the following commands for adding, deleting, inserting or
modifying menu items in a menu of the menu bar currently displayed or installed in a
process:
• ENABLE MENU ITEM
• DISABLE MENU ITEM
• SET MENU ITEM
• SET MENU ITEM STYLE
• SET MENU ITEM MARK
• SET MENU ITEM KEY
• APPEND MENU ITEM
• INSERT MENU ITEM
• DELETE MENU ITEM
The scope of each of these commands is the current use of the menu bar. As soon as you
call MENU BAR again, all the menus and menu items will return to their original state as
defined in the Design environment Menu Bar Editor.
As explained, menus are numbered 1 to N from left to right. For example, File is usually
the first menu. On Windows, the Edit and Help menus are excluded from this
numbering. On Macintosh, the Apple and Edit menus are excluded.
Note that the command Count menus does not take these menus into account. For
example, if you have a menu bar composed of the File, Customers and Invoices menus,
Count menus will return 3, ignoring the system menus maintained by 4D.
Menu items are numbered 1 to N from top to bottom, including separator lines.
Menus that are inserted in the menu bar by means of a menu bar associated with a form,
and therefore appended to the current menu bar, are numbered from left to right starting
with the number 2049 (2048 + 1 to N).
The command Menu selected returns menu and menu item numbers using that
convention.
Warning: These commands cannot access the system menus maintained by 4D (Edit and
Help on Windows, Apple and Edit on Macintosh).
Description
MENU BAR replaces the current menu bar with the one specified by menuBar for the
current process only. In the menuBar parameter, you can pass either the number or name
of the new menu bar.
Note: The name of a menu bar may contain up to 31 characters and must be unique.
The optional process parameter changes the menu bar of the specified process to menuBar.
The optional * parameter allows you to save the state of the menu bar. If this parameter is
omitted, MENU BAR reinitializes the menu bar when the command is executed.
For example, suppose that MENU BAR(1) is executed. Next, several menu commands are
disabled using the DISABLE MENU ITEM command.
If MENU BAR(1) is executed a second time, either from the same process or from a
different process, all menu commands will revert to their initial enabled state.
If MENU BAR(1;*) is executed, the menu bar will retain the same state as before, and the
menu commands that were disabled will remain disabled.
Note: If you do not use the optional process parameter, * can be the second parameter. In
other words, MENU BAR(1;2;*) and MENU BAR(1;*) are both valid statements.
When a user enters the Custom Menus environment, the first menu bar is displayed
(Menu Bar #1). You can change this menu bar when opening a database by specifying the
desired menu bar in the On Startup database method or in the startup method for an
individual user.
2. The following example changes the current menu bar to the menu bar named
“FormMenuBar1” and saves the states of the menu commands. Menu commands that
were previously disabled will appear disabled.
3. The following example sets the current menu bar to menu bar #3 while records are
being modified. After the records have been modified, the menu bar is reset to menu bar
#2, with the menu state saved:
⇒ MENU BAR(3)
ALL RECORDS([Customers])
MODIFY SELECTION([Customers])
⇒ MENU BAR(2;*)
See Also
Managing Menus.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command HIDE MENU BAR makes the menu bar invisible.
If the menu bar was already hidden, the command does nothing.
Example
The following method displays a record in full-screen display (Macintosh) until you click
the mouse button:
HIDE TOOL BAR
⇒ HIDE MENU BAR
Open window(-1;-1;1+Screen width;1+Screen height;Alternate dialog box)
INPUT FORM([Paintings];"Full Screen 800")
DISPLAY RECORD([Paintings])
Repeat
GET MOUSE($vlX;$vlY;$vlButton)
Until($vlButton#0)
CLOSE WINDOW
SHOW MENU BAR
SHOW TOOL BAR
Note: On Windows, the window will be limited to the bounds of the application window.
See Also
HIDE TOOL BAR, SHOW MENU BAR, SHOW TOOL BAR.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SHOW MENU BAR makes the menu bar visible.
If the menu bar was already visible, the command does nothing.
Example
See example for the command HIDE MENU BAR.
See Also
HIDE MENU BAR, HIDE TOOL BAR, SHOW TOOL BAR.
Description
The SET ABOUT command changes the About 4th Dimension menu command in the
Help (Windows) or Apple (Macintosh) menu to ItemText.
After the call, when a user selects this menu command, method will be called. Typically,
this method can open a dialog box to give version information about your database.
The 4th Dimension icon and version number, as well as a single-line copyright notice will
be appended across the top of the dialog box.
Examples
1. The following example replaces the About 4th Dimension menu command with the
About Scheduler menu command. The ABOUT method displays a custom About box:
2. The following example resets the About 4th Dimension menu command back to the
original About box:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Menu selected is used only when forms are displayed. It detects which menu command
has been chosen from a menu.
Tip: Whenever possible, use methods associated with menu commands in an associated
menu bar (with a negative menu bar number) instead of using Menu selected. Associated
menu bars are easier to manage, since it is not necessary to test for their selection.
However, if you use the commands APPEND MENU ITEM or INSERT MENU ITEM, you have
to use Menu selected because the menu items added by these commands do not have
associated methods.
Menu selected returns the menu-selected number, a long integer. To find the menu
number, divide Menu selected by 65,536 and convert the result to an integer. To find the
menu command number, calculate the modulo of Menu selected with the modulus
65,536. Use the following formulas to calculate the menu number and menu command
number:
⇒ Menu := Menu selected \ 65536
⇒ menu command := Menu selected % 65536
Starting with version 6, you can also extract these values using the bitwise operators as
follows:
See Also
Managing Menus.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count menus returns the number of menus present in the menu bar.
If you omit the process parameter, Count menus applies to the menu bar for the current
process. Otherwise, Count menus applies to the menu bar for the process whose reference
number is passed in process.
See Also
Count menu items.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count menu items returns the number of menu items present in the menu
whose number is passed in menu.
If you omit the process parameter, Count menu items applies to the menu bar for the
current process. Otherwise, Count menu items applies to the menu bar for the process
whose reference number is passed in process.
See Also
Count menus.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get menu title returns the title of the menu whose number is passed in
menu.
If you omit the process parameter, Get menu title applies to the menu bar for the current
process. Otherwise, Get menu title applies to the menu bar for the process whose reference
number is passed in process.
See Also
Count menus.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get menu item returns the text of the menu item whose menu and item
numbers are passed in menu and menuItem.
If you omit the process parameter, Get menu item applies to the menu bar for the current
process. Otherwise, Get menu item applies to the menu bar for the process whose reference
number is passed in process.
See Also
Get menu item key, SET MENU ITEM.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET MENU ITEM changes the text of the menu item whose menu and item
numbers are passed in menu and menuItem, to the text passed in itemText.
If you omit the process parameter, SET MENU ITEM applies to the menu bar for the
current process. Otherwise, SET MENU ITEM applies to the menu bar for the process whose
reference number is passed in process.
See Also
Get menu item, SET MENU ITEM KEY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get menu item style returns the font style of the menu item whose menu
and item numbers are passed in menu and menuItem.
If you omit the process parameter, Get menu item style applies to the menu bar for the
current process. Otherwise, Get menu item style applies to the menu bar for the process
whose reference number is passed in process.
Get menu item style returns a combination (one or a sum) of the following predefined
constants:
Constant Type Value
Plain Long Integer 0
Bold Long Integer 1
Italic Long Integer 2
Underline Long Integer 4
Outline Long Integer 8
Shadow Long Integer 16
Condensed Long Integer 32
Extended Long Integer 64
Note: On Windows, only the styles Plain or a combination of Bold, Italic, and Underline are
available.
Example
To test if a menu item is displayed in bold, you write:
See Also
SET MENU ITEM STYLE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET MENU ITEM STYLE changes the font style of the menu item whose
menu and item numbers are passed in menu and menuItem according to the font style
passed in itemStyle.
If you omit the process parameter, SET MENU ITEM STYLE applies to the menu bar for the
current process. Otherwise, SET MENU ITEM STYLE applies to the menu bar for the process
whose reference number is passed in process.
You specify the font style of the item in the itemStyle parameter. You pass a combination
(one or a sum) of the following predefined constants:
Constant Type Value
Plain Long Integer 0
Bold Long Integer 1
Italic Long Integer 2
Underline Long Integer 4
Outline Long Integer 8
Shadow Long Integer 16
Condensed Long Integer 32
Extended Long Integer 64
Note: On Windows, only the styles Plain or a combination of Bold, Italic, and Underline are
available.
See Also
Get menu item style.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get menu item mark returns the check mark of the menu item whose
menu and item numbers are passed in menu and menuItem.
If you omit the process parameter, Get menu item mark applies to the menu bar for the
current process. Otherwise, Get menu item mark applies to the menu bar for the process
whose reference number is passed in process.
If the menu item has no mark, Get menu item mark returns an empty string.
Note: See discussion of check marks on Macintosh and Windows in the description of the
command SET MENU ITEM MARK.
Example
The following example toggles the check mark of a menu item:
See Also
SET MENU ITEM MARK.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET MENU ITEM MARK changes the check mark of the menu item whose
menu and item numbers are passed in menu and menuItem to the first character of the
string passed in mark.
If you omit the process parameter, SET MENU ITEM MARK applies to the menu bar for the
current process. Otherwise, SET MENU ITEM MARK applies to the menu bar for the process
whose reference number is passed in process.
If you pass an empty string, any mark is removed from the menu item. Otherwise:
• On Macintosh, the first character of the string becomes the mark of the menu item.
Usually, you will pass Char (18), which is the check mark character for Macintosh menus.
• On Windows, the menu item is assigned the standard check mark.
Example
See example for the command Get item mark.
See Also
Get menu item mark.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get menu item key returns the ASCII code of the Ctrl (Windows) or
Command (Macintosh) shortcut for the menu item whose menu and item numbers are
passed in menu and menuItem.
If you omit the process parameter, Get menu item key applies to the menu bar for the
current process. Otherwise, Get menu item key applies to the menu bar for the process
whose reference number is passed in process.
If the menu item has no shortcut, Get menu item key returns 0 (zero).
See Also
SET MENU ITEM KEY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET MENU ITEM KEY changes the Ctrl (Windows) or Command
(Macintosh) shortcut for the the menu item whose menu and item numbers are passed in
menu and menuItem, to the character whose ASCII code is passed in itemKey.
If you omit the process parameter, SET MENU ITEM KEY applies to the menu bar for the
current process. Otherwise, SET MENU ITEM KEY applies to the menu bar for the process
whose reference number is passed in process.
If you pass 0 (zero) in itemKey, any shortcut is removed from the menu item.
Note: For consistency in the user interface, use uppercase characters, digits or symbols
that are available on the keyboard, without using any modifier key other than the Ctrl
(Windows) or Command (Macintosh) key.
See Also
Get menu item key.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DISABLE MENU ITEM disables the menu item whose menu and item
numbers are passed in menu and menuItem.
If you omit the process parameter, DISABLE MENU ITEM applies to the menu bar for the
current process. Otherwise, DISABLE MENU ITEM applies to the menu bar for the process
whose reference number is passed in process.
See Also
ENABLE MENU ITEM.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ENABLE MENU ITEM enables the menu item whose menu and item
numbers are passed in menu and menuItem.
If you omit the process parameter, ENABLE MENU ITEM applies to the menu bar for the
current process. Otherwise, ENABLE MENU ITEM applies to the menu bar for the process
whose reference number is passed in process.
See Also
DISABLE MENU ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command APPEND MENU ITEM appends new menu items to the menu whose
number is passed in menu.
If you omit the process parameter, APPEND MENU ITEM applies to the menu bar for the
current process. Otherwise, APPEND MENU ITEM applies to the menu bar for the process
whose reference number is passed in process.
APPEND MENU ITEM allows you to append one or several menu items in one call.
You define the items to be appended with the parameter itemText as follows:
• Separate each item from the next one with a semi-colon (;). For example,
"ItemText1;ItemText2;ItemText3".
• To disable an item: Place an opening parenthesis (() in the item text.
• To specify a separation line: Pass "(-" as item text.
• To specify a font style for a line: In the item text, place a less than sign (<) followed by
one of these characters:
<B Bold
<I Italic
<U Underline
<O Outline (Macintosh only)
<S Shadow (Macintosh only)
• To add a check mark to an item: In the item text, place an exclamation mark (!)
followed by the character you want as a check mark. On Macintosh, the character is
displayed; on Windows, a check mark is displayed no matter what character you passed.
• To add an icon to an item: In the item text, place a circumflex accent (^) followed by a
character whose ASCII code plus 208 is the resource ID of a MacOS-based icon resource.
• To add a shortcut to an item: In the item text, place a slash (/) followed by the shortcut
character for the item.
Note: Use menus that have a reasonable number of items. If you want to display more
than 50 items, think about a using scrollable area in a form instead of a menu.
Important: The new items do not have any associated method. Therefore, they must be
managed from within a form method using the Menu selected command.
Example
This example appends the names of the available fonts to the Font menu, which in this
example is the sixth menu of the current menu bar:
` In the On Startup database method
` The font list is loaded and menu item text is built
FONT LIST(◊asAvailableFont)
◊atFontMenuItems:=""
For ($vlFont;1;Size of array(◊asAvailableFont))
◊atFontMenuItems:=◊atFontMenuItems+";"+◊asAvailableFont{$vlFont}
End for
See Also
DELETE MENU ITEM, INSERT MENU ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command INSERT MENU ITEM inserts new menu items into the menu whose number
is passed in menu after the existing menu item whose number is passed in afterItem.
If you omit the process parameter, INSERT MENU ITEM applies to the menu bar for the
current process. Otherwise, INSERT MENU ITEM applies to the menu bar for the process
whose reference number is passed in process.
INSERT MENU ITEM allows to you insert one or several menu items in one call.
INSERT MENU ITEM works like APPEND MENU ITEM, except for the following differences:
• INSERT MENU ITEM enables you to insert items anywhere in the menu, while
APPEND MENU ITEM always adds them at the end of the menu.
• With INSERT MENU ITEM, the item definition passed in itemText is limited to 255
characters, while with APPEND MENU ITEM, itemText is limited to 32,000 characters.
See the description of the command APPEND MENU ITEM for details about the the item
definition passed in itemText.
Important: The new items do not have any associated method. Therefore, they must be
managed from within a form method using the Menu selected command.
See Also
APPEND MENU ITEM.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE MENU ITEM deletes the menu item whose menu and item numbers
are passed in menu and menuItem.
If you omit the process parameter, DELETE MENU ITEM applies to the menu bar for the
current process. Otherwise, DELETE MENU ITEM applies to the menu bar for the process
whose reference number is passed in process.
Note: For consistency in the user interface, do not keep a menu with no items.
See Also
APPEND MENU ITEM, INSERT MENU ITEM.
Messages
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
MESSAGES OFF
Description
The commands MESSAGES ON and MESSAGES OFF turn on and off the progress meters
displayed by 4th Dimension while executing time-consuming operations. By default,
messages are on.
The following table shows User environment operations that display the progress meter:
Apply Formula Quick Report Order by
Export Data Import Data Graph
Query by Form Query by Formula Query Editor
The following table lists the commands that display the progress meter:
APPLY TO SELECTION IMPORT SYLK QUERY
DISTINCT VALUES IMPORT TEXT QUERY BY FORMULA
EXPORT DIF RELATE MANY SELECTION QUERY BY EXAMPLE
EXPORT SYLK RELATE ONE SELECTION QUERY SELECTION
EXPORT TEXT REDUCE SELECTION QUERY SELECTION BY FORMULA
GRAPH TABLE REPORT ORDER BY FORMULA
IMPORT DIF SCAN INDEX ORDER BY
Example
The following example turns off the progress meter before doing a sort, and then turns it
back on after completing the sort:
⇒ MESSAGES OFF
ORDER BY ([Addresses];[Addresses]ZIP;>;[Addresses]Name2;>)
MESSAGES ON
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
MESSAGES ON
Description
See the description of the MESSAGES OFF command.
Description
The ALERT command displays an alert dialog box composed of a note icon, a message, and
an OK button.
You pass the message to be displayed in the parameter message. This message can be up to
255 characters long. However, if the message does not fit into the message area, it can
appear truncated, depending on its length and the width of the characters.
By default, the title of the OK button is “OK.” To change the title of the OK button, pass
the new custom title into the optional parameter ok button title. If necessary, the OK
button width is resized toward the left, according to the width of the custom title you
pass.
Tip: Do not call the ALERT command from the section of a form or object method that
handles the On Activate or On Deactivate form events; this will cause an endless loop.
Examples
1. This example displays an alert showing information about a company. Note that the
displayed string contains carriage returns, which cause the string to wrap to the next line:
⇒ ALERT("Company: "+[Companies]Name+Char(13)+"People in company: "+
String(Records in selection([People]))+Char(13)+"Number of parts they supply: "+
String (Records in selection([Parts])))
2. The line:
⇒ ALERT("I'm sorry Dave, I can't do that.";"Alas!")
displays the alert dialog box (on MacOS) shown:
3. The line:
⇒ ALERT("You no longer have the access privileges for deleting these records.";"Well,
I swear I did not know that")
displays the alert dialog box (On Macintosh) shown:
See Also
CONFIRM, Request.
Description
The CONFIRM command displays a confirm dialog box composed of a note icon, a
message, an OK button, and a Cancel Button.
You pass the message to be displayed in the message parameter. This message can be up to
255 characters long. If the message does not fit into the message area, it can appear
truncated, depending on its length and the width of the characters.
By default, the title of the OK button is “OK” and that of the Cancel button is “Cancel.”
To change the titles of these buttons, pass the new custom titles into the optional
parameters ok button title and cancel button title. If necessary, the width of the buttons is
resized toward the left, according to the width of the custom titles you pass.
The OK button is the default button. If the user clicks the OK button or presses Enter to
accept the dialog box, the OK system variable is set to 1. If the user clicks the Cancel
button to cancel the dialog box, the OK system variable is set to 0.
Tip: Do not call the CONFIRM command from the section of a form or object method
that handles the On Activate or On Deactivate form events; this will cause an endless loop.
Examples
1. The line:
⇒ CONFIRM("WARNING: You will not be able to revert this operation.")
If (OK=1)
ALL RECORDS([Old Stuff])
DELETE SELECTION([Old Stuff])
Else
ALERT ("Operation canceled.")
End if
2. The line:
⇒ CONFIRM("Do you really want to close this account?";"Yes";"No")
will display the confirm dialog box (on Windows) shown here:
3. You are writing a 4D application for the international market. You wrote a project
method that returns the correct localized text from its English version. You have also
populated an array named <>asLocalizedUIMessages,where you store the most common
words. In doing so, the line:
⇒ CONFIRM(INTL Text ("Do you want to add a new Memo?");
<>asLocalizedUIMessages{kLoc_YES};<>asLocalizedUIMessages{kLoc_NO})
could display the French confirm dialog box (on Windows) shown here:
See Also
ALERT, Request.
Description
The command Request displays a request dialog box composed of a message, a text input
area, an OK button, and a Cancel Button.
You pass the message to be displayed in the message parameter. This message can be up to
255 characters long. If the message does not fit into the message area, it can appear
truncated, depending on its length and the width of the characters.
By default, the title of the OK button is “OK” and that of the Cancel button is “Cancel.”
To change the titles of these buttons, pass the new custom titles into the optional
parameters OKButtonTitle and CancelButtonTitle. If necessary, the width of the buttons is
resized toward the left, according to the width of the custom titles you pass.
The OK button is the default button. If you click the OK button or press Enter to accept
the dialog box, the OK system variable is set to 1. If you click the Cancel button to cancel
the dialog box, the OK system variable is set to 0.
The user can enter text into the text input area. To specify a default value, pass the default
text in the defaultResponse parameter. If the user clicks OK, Request returns the text. If
the user clicks Cancel, Request returns an empty string (""). If the response should be a
numeric or a date value, convert the string returned by Request to the proper type with
the Num or Date functions.
Tip: Do not call the Request command from the section of a form or object method that
handles the On Activate or On Deactivate form event; this will cause an endless loop.
Tip: If you need to get several pieces of information from the user, design a form and
present it with DIALOG, rather than presenting a succession of Request dialog boxes.
2. The line:
⇒ vsPrompt := Request ("Name of the Employee:";"";"Create Record";"Cancel")
If (OK=1)
ADD RECORD ([Employees])
` Note: vsPrompt is then copied into the field [Employees]Last name
` during the On Load event in the form method
End if
will display the request dialog box (on Windows) shown here:
3. The line:
⇒ $vdPrompt := Date (Request ("Enter the new date:";String (Current date)))
will display the request dialog box (on Windows) shown here:
See Also
ALERT, CONFIRM.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
MESSAGE (message)
Description
The MESSAGE command is usually used to inform the user of some activity. It displays
message on the screen in a special message window that opens and closes each time you
call MESSAGE, unless you work with a window you previously opened using Open window
(see the following details). The message is temporary and is erased as soon as a form is
displayed or the method stops executing. If another MESSAGE is executed, the old
message is erased.
If a window is opened with Open window, all subsequent calls to MESSAGE display the
messages in that window. The window behaves like a terminal:
• Successive messages do not erase previous messages when displayed in the window.
Instead, they are concatenated onto existing messages.
• If a message is wider than the window, 4th Dimension automatically performs text
wrap.
• If a message has more lines than the window, 4th Dimension automatically scrolls the
message window.
• To control line breaks, include carriage returns — Char(13) — into your message.
• To display the text at a particular place in the window, call GOTO XY.
• To erase the contents of the window, call ERASE WINDOW .
• The window is only an output window and does not redraw when other windows
overlap it.
You can choose the font and the font size (within limits) at your convenience. However,
if you combine the use of MESSAGE and GOTO XY, it is a good idea to choose a fixed
width font, such as Terminal on Windows or Monaco on Macintosh.
Examples
1. The following example processes a selection of records and calls MESSAGE to inform the
user about the progress of the operation:
For($vlRecord;1;Records in selection([anyTable]))
⇒ MESSAGE ("Processing record #"+String($vlRecord))
` Do Something with the record
NEXT RECORD([anyTable])
End for
See Also
CLOSE WINDOW, ERASE WINDOW, GOTO XY, Open window.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
GOTO XY (x; y)
Description
The GOTO XY command is used in conjunction with the MESSAGE command when you
display messages in a window opened using Open window.
GOTO XY positions the character cursor (an invisible cursor) to set the location of the
next message in the window.
The upper-left corner is position 0,0. The cursor is automatically placed at 0,0 when a
window is opened and after ERASE WINDOW is executed.
After GOTO XY positions the cursor, you can use MESSAGE to display characters in the
window.
Tip: Using a fixed-width (monospaced) font, such as Terminal on Windows and Monaco
on Macintosh, for the message, gives the best display results with GOTO XY and
MESSAGE. See the description of the MESSAGE command for more information.
Examples
1. See example for the command MESSAGE.
See Also
MESSAGE.
Named Selections
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Named selections are created with the COPY NAMED SELECTION, CUT NAMED SELECTION
and CREATE SELECTION FROM ARRAY commands. Named selections are generally used to
work on one or more selections and to save and later restore an ordered selection. There
can be many named selections for each table in a process. To reuse a named selection as
the current selection, call USE NAMED SELECTION. When you are done with a named
selection, use CLEAR NAMED SELECTION.
Note: This syntax can be used on both Windows and Macintosh. In addition, on
Macintosh only, you can use the diamond (Option-Shift-V on US keyboard).
A named selection whose name is not prefixed with the symbols (<>) is process in scope
and is available only within the process in which it was created.
With 4D Client and 4D Server, an interprocess named selection is available only to the
processes of the client that created it. An interprocess named selection is not available to
other client machines.
Warning: Creating a named selection requires access to the selection of the table. Since
selections are kept on the server and a local process does not have access to server data, do
not use named selections within local processes.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
COPY NAMED SELECTION copies the current selection of table to the named selection
name. The default table for the process is used if the optional table parameter is not
specified. The parameter name contains a copy of the selection. The current selection and
the current record of Table for the process are not changed.
A named selection does not actually contain the records, but only an ordered list of
references to records. Each reference to a record takes 4 bytes in memory. This means that
when a selection is copied using the COPY NAMED SELECTION command, the amount of
memory required is 4 bytes multiplied by the number of records in the selection. Since
named selections reside in memory, you should have enough memory for the named
selection as well as the current selection of the table in the process.
Use the CLEAR NAMED SELECTION command to free the memory used by name.
Example
The following example allows you to check if there are other overdue invoices in the
[People] table. The selection is sorted and then saved. We search for all records where
invoices are due. Then we reuse the selection and clear the named selection in memory.
Clearing the named selection in memory is optional, in case the database designer wants
to keep the sorted selection for future use:
ALL RECORDS([People])
`Allow the user to sort the selection
ORDER BY([People])
` Save the sorted selection as a named selection
⇒ COPY NAMED SELECTION([People];"UserSort")
` Search for records where invoices are due
QUERY([People];[People]InvoiceDue=True)
` If records are found
See Also
CLEAR NAMED SELECTION, CUT NAMED SELECTION, USE NAMED SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CUT NAMED SELECTION creates a named selection name and moves the current selection
of table to it. This command differs from COPY NAMED SELECTION in that it does not
copy the current selection, but moves the current selection of table itself.
After the command has been executed, the current selection of table in the current
process becomes empty. Therefore, CUT NAMED SELECTION should not be used while a
record is being modified.
CUT NAMED SELECTION is more memory efficient than COPY NAMED SELECTION. With
COPY NAMED SELECTION, 4 bytes times the number of selected records is duplicated in
memory. With CUT NAMED SELECTION, only the reference to the list is moved.
Example
The following method empties the current selection of a table [Customers]:
⇒ CUT NAMED SELECTION([Customers]; "ToBeCleared")
CLEAR NAMED SELECTION("ToBeCleared")
See Also
CLEAR NAMED SELECTION, COPY NAMED SELECTION, USE NAMED SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
USE NAMED SELECTION uses the named selection name as the current selection for the
table to which it belongs.
When you create a named selection, the current record is “remembered” by the named
selection. USE NAMED SELECTION retrieves the position of this record and makes the
record the new current record; this command loads the current record. If the current
record was modified after name was created, the record should be saved before USE NAMED
SELECTION is executed, in order to avoid losing the modified information.
• If COPY NAMED SELECTION was used to create name, the named selection name is copied
to the current selection of the table to which name belongs. The named selection name
exists in memory until it is cleared. Use the CLEAR NAMED SELECTION command to clear
the named selection and free the memory used by name.
• If CUT NAMED SELECTION was used to create name, the current selection is set to name
and name no longer exists in memory.
Also note that during a transaction, temporary record addresses are used. If a named
selection is created during a transaction, it may contain addresses that will no longer be
valid when the transaction is validated or cancelled, because the records will receive their
final and actual address after the transaction is validated.
See Also
COPY NAMED SELECTION, CUT NAMED SELECTION, USE NAMED SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CLEAR NAMED SELECTION clears name from memory and frees the memory used by name.
CLEAR NAMED SELECTION does not affect tables, selections, or records. Since named
selections use memory, it is good practice to clear named selections when they are no
longer needed.
If name was created using the CUT NAMED SELECTION command and then manipulated
using the USE NAMED SELECTION command, name no longer exists in memory. In this
case, the CLEAR NAMED SELECTION command does not need to be used.
See Also
COPY NAMED SELECTION, CUT NAMED SELECTION, USE NAMED SELECTION.
Description
The command CREATE SELECTION FROM ARRAY creates the named selection selectionName
from:
• either an array of absolute record numbers recordArray from table,
• or an array of booleans. In this case, the values of the array indicate the belonging
(True) or not (False) of each record in table in selectionName.
If you don’t pass selectionName or if you pass an empty string, the command will be
applied to the current selection, which will then be updated.
When you use a Longint array with this command, all the numbers of the array represent
the list of record numbers in selectionName. If a number is incorrect (record not created),
error -10503 is generated.
When you use a Boolean array with this command, the Nth element of the array
indicates if the record number N is (True) or is not (False) in selectionName. The number
of elements in recordArray must be equal to the number of records in table. If the array is
smaller than the number of records, only the records defined by the array can make up
the selection.
Note: With an array of booleans, the command uses elements from numbers 0 to N-1.
Warning: A named selection is created and loaded into memory. Therefore, make sure
that you have enough memory before executing this command.
See Also
CLEAR NAMED SELECTION, COPY NAMED SELECTION, CREATE SET FROM ARRAY, USE
NAMED SELECTION.
Object Properties
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Object Properties commands act on the properties of objects present in forms. They
enable you to change the appearance and behavior of the objects while using the forms
in the User or Custom menus environment.
Important: The scope of these commands is the form currently being used; changes
disappear when you exit the form.
Accessing Objects using their Object Names or their Data Source Names
The Object Properties commands share the same generic syntax described here:
COMMAND NAME({*;} object { ; additional parameters specific to each command )
If you specify the optional * parameter, you indicate an object name (a string) in object.
You can use the @ character within that name if you want to address several objects of
the form in one call. The following table shows examples of object names you can specify
to this command.
If you omit the optional * parameter, you indicate a field or a variable in object. In this
case, you specify a field or variable reference (field or variable objects only) instead of a
string.
Note: This second syntax is compatible with the previous version of 4th Dimension.
See Also
BUTTON TEXT, DISABLE BUTTON, ENABLE BUTTON, FONT, FONT SIZE, FONT STYLE, SET
CHOICE LIST, SET ENTERABLE, SET FILTER, SET FORMAT, SET RGB COLORS, SET VISIBLE.
Description
FONT sets the form objects specified by object to be displayed using the font whose name
or number you pass in font.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
Examples
1. The following example sets the font for a button named bOK:
2. The following example sets the font for all the form objects whose name contains
"info":
See Also
FONT SIZE, FONT STYLE.
Description
FONT SIZE sets the form objects specified by object to be displayed using the font size you
pass in size.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
The size is any integer between 1 and 255. If the exact font size does not exist, characters
are scaled.
The area for the object, as defined in the form, must be large enough to display the data
in the new size. Otherwise, the text may be truncated or not displayed at all.
Examples
1. The following example sets the font size for a variable named vtInfo:
2. The following example sets the font size for all the form objects whose name starts
with "hl":
See Also
FONT, FONT STYLE.
Description
FONT STYLE sets the form objects specified by object to be displayed using the font style
you pass in styles.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
You pass in styles a sum of the constants describing your font style selection. The
following are the predefined constants provided by 4D:
Constant Type Value
Plain Long Integer 0
Bold Long Integer 1
Italic Long Integer 2
Underline Long Integer 4
Outline Long Integer 8
Shadow Long Integer 16
Condensed Long Integer 32
Extended Long Integer 64
Note: On Windows, only the Plain, Bold, Italic and Underline styles are available.
2. This example sets the font style to Plain for all form objects with names starting with
“vt”:
See Also
FONT, FONT SIZE.
Description
The command ENABLE BUTTON enables the form objects specified by object.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
This command (despite what its name suggests) can be applied to the following types of
object:
• Button, Default Button, 3D Button, Invisible Button, Highlight Button
• Radio Button, 3D Radio Button, Radio Picture
• Check Box, 3D Check Box
• Pop-up menu, Drop-down List, Combo Box, Menu/Drop-down list
• Thermometer, Ruler
Note: It is not practical to use this command with an object that is assigned an automatic
action, because 4D changes the state of the control when needed.
Examples
1. This example enables the button bValidate:
⇒ ENABLE BUTTON(bValidate)
2. This example enables all form objects that have names containing “btn”:
⇒ ENABLE BUTTON(*;"@btn@")
See Also
BUTTON TEXT, DISABLE BUTTON.
Description
The command DISABLE BUTTON disables the form objects specified by object.
A disabled button or object does not react to mouse clicks and shortcuts, and is displayed
dimmed or grayed out.
Note: Disabling a button or an object does not prevent you from changing its value
programmatically.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
This command (despite what its name suggests) can be applied to the following types of
object:
• Button, Default Button, 3D Button, Invisible Button, Highlight Button
• Radio Button, 3D Radio Button, Radio Picture
• Check Box, 3D Check Box
• Pop-up menu, Drop-down List, Combo Box, Menu/Drop-down list
• Thermometer, Ruler
Note: It is not practical to use this command with an object that is assigned an automatic
action, because 4D changes the state of the control when needed.
⇒ DISABLE BUTTON(bValidate)
2. This example disables all form objects that have names containing “btn”:
⇒ DISABLE BUTTON(*;"@btn@")
See Also
BUTTON TEXT, ENABLE BUTTON.
Description
The command BUTTON TEXT changes the title of the buttons specified by object to the
value you pass in buttonText.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
BUTTON TEXT affects only buttons that display text: buttons, check boxes, and radio
buttons.
Usually, you will apply this command to one button at a time. The button area must be
large enough to accommodate the text; if it is not, the text is truncated. Do not use
carriage returns in buttonText.
Example
The following example is the object method of a search button located in the footer area
of an output form displayed using MODIFIED SELECTION. The method searches a table;
depending on the search results, it enables or disables a button labeled bDelete and
changes its title:
See Also
DISABLE BUTTON, ENABLE BUTTON.
Description
SET FORMAT sets the display format for the objects specified by object to the format you
pass in displayFormat.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
SET FORMAT can be used for both input forms and output forms (displayed or printed)
and can be applied to fields, enterable/non-enterable variables, and numeric scrollable
areas.
You use a display format suitable to the type of data present in the object:
• To format Boolean fields, pass two values, separated by a semicolon (;).
• To format Date fields or variables, pass Char(n) in displayFormat, where n is one of the
following predefined constants provided by 4D:
Constant Type Value
Short Long Integer 1
Abbreviated Long Integer 2
Long Long Integer 3
MM DD YYYY Long Integer 4
Month Date Year Long Integer 5
Abbr Month Date Long Integer 6
MM DD YYYY Forced Long Integer 7
• To format Picture fields or variables, pass Char(n) in displayFormat, where n is one of the
following predefined constants provided by 4D:
Constant Type Value
Truncated Centered Long Integer 1
Scaled to Fit Long Integer 2
On Background Long Integer 3
Truncated non Centered Long Integer 4
Scaled to fit proportional Long Integer 5
Scaled to fit prop centered Long Integer 6
For more information about alphanumeric and numeric display formats, see the
4th Dimension Design Reference manual.
Note: In displayFormat, to use display formats you may have predefined in the Database
Properties dialog box, prefix the name of the format with a vertical bar (|).
Examples
1. The following line of code formats the [Employee]Date Hired field to Month Date Year.
2. The following example changes the format for a [Company]ZIP Code field according to
the length of the value stored in the field:
If (Length ([Company]ZIP Code) = 9)
⇒ SET FORMAT ([Company]ZIP Code; "#####–####")
Else
⇒ SET FORMAT ([Company]ZIP Code; "#####")
End if
3. The following example sets the format of a Boolean field to display Married and
Unmarried, instead of the default Yes and No:
See Also
SET FILTER.
Description
SET FILTER sets the entry filter for the objects specified by object to the filter you pass in
entryFilter.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
SET FILTER can be used for input and dialog forms and can be applied to fields and
enterable variables that accept an entry filter in Design environment.
Passing an empty string in entryFilter removes the current entry filter for the objects.
Note: This command cannot be used with fields located in a subform’s list form.
Note: In entryFilter, to use entry filters you may have predefined in the Database
Properties dialog box, prefix the name of the filter with a vertical bar (|).
Examples
1. The following example sets the entry filter for a postal code field. If the address is in
the U.S., the filter is set to ZIP codes. Otherwise, it is set to allow any entry:
If ([Companies]Country = "US") ` Set the filter to a ZIP code format
⇒ SET FILTER ([Companies]ZIP Code; "&9#####")
Else ` Set the filter to accept alpha and numeric and uppercase the alpha
⇒ SET FILTER ([Companies]ZIP Code; "~@")
End if
See Also
SET FORMAT.
Description
The command SET CHOICE LIST sets the choice list for the objects specified by object to
the hierarchical list (defined in the Design environment List Editor) whose name you pass
in list.
This command can be applied in an input or dialog form, to fields and enterable variables
whose value can be entered as text. The list is displayed during data entry when the user
selects the text area.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
Note: This command cannot be used with fields located in a subform’s list form.
Example
The following example sets a choice list for a shipping field. If the shipping is overnight,
then the choice list is set to shippers who can ship overnight. Otherwise, it is set to the
standard shippers:
If ([Shipments]Overnight)
⇒ SET CHOICE LIST([Shipments]Shipper; "Fast Shippers")
Else
⇒ SET CHOICE LIST([Shipments]Shipper; "Normal Shippers")
End if
Description
The command SET ENTERABLE makes the form objects specified by object either enterable
or non-enterable.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
specify a field or variable reference (field or variable objects only) instead of a string. For
more information about object names, see the section Object Properties.
When the entryArea is enterable (TRUE), the user can move the cursor into the area and
enter data. When the entryArea is non-enterable (FALSE), the user cannot move the cursor
into the area and cannot enter data. Making an object non-enterable does not prevent
you from changing its value programmatically.
Example
The following example sets a shipping field, depending on the weight of the shipment. If
the shipment is 1 ounce or less, then the shipper is set to US Mail and the field is set to be
non-enterable. Otherwise, the field is set to be enterable.
If ([Shipments]Weight<=1)
[Shipments]Shipper:="US Mail"
⇒ SET ENTERABLE([Shipments]Shipper;False)
Else
SET ENTERABLE([Shipments]Shipper;True)
End if
See Also
DISABLE BUTTON, ENABLE BUTTON, SET VISIBLE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET VISIBLE shows or hides the objects specified by object.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
If you pass visible equal to TRUE, the objects are shown. If you pass visible equal to FALSE,
the objects are hidden.
Example
Here is a typical form in the Design environment:
The objects in the Employer Information group box each have an object name that
contains the expression “employer” (including the group box). When the Currently
Employed check box is checked, the objects must be visible; when the check box is
unchecked, the objects must be invisible.
Therefore, in the User or Custom Menus environments, the form looks like:
or:
See Also
DISABLE BUTTON, ENABLE BUTTON, SET ENTERABLE.
Description
The command SET COLOR sets the foreground and background colors of the form objects
specified by object.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
The color parameter specifies both foreground and background colors. The color is
calculated as:
Color:=–(Foreground+(256 * Background))
where foreground and background are color numbers (from 0 to 255) within the color
palette.
Color is always a negative number. For example, if the foreground color is to be 20 and
the background color is to be 10, then color is – (20 + (256 * 10)) or –2580.
Note: You can see the color palette in the Form Editor’s Object Properties window.
Note: While SET COLOR works with indexed colors within the default 4D color palette,
version 6 introduces the command SET RGB COLORS, which allows you to work with any
RGB color.
Example
The following example sets the color for a button named bInfo. The color is set to the
values of the two variables named vForeground and vBackground:
See Also
SET RGB COLORS.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET RGB COLORS changes the foreground and background colors of the
objects specified by object and the optional * parameters.
If you specify the optional * parameter, you indicate an object name (a string) in object. If
you omit the optional * parameter, you indicate a field or a variable in object. In this case,
you specify a field or variable reference (field or variable objects only) instead of a string.
For more information about object names, see the section Object Properties.
You indicate RGB color values in foreground and background. An RGB value is a 4-byte
Long Integer whose format (0x00RRGGBB) is described in the following table (bytes are
numbered from 0 to 3, from right to left):
Byte Description
3 Must be zero if absolute RGB color
2 Red component of the color (0..255)
1 Green component of the color (0..255)
0 Blue component of the color (0..255)
WARNING: On Windows, these automatic colors are system dependent. If you change
your system colors in the Colors Windows Control Panel, 4th Dimension will adjust its
automatic colors accordingly. Use the automatic color values for setting objects to the
system colors, not for setting them to the example colors shown above.
Note the use of the Bitwise operators for calculating the color value from the thermometer
values.
In the User or Custom Menus environments, the form looks like this:
See Also
Bitwise Operators, SET COLOR.
Description
The command GET OBJECT RECT returns the coordinates left, top, right and bottom (in
points) in variables or fields of the object(s) of the current form defined by the
parameters * and object.
If you pass the optional parameter *, it indicates that the object parameter is an object
name (a string). If you don’t pass the optional parameter *, it indicates that object is a
field or a variable. In this case, you don’t pass a string but a field or variable reference
(only a field or variable of type object).
If you pass an object name to object and use the wildcard character (“@”) to select more
than one object, the coordinates returned will be those of the rectangle formed by all the
objects concerned.
Note: Since 4D version 6.5, it is possible to set the interpretation mode of the wildcard
character (“@”), when it is included in a string of characters. This option has an impact
on the “Object Properties” commands. Please refer to the 4D Design Mode manual.
If the object doesn’t exist or if the command is not called in a form, the coordinates
(0;0;0;0) are returned.
Example
Let’s assume that you want to obtain the coordinates of a rectangle formed by all the
objects that begin with “button”:
See Also
MOVE OBJECT.
Description
The command MOVE OBJECT allows you to move the object(s) in the current form,
defined by the * and object parameters moveH pixels horizontally and moveV pixels
vertically.
It is also possible (optionally) to resize the object(s) resizeH pixels horizontally and resizeV
pixels vertically.
The direction to move and resize depend on the values passed to the moveH and moveV
parameters:
• If the value is positive, objects are moved and resized to the right and to the bottom,
respectively.
• If the value is negative, objects are moved and resized to the left and to the top,
respectively.
If you pass the first optional parameter *, you indicate that the object parameter is a
parameter name (a string of characters). If you don’t pass the * parameter, object is a field
or a variable. In this case, you don’t pass a string but a field or variable reference (only a
field or variable of type object).
If you pass an object name to object and use the wildcard character (“@”) to select more
than one object, all the objects concerned will be moved or resized.
Note: Since 4D version 6.5, it is possible to set the interpretation mode of the wildcard
character (“@”), when it is included in a string of characters. This option has an impact
on the “Object Properties” commands. Please refer to the 4D Design Mode manual.
Examples
(1) The following statement moves “button_1” 10 pixels to the right, 20 pixels to the top
and resizes it to 30 pixels in width and 40 in height:
(2) The following statement moves “button_1” to the following coordinates (10;20)
(30;40):
See Also
GET OBJECT RECT.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The BEST OBJECT SIZE command returns the bestWidth and bestHeight parameters, the
“optimal” width and height of the form object designated by the * and object parameters.
These values are expressed in pixels. This command is particularly useful for displaying or
printing complex reports, associated with the MOVE OBJECT command.
If you pass the optional * parameter, this indicates that the object parameter is an object
name (a character string). If you do not pass the * parameter, this indicates that object is a
field or a variable. In this case, do not pass a string but rather a field or variable reference
(object type only).
The optimal values returned indicate the minimum size of the object so that its current
contents are entirely included within the limits. Of course, these values are only
meaningful for objects containing text. This calculation takes the font, font size, font
style and object contents into account. It also takes hyphenation and carriage returns
into consideration. If the object specified is empty, the bestWidth returned is 0.
The size returned does not take into account any graphic frame applied around the object,
nor any scrollbars. To obtain the real size of an object on screen, it is necessary to add the
width of these elements.
The optional maxWidth parameter enables you to attribute a maximum width to the
object. If the optimal width of the object is greater than this value, BEST OBJECT SIZE
returns maxWidth in the bestWidth parameter and increases the optimal height as a
consequence.
Example
Refer to the example in the SET PRINT MARKER command.
See also
MOVE OBJECT.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get alignment returns a code indicating the type of alignment applied to
the object designated by the object and * parameters.
If you specify the optional * parameter, you indicate an object name (a string) in the
object parameter. If you omit the * parameter, you indicate a field or variable in the object
parameter. In this case, you specify a field or variable reference (field or variable objects
only) instead of a string.
Note: If you apply the command to a group of objects, only the alignment value of the
last object is returned.
The returned code corresponds to one of the following constants located in the Object
alignment theme:
Constant Type Value
Align default Longint 1
Align left Longint 2
Center Longint 3
Align right Longint 4
See Also
SET ALIGNMENT.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET ALIGNMENT allows you to set the type of alignment applied to the
object(s) designated by the object and * parameters.
If you specify the optional * parameter, you indicate an object name (a string) in the
object parameter. If you omit the * parameter, you indicate a field or variable in the object
parameter. In this case, you specify a field or variable reference (field or variable objects
only) instead of a string.
Pass one of the constants of the Object alignment theme in the alignment parameter:
Constant Type Value
Align default Longint 1
Align left Longint 2
Center Longint 3
Align right Longint 4
See Also
Get alignment.
Obsolete commands
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SEARCH BY INDEX
This command is still present in 4th Dimension for compatibility with 4D version 1. For
any new programming, use the command QUERY.
WARNING: This command will disappear in future versions. Please do not use it.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SORT BY INDEX
This command is still present in 4th Dimension for compatibility with 4D version 1. For
any new programming, use the command ORDER BY.
WARNING: This command will disappear in future versions. Please do not use it.
On a Series
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Average, Max, Min, Sum, Sum squares, Std deviation, and Variance functions can be
applied to fields or subfields. In the case of a field, they are applied to a selection of
records. In the case of a subfield, they are applied to a selection of the subrecords of the
current record. Note that the
Sum squares, Std deviation, and Variance functions can be used on a field only during
printing.
These functions work on numeric data only. Each of these functions returns a numeric
value.
Using a field
When Average, Max, Min, or Sum are used on a field outside a printing operation, they
may have to load each record in the current selection to calculate the result. If there are
many records, this process may take some time. To avoid this, index the field.
When these functions are used in a report, they behave differently than at other times.
This is because the report itself must load each record. Use these functions in a form or
object method when printing with the PRINT SELECTION command or when printing by
choosing Print from the File menu in the User environment.
When you use these functions in a report, the values that are returned are reliable only at
break level 0, and only when break processing is turned on. This means that they are
useful only at the end of a report, after all the records have been processed.
You would use these functions only in an object method for a non-enterable area that is
included in the B0 Break area.
Remember that the field passed as a parameter to the statistical function must be a
numeric.
See Also
Average, Max, Min, Std deviation, Sum, Sum Squares, Variance.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Sum returns the sum (total of all values) for series. If series is an indexed
field, the index is used to total the values.
Example
The following example is an object method for a variable that vTotal placed in a form.
The object method assigns the sum of all salaries to vTotal:
⇒ vTotal:=Sum([Employees]Salary)
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Employees])
ORDER BY ([Employees];[Employees]LastNm;>)
BREAK LEVEL (1)
ACCUMULATE ([Employees]Salary)
OUTPUT FORM ([Employees];"PrintForm")
PRINT SELECTION ([Employees])
Note: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
ACCUMULATE, Average, BREAK LEVEL, Max, Min, ORDER BY, PRINT SELECTION, Subtotal.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Average returns the arithmetic mean (average) of series. If series is an indexed field, the
index is used to find the average.
Example
The following example sets the variable vAverage that is in the B0 Break area of an output
form. The line of code is the object method for vAverage. The object method is not
executed until the level 0 break:
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Employees])
ORDER BY ([Employees];[Employees]LastNm;>)
BREAK LEVEL (1)
ACCUMULATE ([Employees]Salary)
OUTPUT FORM ([Employees];"PrintForm")
PRINT SELECTION ([Employees])
Note: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
ACCUMULATE, BREAK LEVEL, Max, Min, ORDER BY, PRINT SELECTION, Subtotal, Sum.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Min returns the minimum value in series. If series is an indexed field, the index is used to
find the minimum value.
Examples
1. The following example is an object method for the variable vMin placed in the break 0
portion of the form. The variable is printed at the end of the report. The object method
assigns the minimum value of the field to the variable, which is then printed in the last
break of the report:
⇒ vMin:=Min([Employees]Salary)
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Employees])
ORDER BY ([Employees];[Employees]LastNm;>)
BREAK LEVEL (1)
ACCUMULATE ([Employees]Salary)
OUTPUT FORM ([Employees];"PrintForm")
PRINT SELECTION ([Employees])
NOTE: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
2. The following example finds the lowest sale amount of an employee and displays the
result in an alert box. The sales amounts are stored in the subfield [Employees]SalesDollars:
See Also
Execute on server, Execute on server, GET PROCESS VARIABLE, Max, Processes, SET PROCESS
VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Max returns the maximum value in series. If series is an indexed field, the index is used to
find the maximum value.
Example
The following example is an object method for the variable vMax placed in the break 0
portion of the form. The variable is printed at the end of the report. The object method
assigns the maximum value of the field to the variable, which is then printed in the last
break of the report.
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Employees])
ORDER BY ([Employees];[Employees]LastNm;>)
BREAK LEVEL (1)
ACCUMULATE ([Employees]Salary)
OUTPUT FORM ([Employees];"PrintForm")
PRINT SELECTION ([Employees])
Note: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
Min.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Std deviation returns the standard deviation of series. If series is an indexed field, the index
is used to find the standard deviation. You can only use a field with this function when
printing a report.
Example
The following example is an object method for the variable vDeviate. The object method
assigns the standard deviation for a data series to vDeviate:
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Table1])
ORDER BY ([Table1];[Table1]DataSeries;>)
BREAK LEVEL (1)
ACCUMULATE ([Table1]DataSeries)
OUTPUT FORM ([Table1];"PrintForm")
PRINT SELECTION ([Table1])
NOTE: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
Average, Sum, Sum Squares, Variance.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Variance returns the variance for series. If series is an indexed field, the index is used to
find the variance. You can only use a field with this function when printing a report.
Example
The following example is an object method for the variable var. The object method
assigns the sum of squares for a data series to var:
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Students])
ORDER BY ([Students];[Students]Class;>)
BREAK LEVEL (1)
ACCUMULATE ([Students]Grades)
OUTPUT FORM ([Students];"PrintForm")
PRINT SELECTION ([Students])
NOTE: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
Average, Std deviation, Sum, Sum squares.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Sum squares returns the sum of the squares of series. If series is an indexed field, the index
is used to find the sum of the squares. You can only use a field with this function when
printing a report.
Example
The following example is an object method for the variable vSquares. The object method
assigns the sum of squares for a data series to vSquares. The vSquares variable is printed in
the last break of the report:
The following method is called to print the records in the selection and to activate break
processing:
ALL RECORDS ([Table1])
ORDER BY ([Table1];[Table1]DataSeries;>)
BREAK LEVEL (1)
ACCUMULATE ([Table1]DataSeries)
OUTPUT FORM ([Table1];"PrintForm")
PRINT SELECTION ([Table1])
NOTE: The parameter to the BREAK LEVEL command should be equal to the number of
breaks in your report. For more information about break processing, refer to the printing
commands.
See Also
Average, Std deviation, Sum, Variance.
Operators
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Operators are symbols used to specify operations performed between expressions. They:
• Perform calculations on numbers, dates, and times.
• Perform string operations, Boolean operations on logical expressions, and specialized
operations on pictures.
• Combine simple expressions to generate new expressions.
Precedence
The order in which an expression is evaluated is called precedence. 4 th Dimension has a
strict left-to-right precedence, in which algebraic order is not observed. For example:
3+4*5
returns 35, because the expression is evaluated as 3 + 4, yielding 7, which is then
multiplied by 5, with the final result of 35.
To override the left-to-right precedence, you MUST use parentheses. For example:
3 + (4 * 5)
returns 23 because the expression (4 * 5) is evaluated first, because of the parentheses. The
result is 20, which is then added to 3 for the final result of 23.
Parentheses can be nested inside other sets of parentheses. Be sure that each left
parenthesis has a matching right parenthesis to ensure proper evaluation of expressions.
Lack of, or incorrect use of parentheses can cause unexpected results or invalid
expressions. Furthermore, if you intend to compile your applications, you must have
matching parentheses—the compiler detects a missing parenthesis as a syntax error.
Important: Do NOT confuse the assignment operator := with the equality comparison
operator =.
String Operators
See the section String Operators.
Numeric Operators
See the section Numeric Operators.
Date Operators
See the section Date Operators.
Time Operators
See the section Time Operators.
Comparison Operators
See the section Comparison Operators.
Logical Operators
See the section Logical Operators.
Picture Operators
See the section Picture Operators.
Bitwise Operators
See the section Bitwise Operators.
See Also
Constants, Data Types, Identifiers.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An expression that uses a string operator returns a string. The following table shows the
string operators:
See Also
Bitwise Operators, Comparison Operators, Date Operators, Logical Operators, Numeric
Operators, Operators, Picture Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An expression that uses a numeric operator returns a number. The following table shows
the numeric operators:
Modulo Operator
The modulo operator % divides the first number by the second number and returns a
whole number remainder. Here are some examples:
• 10 % 2 returns 0 because 10 is evenly divided by 2.
• 10 % 3 returns 1 because the remainder is 1.
• 10.5 % 2 returns 0 because the remainder is not a whole number.
WARNING: The modulo operator % returns significant values with numbers that are in
the Long Integer range (from minus 2^31 to 2^31 minus one). To calculate the modulo
with numbers outside of this range, use the Mod command.
See Also
Bitwise Operators, Comparison Operators, Date Operators, Logical Operators, Operators,
Picture Operators, String Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An expression that uses a date operator returns a date or a number, depending on the
operation. All date operations will result in an accurate date, taking into account the
change between years and leap years. The following table shows the date operators:
See Also
Bitwise Operators, Comparison Operators, Logical Operators, Numeric Operators, Operators,
Picture Operators, String Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An expression that uses a time operator returns a time or a number, depending on the
operation. The following table shows the time operators:
Tips
(1) To obtain a time expression from an expression that combines a time expression with
a number, use the commands Time and Time string.
Example:
` The following line assigns to $vlSeconds the number of seconds that will be elasped
` between midnight and one hour from now
$vlSeconds:=Current Time+3600
` The following line assigns to $vHSoon the time it will be in one hour
$vhSoon:=Time(Time string(Current time+3600))
However, while developing your application, you may encounter situations where a delay,
expressed in seconds and added to a time value, is only available to you as a numeric
value.
In this case, use the next tip.
Example:
` Select and open a document
$vhDocRef:=Open document("")
If (OK=1)
` Pass the DocRef time expression
` as a numeric expresssion to a 4D Extension routine
DO SOMETHING SPECIAL (0+$vhDocRef)
End if
See Also
Bitwise Operators, Comparison Operators, Date Operators, Logical Operators, Numeric
Operators, Operators, Picture Operators, String Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The tables in this section show the comparison operators as they apply to string, numeric,
date, time, and pointer expressions. An expression that uses a comparison operator returns
a Boolean value, either TRUE or FALSE.
String Comparisons
Operation Syntax Returns Expression Value
Equality String = String Boolean "abc" = "abc" True
"abc" = "abd" False
Inequality String # String Boolean "abc" # "abd" True
"abc" # "abc" False
Greater than String > String Boolean "abd" > "abc" True
"abc" > "abc" False
Less than String < String Boolean "abc" < "abd" True
"abc" < "abc" False
Greater than or equal to String >= String Boolean "abd" >= "abc" True
"abc" >= "abd" False
Less than or equal to String <= String Boolean "abc" <= "abd" True
"abd" <= "abc" False
Numeric Comparisons
Operation Syntax Returns Expression Value
Equality Number = Number Boolean 10 = 10 True
10 = 11 False
Inequality Number # Number Boolean 10 #11 True
10 # 10 False
Greater than Number > Number Boolean 11 > 10 True
10 > 11 False
Less than Number < Number Boolean 10 < 11 True
11 < 10 False
Greater than or equal to Number >= Number Boolean 11 >= 10 True
10 >= 11 False
Less than or equal to Number <= Number Boolean 10 <= 11 True
11 <= 10 False
Time Comparisons
Operation Syntax Returns Expression Value
Equality Time = Time Boolean ?01:02:03? = ?01:02:03? True
?01:02:03? = ?01:02:04? False
Inequality Time # Time Boolean ?01:02:03? # ?01:02:04? True
?01:02:03? # ?01:02:03? False
Greater than Time > Time Boolean ?01:02:04? > ?01:02:03? True
?01:02:03? > ?01:02:03? False
Less than Time < Time Boolean ?01:02:03? < ?01:02:04? True
?01:02:03? < ?01:02:03? False
Greater than or equal to Time >= Time Boolean ?01:02:03? >=?01:02:03? True
?01:02:03? >=?01:02:04? False
Less than or equal to Time <= Time Boolean ?01:02:03? <=?01:02:03? True
?01:02:04? <=?01:02:03? False
Pointer comparisons
With:
` vPtrA and vPtrB point to the same object
vPtrA:=->anObject
vPtrB:=->anObject
` vPtrC points to another object
vPtrC:=->anotherObject
• When strings are compared, diacritical characters are compared using the system
character comparison table of your computer. For example, the following expressions
return TRUE:
"n" = "ñ"
"n" = "Ñ"
"A" = "å"
` and so on
• The wildcard character (@) can be used in any string comparison to match any number
of characters. For example, the following expression is TRUE:
"abcdefghij" = "abc@"
The wildcard character must be used within the second operand (the string on the right
side) in order to match any number of characters. The following expression is FALSE,
because the @ is considered only as a one character in the first operand:
"abc@" = "abcdefghij"
The wildcard means “one or more characters or nothing”. The following expressions are
TRUE:
"abcdefghij" = "abcdefghij@"
"abcdefghij" = "@abcdefghij"
"abcdefghij" = "abcd@efghij"
"abcdefghij" = "@abcdefghij@"
"abcdefghij" = "@abcde@fghij@"
On the other hand, whatever the case, a string comparison with two consecutive
wildcards will always return FALSE. The following expression is FALSE:
"abcdefghij" = "abc@@fg"
Tip
If you obtain a string from data entry, that string may contain the @ character—you
cannot treat this wildcard like the other characters. Let’s consider the following example:
$vsValue:=Request("Enter the value you are looking for:")
If (OK=1)
QUERY ([Customers];[Customers]Name=$vsValue+"@")
End if
You must use the Ascii command, because the following expression (if $vsValue is not
empty) always returns TRUE:
$vsValue≤Length($vsValue)≥="@"
Continuing with this example, the string entered in the request dialog box may contain
several @ characters and even strings like "@@D@OE@@@". The following code will
eliminate all the @ characters present in a string:
` No at signs Project Method
` No at signs ( String ) -> String
` No at signs ( Any string ) -> String with no @
$0:=""
For ($vlChar;1;Length($1))
If (Ascii($1≤$vlChar≥)#64)
$0:=$0+$1≤$vlChar≥
End if
End for
In other words, this small project method does the same thing as the command Replace
string. However, it is necessary (and it uses ASCII codes) because the following Replace
string expression will always return an empty string:
Replace String($vsValue;"@";"") ` All characters are removed
With this code, the query will always be a “begins with” query, no matter what string is
entered in the request dialog box.
See Also
Bitwise Operators, Date Operators, Logical Operators, Numeric Operators, Operators, Picture
Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension supports two logical operators that work on Boolean expressions:
conjunction (AND) and inclusive disjunction (OR). A logical AND returns TRUE if both
expressions are TRUE. A logical OR returns TRUE if at least one of the expressions is TRUE.
4th Dimension also provides the Boolean functions True, False, and Not. For more
information, see the descriptions of these commands.
The following is the truth table for the AND logical operator:
Expr1 Expr2 Expr1 & Expr2
True True True
True False False
False True False
False False False
Tip
If you need to calculate the exclusive disjunction between Expr1 and Expr2, evaluate:
(Expr1 | Expr2) & Not(Expr1 & Expr2)
See Also
Bitwise Operators, Comparison Operators, Date Operators, Numeric Operators, Operators,
Picture Operators, String Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
An expression that uses a picture operator returns a picture. The following table shows the
picture operators.
The two operators & and | always return a bitmapped picture, no matter what the nature
of the two source pictures. The reason is that 4th Dimension first draws the pictures into
memory bitmaps, then calculates the resulting picture by performing graphical exclusive
or inclusive OR on the pixels of the bitmaps.
The other picture operators return vectorial pictures if the two source pictures are
vectorial. Remember, however, that pictures printed by the display format On
Background are printed bitmapped.
Examples
In the following examples, all of the pictures are shown using the display format On
Background.
• Horizontal concatenation
circle + rectangle ` Place the rectangle on the right of the circle
See Also
Bitwise Operators, Comparison Operators, Date Operators, Logical Operators, Numeric
Operators, Operators, String Operators, Time Operators.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Note: If you pass an Integer or a Real value to a bitwise operator, 4th Dimension evaluates
the value as a Long Integer value before calculating the expression that uses the bitwise
operator.
While using the bitwise operators, you must think about a Long Integer value as an array
of 32 bits. The bits are numbered from 0 to 31, from right to left.
Because each bit can equal 0 or 1, you can also think about a Long Integer value as a value
where you can store 32 Boolean values. A bit equal to 1 means True and a bit equal to 0
means False.
An expression that uses a bitwise operator returns a Long Integer value, except for the Bit
Test operator, where the expression returns a Boolean value. The following table lists the
bitwise operators and their syntax:
Operation Operator Syntax Returns
Bitwise AND & Long & Long Long
Bitwise OR (inclusive) | Long | Long Long
Bitwise OR (exclusive) ^| Long ^| Long Long
Left Bit Shift << Long << Long Long (see note 1)
Right Bit Shift >> Long >> Long Long (see note 1)
Bit Set ?+ Long ?+ Long Long (see note 2)
Bit Clear ?- Long ?- Long Long (see note 2)
Bit Test ?? Long ?? Long Boolean (see note 2)
Notes
(1) For the Left Bit Shift and Right Bit Shift operations, the second operand indicates the
number of positions by which the bits of the first operand will be shifted in the resulting
value.
Therefore, this second operand should be between 0 and 32. Note however, that shifting
by 0 returns an unchanged value and shifting by more than 31 bits returns 0x00000000
because all the bits are lost. If you pass another value as second operand, the result is non
significant.
(2) For the Bit Set, Bit Clear and Bit Test operations , the second operand indicates the
number of the bit on which to act. Therefore, this second operand must be between 0
and 31. Otherwise, the expression returns the value of the first operand unchanged for Bit
Set and Bit Clear, and returns False for Bit Test.
Operation Description
Bitwise AND Each resulting bit is the logical AND of the bits in the two
operands. Here is the logical AND table:
1&1→1
0&1→0
1&0→0
0&0→0
In other words, the resulting bit is 1 if the two operand bits are
1; otherwise the resulting bit is 0.
Bitwise OR (inclusive) Each resulting bit is the logical OR of the bits in the two
operands. Here is the logical OR table:
1|1→1
0|1→1
1|0→1
0|0→0
In other words, the resulting bit is 1 if at least one of the two
operand bits is 1; otherwise the resulting bit is 0.
Bitwise OR (exclusive) Each resulting bit is the logical XOR of the bits in the two
operands. Here is the logical XOR table:
1 ^| 1 → 0
0 ^| 1 → 1
1 ^| 0 → 1
0 ^| 0 → 0
In other words, the resulting bit is 1 if only one of the two
operand bits is 1; otherwise the resulting bit is 0.
Left Bit Shift The resulting value is set to the first operand value, then the
resulting bits are shifted to the left by the number of positions
indicated by the second operand. The bits on the left are lost
and the new bits on the right are set to 0.
Note: Taking into account only positive values, shifting to the
left by N bits is the same as multiplying by 2^N.
Right Bit Shift The resulting value is set to the first operand value, then the
resulting bits are shifted to the right by the number of position
indicated by the second operand. The bits on the right are lost
and the new bits on the left are set to 0.
Note: Taking into account only positive values, shifting to the
right by N bits is the same as dividing by 2^N.
Examples
(1) The following table gives an example of each bit operator:
(2) 4th Dimension provides many predefined constants. The literals of some of these
constants end with “bit” or “mask.” For example, this is the case of the constants
provided in the Resources properties theme:
For example, to test whether a resource (whose properties have been obtained in the
variable $vlResAttr) is purgeable or not, you can write:
If ($vlResAttr ?? Purgeable resource bit) ` Is the resource purgeable?
or:
If (($vlResAttr & Purgeable resource mask) # 0) Is the resource purgeable?
Conversely, you can use these constants to set the same bit. You can write:
$vlResAttr:=$vlResAttr ?+ Purgeable resource bit
or:
$vlResAttr:=$vlResAttr | Purgeable resource bit
(3) This example stores two Integer values into a Long Integer value. You can write:
$viIntB:=$vlLong & 0xFFFF ` Extract back the Integer stored in the low-word
Tip: Be careful when manipulating Long Integer or Integer values with expressions that
combine numeric and bitwise operators. The high bit (bit 31 for Long Integer, bit 15 for
Integer) sets the sign of the value—positive if it is cleared, negative if it is set. Numeric
operators use this bit for detecting the sign of a value, bitwise operators do not care about
the meaning of this bit.
See Also
Comparison Operators, Date Operators, Logical Operators, Numeric Operators, Operators,
Picture Operators, String Operators, Time Operators.
Printing
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PRINT LABEL enables you to print labels with the data from the selection of table.
If do not specify the document parameter, PRINT LABEL prints the current selection of
table as labels, using the current output form. You cannot use this command to print
subforms. For details about creating forms for labels, refer to the 4th Dimension Design
Reference manual.
If you specify the document parameter, PRINT LABEL enables you to access the Label
Wizard (shown below) or to print an existing Label document stored on disk. See the
following discussion.
If the Label Wizard is not involved, the OK variable is set to 1 if all labels are printed;
otherwise, it is set to 0 (zero) (i.e., if user clicked Cancel in the printing dialog boxes).
If you specify the document parameter, the labels are printed with the label setup defined
in document. If document is an empty string (""), PRINT LABEL will present an Open File
dialog box so the user can specify the file to use for the label setup. If document is the
name of a document that does not exist (for example, pass char(1) in document), the
Label Wizard is displayed and the user can define the label setup.
Examples
1. The following example prints labels using the output form of a table. The example uses
two methods. The first is a project method that sets the correct output form and then
prints labels:
ALL RECORDS([Addresses]) ` Select all records
OUTPUT FORM ([Addresses]; "Label Out") ` Select the output form
⇒ PRINT LABEL([Addresses]) ` Print the labels
OUTPUT FORM ([Addresses];"Output") ` Restore default output form
The second method is the form method for the form "Label Out". The form contains one
variable named vLabel, which is used to hold the concatenated fields. If the second address
field (Addr2) is blank, it is removed by the method. Note that this task is performed
automatically with the Label Wizard. The form method creates the label for each record:
` [Addresses]; "Label Out" form method
Case of
: (Form event=On load)
vLabel:=[Addresses]Name1+" "+[Addresses]Name2+Char(13)+[Addresses]Addr1+
Char(13)
If ([Addresses]Addr2 # "")
vLabel:=vLabel +[Addresses]Addr2+Char(13)
End if
vLabel:=vLabel+[Addresses]City+", "+[Addresses]State+" "+[Addresses]ZipCode
End case
3. The following example lets the user query the [People] table, and then lets the user
choose the labels to be printed:
QUERY ([People])
If (OK=1)
⇒ PRINT LABEL ([People];"")
End if
4. The following example lets the user query the [People] table, and then displays the
Label Wizard so the user can design, save, load and print any labels:
QUERY ([People])
If (OK=1)
⇒ PRINT LABEL ([People];Char(1))
End if
See Also
PRINT SELECTION, QR REPORT.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PRINT SELECTION prints the current selection of table. The records are printed with the
current output form of the table in the current process. PRINT SELECTION performs the
same action as the Print menu command in the User environment. If the selection is
empty, PRINT SELECTION does nothing.
By default, PRINT SELECTION displays the printer dialog boxes before printing. If the user
cancels either of the printer dialog boxes, the command is canceled and the report is not
printed.
You can suppress these dialog boxes by using either the optional asterisk (*) parameter or
the optional “greater than” (>) parameter:
• The * parameter causes a print job using the current print parameters (default parameters
or those defined by the PAGE SETUP and/or SET PRINT OPTION commands)..
• Furthermore, the > parameter causes a print job without reinitializing the current print
parameters. This setting is useful for executing several successive calls to PRINT SELECTION
(ex. inside a loop) while maintaining previously set customized print parameters. For an
example of use of this parameter, refer to the PRINT RECORD command description.
During printing, the output form method and/or the form’s object methods are executed
depending on the events that are enabled in the Form and Object Properties windows in
the Design environment, as well as on the events actually occurring:
• An On Header event is generated just before a header area is printed.
• An On Printing Detail event is generated just before a record is printed.
• An On Printing Break event is generated just before a break area is printed.
• An On Printing Footer event is generated just before a footer is printed.
You can check whether PRINT SELECTION is printing the first header by testing Before
selection during an On Header event. You can also check for the last footer, by testing End
selection during an On Printing Footer event. For more information, see the description of
these commands, as well as those of Form event and Level.
Warning: Do not use the PAGE BREAK command with the PRINT SELECTION command.
PAGE BREAK is to be used with the PRINT FORM command.
After a call to PRINT SELECTION, the OK variable is set to 1 if the printing has been
completed. If the printing was interrupted, the OK variable is set to 0 (zero) (i.e., the user
clicked Cancel in the printing dialog boxes).
Example
The following example selects all the records in the [People] table. It then uses the
DISPLAY SELECTION command to display the records and allows the user to highlight the
records to print. Finally, it uses the selected records with the USE SET command, and
prints them with PRINT SELECTION:
ALL RECORDS([People]) ` Select all records
DISPLAY SELECTION ([People]; *) ` Display the records
USE SET ("UserSet") ` Use only records picked by user
⇒ PRINT SELECTION([People]) ` Print the records that the user picked
See Also
ACCUMULATE, BREAK LEVEL, Level, PAGE SETUP, Subtotal.
Description
Print form simply prints form with the current values of fields and variables. It is usually
used to print very complex reports that require complete control over the printing
process. Print form does not do any record processing, break processing or page breaks.
These operations are your responsibility. Print form prints fields and variables in a fixed
size frame only.
Since Print form does not issue a page break after printing the form, it is easy to combine
different forms on the same page. Thus, Print form is perfect for complex printing tasks
that involve different tables and different forms. To force a page break between forms,
use the PAGE BREAK command. In order to carry printing over to the next page for a form
whose height is greater than the available space, call the CANCEL command before the
PAGE BREAK command.
In this case, Print form only prints the Detail area (the area between the Header line and
the Detail line) of the form.
• Section printing
Syntax:
height:=Print form (myTable;myForm;areaStart;areaEnd)
In this case, the command will print the section included between the areaStart and
areaEnd parameters. The values entered must be expressed in pixels.
The value returned by Print form indicates the height of the printable area. This value will
be automatically taken into account by the Get printed height command.
The printer dialog boxes do not appear when you use Print form. The report does not use
the print settings that were assigned to the form in the Design environment. There are
two ways to specify the print settings before issuing a series of calls to Print form:
• Call PRINT SETTINGS. In this case, you let the user choose the settings.
• Call PAGE SETUP. In this case, print settings are specified programmatically.
Print form builds each printed page in memory. Each page is printed when the page in
memory is full or when you call PAGE BREAK. To ensure the printing of the last page after
any use of Print form, you must conclude with the PAGE BREAK command. Otherwise, if
the last page is not full, it stays in memory and is not printed.
Warning: Subforms and external objects are not printed with Print form. To print only one
form with such objects, use PRINT RECORD instead.
Print form generates only one On Printing Detail event for the form method.
See Also
CANCEL, PAGE BREAK, PAGE SETUP, PRINT SETTINGS.
Description
PAGE BREAK triggers the printing of the data that has been sent to the printer and ejects
the page. PAGE BREAK is used with Print form (in the context of the On Printing Detail
form event) to force page breaks and to print the last page created in memory. Do not use
PAGE BREAK with the PRINT SELECTION command. Instead, use Subtotal or BREAK LEVEL
with the optional parameter to generate page breaks.
The * parameter allows you to cancel a print job started with the Print form command.
Executing this command immediately stops the print job in progress.
Note: Under Windows, this mechanism can be disrupted by the spooling properties of the
print server. If the printer is configured to start printing immediately, cancelling will not
be effective. For the PAGE BREAK(*) command to operate correctly, it is preferable to
choose the "Start printing after last page is spooled" property for the printer.
The > parameter modifies the way in which the PAGE BREAK command behaves. This
syntax has two effects:
• It holds the print job open until the PAGE BREAK command is executed again without a
parameter.
• It gives priority to the print job. No other printing can take place until the print job is
finished.
The second option is particularly useful when used with a spooled print job. The >
parameter guarantees that the print job will be spooled to one file. This will reduce
printing time.
Examples
(1) See example for the Print form command.
(2) Refer to the example of the SET PRINT MARKER command.
See Also
CANCEL, PRINT FORM.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PRINT RECORD prints the current record of table, without modifying the current
selection. The current output form is used for printing. If there is no current record for
table, PRINT RECORD does nothing.
You can print subforms and external objects with the PRINT RECORD command. This is
not possible with Print form.
Note: If there are modifications to the record that have not been saved, this command
prints the modified field values, not the field values located on disk.
By default, PRINT RECORD displays the printer dialog boxes before printing. If the user
cancels either of the printer dialog boxes, the command is canceled and the record is not
printed.
You can suppress these dialog boxes by using either the optional asterisk (*) parameter or
the optional “greater than” (>) parameter:
• The * parameter causes a print job using the current print parameters (default parameters
or those defined by the PAGE SETUP and/or SET PRINT OPTION commands).
• Furthermore, the > parameter causes a print job without reinitializing the current print
parameters. This setting is useful for executing several successive calls to PRINT RECORD
(ex. inside a loop) while maintaining previously set customized print parameters.
Examples
1. The following example prints the current record of the [Invoices] table. The code is
contained in the object method of a Print button on the input form. When the user
clicks the button, the record is printed using an output form designed for this purpose.
` Select the right output form for printing
OUTPUT FORM([Invoices];"Print One From Data Entry")
` Print Invoices as it is (without showing the printing dialog boxes)
⇒ PRINT RECORD([Invoices];*)
OUTPUT FORM([Invoices];"Standard Output") ` Restore the previous output form
See Also
Print form.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Printing page returns the printing page number. It can be used only when you are
printing with PRINT SELECTION or the Print menu in the User environment.
Example
The following example changes the position of the page numbers on a report so that the
report can be reproduced in a double-sided format. The form for the report has two
variables that display page numbers. A variable in the lower-left corner (vLeftPageNum)
will print the even page numbers. A variable in the lower-right corner (vRightPageNum)
will print the odd page numbers. The example tests for even pages, then clears and sets
the appropriate variables:
Case of
: (Form event=On Printing Footer)
⇒ If ((Printing page % 2) = 0) ` Modulo is 0, it is an even page
⇒ vLeftPageNum:=String(Printing page) ` Set the left page number
vRightPageNum:="" ` Clear the right page number
Else ` Otherwise it is an odd page
vLeftPageNum:="" ` Clear the left page number
⇒ vRightPageNum:=String (Printing page) ` Set the right page number
End if
End case
See Also
PRINT SELECTION.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Note: This command does not work under MacOS 9.
The PRINTERS LIST command fills in the array(s) passed as parameter(s) with the names as
well as, optionally, the locations and models of the available printers for the machine.
Note: If the printers are managed using a print server (spooler), the complete access path
(under Windows) or the name of the spooler (under MacOS) is returned.
Pass the name of a text array in the namesArray parameter. After command execution,
this array will contain the names of available printers. If you pass the optional
locationsArray and modelsArray arrays, you will retrieve the network location (or local port)
and model for each printer.
Note: The locationsArray and modelsArray parameters can only be used under Windows.
Use the SET CURRENT PRINTER and Get current printer commands to modify or get the
selected printer in 4D.
Under Windows, the name of a printer can be modified manually at the operating system
level. On the other hand, its location and model type are linked to its physical
characteristics. Therefore, you can use the optional array values to check the
characteristics of the selected printer — typically, you can check that all the client
machines use the same printer.
Under MacOS, this check can be carried out using the name of the printer (name of the
print server), which is the same for each machine that is connected.
See also
Get current printer, SET CURRENT PRINTER.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Note: This command does not work under MacOS 9.
The SET CURRENT PRINTER command is used to designate the printer to be used for
printing with the current 4D application.
Pass the name of the printer to be selected in the printerName parameter. To get a list of
available printers, use the new PRINTERS LIST command beforehand.
If you pass an empty string in printerName, the current printer defined in the system will
be used.
The selection of a new printer will cause the resetting of the current print options.
Consequently, the SET CURRENT PRINTER command must be called before PAGE SETUP
and SET PRINT OPTION, otherwise the parameters set previously are lost.
This command can be used with the PRINT SELECTION, PRINT LABEL, PRINT RECORD, Print
form, and QR REPORT commands, and is applied to all 4th Dimension printing, including
that in Design mode.
See also
Get current printer, PRINTERS LIST.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Note: This command does not work under MacOS 9.
The Get current printer command returns the name of the current printer defined in the
4D application. By default, on start-up of 4D, the current printer is the printer defined in
the system.
If the current printer is managed using a print server (spooler), the complete access path
(under Windows) or the name of the spooler (under MacOS) is returned.
To obtain the list of available printers as well as additional information, use the PRINTERS
LIST command. To modify the current printer, use the SET CURRENT PRINTER command.
See also
PRINTERS LIST, SET CURRENT PRINTER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
BREAK LEVEL specifies the number of break levels in a report performed using PRINT
SELECTION.
Warning: In compiled mode, you must execute BREAK LEVEL and ACCUMULATE before
every report for which you want to do break processing. These commands activate break
processing for a report. See the explanation for the Subtotal command.
The level parameter indicates the deepest level for which you want to perform break
processing. You must have sorted the records with at least that many levels. If you have
sorted more levels, those levels will be printed as sorted, but will not be processed for
breaks.
Each break level that is generated will print the corresponding Break areas and Header
areas in the form. There should be at least as many Break areas in the form as the number
you pass in level. If there are more Break areas, they will be ignored and will not be
printed.
The second, optional, argument, pageBreak, is used to cause page breaks during printing.
Example
The following example prints a report with two break levels. The selection is sorted on
four levels, but the BREAK LEVEL command specifies to break on only two levels. One field
is accumulated with the ACCUMULATE command:
ORDER BY ([Emp]Dept;>;[Emp]Title;>;[Emp]Last;>;[Emp]First;>) ` Sort on four levels
⇒ BREAK LEVEL (2) ` Turn on break processing to 2 levels (Dept and Title)
ACCUMULATE ([Emp]Salary) ` Accumulate the salaries
OUTPUT FORM ([Emp];"Dept salary") ` Select the report form
PRINT SELECTION([Emp]) ` Print the report
See Also
ACCUMULATE, ORDER BY, PRINT SELECTION, Subtotal.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET PRINT OPTION command is used to modify, by programming, the value of a
print option. Each option defined using this command is applied to the entire database
and for the duration of the session as long as no other command that modifies print
parameters (PRINT SETTINGS, PRINT SELECTION without the > parameter, etc.) is called.
The option parameter allows you to indicate the option to be modified. You can pass
either a value or one of the predefined constants of the “Print options”theme.
Pass the new value(s) of the specified option in the value1 and (optionally) value2
parameters. The number and nature of the values to be passed depends on the type of
option specified.
The following tables lists the options and their possible values:
option (constant) value1 value2
1 (Paper option) Name -
Height Width
2 (Orientation option) 1=Portrait, 2=Landscape -
3 (Scale option) Number (%) -
4 (Number of copies option) Number -
5 (Paper source option) Windows only:
Index (number) -
8 (Color option) Windows only:
1=N/B, 2=Color -
9 (Destination option) 1=Printer, -
2=File (PC)/PS (Mac), Access path
3=PDF (Mac), Access path
4=EPS (Mac) Access path
11 (Double sided option) Windows only:
0=Single-sided (standard) -
1=Double-sided Binding: 0=Left (default),
1=Top
12 (Spooler document name option) Name of document -
to be printed
Once set using this command, a print option is kept throughout the duration of the
session for the entire 4D application. It will be used by the PRINT SELECTION, PRINT
LABEL, PRINT RECORD, Print form, and REPORT commands, as well as for all 4th
Dimension printing, including that in Design mode.
Note: It is indispensable to use the optional > parameter with the PRINT SELECTION,
PRINT LABEL, PRINT RECORD and PAGE BREAK commands in order to avoid resetting the
print options that were set using the SET PRINT OPTION command.
See also
GET PRINT OPTION, PRINT OPTION VALUES.
Error Handling
If the value passed for an option is invalid or if it is not available on the printer, the
command returns an error (that you can intercept using an error management method
installed by the ON ERR CALL command) and the current value of the option remains
unchanged.
Constants
Print options theme.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET PRINT OPTION command returns the current value(s) of a print option.
The option parameter enables you to specify the option to get. You can either pass a value
or one of the following predefined constants, located in the “Print options” theme:
Constant Type Value
Paper option Longint 1
Orientation option Longint 2
Scale option Longint 3
Number of copies option Longint 4
Paper source option Longint 5
Color option Longint 8
Destination option Longint 9
Double sided option Longint 11
Spooler document name option Longint 12
The command returns, in the value1 and (optionally) value2 parameters, the current
value(s) of the specified option. For more information on options and possible values,
refer to the description of the SET PRINT OPTION command. Note the following specific
features of the GET PRINT OPTION command:
• option = 1 (paper option): returns the name of the current paper in value1 if value2 is
omitted. If value2 is passed, the command returns, respectively, the width and height of
the paper in value1 and value2. Use the PRINT OPTION VALUES command to get the name,
height and width of all the paper formats offered by the printer.
• option = 2 (orientation option): returns 1 (Portrait) or 2 (Landscape). If a different
orientation option is used, value1 is set to 0.
• option = 5 (paper source option): in value1 returns the index (in the array of trays
returned by the PRINT OPTION VALUES command) of the paper tray used (value2 must be
omitted).
Note: This option can only be used under Windows.
• option = 8 (color option): returns a code in value1 specifying the mode for handling
color: 1=Black and white (monochrome), 2=Color.
Note: This option can only be used under Windows.
• option = 9 (destination option): if the current value is not in the predefined list, value1
contains -1 and the system variable OK is set to 1. If an error occurs, value1 and the
See also
PRINT OPTION VALUES, SET PRINT OPTION.
Constants
Print options theme.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
In namesArray, the PRINT OPTION VALUES command returns a list of value names
available for the print option defined. Optionally, you can retrieve information for each
value in info1Array and info2Array.
The option parameter allows you to specify the option to get. You must pass one of the
following constants of the “Print options” theme (options able to return lists of value
names):
Constant Type Value
Paper Longint 1
Paper source Longint 5
After command execution, the namesArray array as well as, where applicable, the
info1Array and info2Array arrays will be filled in by the command with the names and
information of the available values.
If you pass value 1 (paper option) in the option parameter, the command will return the
following information:
• in namesArray, the names of the available paper formats;
• in info1Array, the heights of each paper format;
• in info2Array, the widths of each paper format.
Note: In order to obtain this information, the print driver must have access to a valid
PPD (PostScript Printer Description) file for the printer.
In order to apply a specific paper format using the SET PRINT OPTION command, you can
either pass one of the values of namesArray, the corresponding values of info1Array and
info2Array.
If you pass value 5 (paper source option) in the option parameter, the command returns
the names of the different trays available in namesArray, and their internal Windows ID
numbers in info1Array (info2Array remains empty).
The order of the values in the arrays is defined by the print driver. To indicate a tray using
the SET PRINT OPTION command, you must pass the index, as found in the namesArray or
info1Array arrays, of the element desired.
All the information returned by these commands is supplied by the operating system.
Refer to the documentation of your system for more details about specific options.
See also
GET PRINT OPTION, SET PRINT OPTION.
Constants
Print options theme.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
ACCUMULATE specifies the fields or variables to be accumulated during a form report
performed using PRINT SELECTION.
Warning: In compiled mode, you must execute BREAK LEVEL and ACCUMULATE before
every report for which you want to do break processing. These commands activate break
processing for a report. See the explanation for the Subtotal command.
Use ACCUMULATE when you want to include subtotals for numeric fields or variables in a
form report. ACCUMULATE tells 4th Dimension to store subtotals for each of the Data
arguments. The subtotals are accumulated for each break level specified with the BREAK
LEVEL command.
Use the Subtotal function in the form method or an object method to return the subtotal
of one of the data arguments.
Example
See the example for the BREAK LEVEL command.
See Also
BREAK LEVEL, ORDER BY, PRINT SELECTION, Subtotal.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Subtotal returns the subtotal for data for the current or last break level. Subtotal works
only when a sorted selection is being printed with PRINT SELECTION or when printing
using Print in the User environment. The data parameter must be of type real, integer, or
long integer. Assign the result of the Subtotal function to a variable placed in the Break
area of the form.
Warning: In compiled mode, you must execute BREAK LEVEL and ACCUMULATE before
every form report for which you want to do break processing and calculate subtotals. See
discussion at the end of the description of this command.
Subtotal should be in the form method or an object method for the form. 4th Dimension
scans the form method and object methods before printing; if Subtotal is present, break
processing will be initiated (in interpreted mode only).
The second, optional, argument to Subtotal is used to cause page breaks during printing. If
pageBreak is 0, Subtotal does not issue a page break. If pageBreak equals 1, Subtotal issues a
page break for each level 1 break. If pageBreak equals 2, Subtotal issues a page break for
each level 1 and level 2 break, and so on.
To have breaks on N sort levels, you must sort the current selection on N + 1 levels (unless
you use BREAK LEVEL or ACCUMULATE, in which case N levels is sufficien). This lets you
sort on a last field, so that the field does not create unwanted breaks. To have the last sort
field generate a break, sort the field twice.
Tip: If you execute Subtotal from within an output form displayed at the screen, an error
will be generated, triggering an infinite loop of updates between the form and the error
window. To get out of this loop, press Alt+Shift (Windows) or Option-Shift (Macintosh)
when you click on the Abort button in the Error window (you may have to do so several
times). This temporarily stops the updates for the form’s window. Select another form as
the output form so the error will occur again. Go back to the Design Environment and
isolate the call to Subtotal into a test Form event=On Printing Break if you use the form
both for display and printing.
For more information about designing forms with header and break areas, see the
4th Dimension Design Reference manual.
If 4th Dimension finds the function, break processing is activated. The Subtotal function
does not need to be executed for it to turn on break processing. For example, it could be
in a method of an object that is below the Footer line and therefore would never be
printed or executed.
When Subtotal is used to activate break processing, you must sort on one more level than
you break on. For example, to have two levels of breaks in your report, sort on three
levels.
The process to print the report in the User environment is typically like this:
1. Select the records to be printed.
2. Order by (sort) the records, sorting on one extra level.
3. Choose Print from the File menu.
4th Dimension scans the form and object methods, finds the Subtotal function, turns on
break processing, and prints the report. There are two disadvantages to using Subtotal to
trigger break processing:
• You cannot use Subtotal to activate break processing in compiled databases.
• You must sort on one extra level; if you have many records, this may be time
consuming.
Using BREAK LEVEL and ACCUMULATE to activate break processing is the recommended
method when using methods to generate form reports. The process to print a report using
this method is typically like this:
1. Select the records to be printed.
2. Sort the records using ORDER BY. Sort on at least the same number of levels as breaks.
3. Execute BREAK LEVEL and ACCUMULATE.
4. Print the report using PRINT SELECTION.
You must use BREAK LEVEL and ACCUMULATE to activate break processing in compiled
mode. However, the Subtotal function is still necessary in order to display values on a
form.
See Also
ACCUMULATE, BREAK LEVEL, Level, PRINT SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Level → Number
Description
Level is used to determine the current header or break level. It returns the level number
during the On Header and On Printing Break events.
Level 0 is the last level to be printed and is appropriate for printing a grand total. Level
returns 1 when 4th Dimension prints a break on the first sorted field, 2 when
4th Dimension prints a break on the second sorted field, and so on.
Example
This example is a template for a form method. It shows each of the possible events that
can occur while a summary report uses a form as an output form. Level is called when a
header or a break is printed:
` Method of a form being used as output form for a summary report
$vpFormTable:=Current form table
Case of
` ...
: (Form event=On Header)
` A header area is about to be printed
Case of
: (Before selection($vpFormTable->))
` Code for the first break header goes here
⇒ : (Level = 1)
` Code for a break header level 1 goes here
⇒ : (Level = 2)
See Also
ACCUMULATE, BREAK LEVEL, Form event, PRINT SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PAGE SETUP sets the page setup for the printer to that stored with form. The page setup is
stored with the form when the form is saved in the Design environment.
In the following three cases, the printing dialog boxes are not displayed and the printing
is performed with the default print settings. :
• Calling PRINT SELECTION to which you pass the optional * parameter
• Calling PRINT RECORD to which you pass the optional * parameter
• Issuing a series of calls to PRINT FORM not preceeded by a call to PRINT SETTINGS.
Calling PAGE SETUP enables you, in this case, to skip the printing dialog boxes AND to use
print settings other than the default ones.
Example
Several (empty) forms are created for a table named [Design Stuff]. The form “PS100” is
assigned a page setup with a scaling of 100%, the form “PS90” is assigned a page setup
with a scaling of 90%, and so on. The following project method enables you to print the
selection of a table using various scalings without having to specify the scaling in the
printing dialog boxes (which are not displayed), each time:
` AUTOMATIC SCALED PRINTING project method
` AUTOMATIC SCALED PRINTING ( Pointer ; String {; Long } )
` AUTOMATIC SCALED PRINTING ( ->[Table]; "Output form" {; Scaling } )
If (Count parameters>=3)
⇒ PAGE SETUP([Design Stuff];"PS"+String($3))
If (Count parameters>=2)
OUTPUT FORM($1->;$2)
End if
End if
If (Count parameters>=1)
PRINT SELECTION($1->;*)
Else
PRINT SELECTION(*)
End if
See Also
PRINT FORM, PRINT RECORD, PRINT SELECTION.
Description
The command Get print marker enables you to get the current position of a marker during
printing.
Pass one of the constants of the Form area theme in the markNum parameter:
Constant Type Value
Form Header Longint 200
Form Header1...10 Longint 201...210
Form Detail Longint 0
Form Break0...9 Longint 300...309
Form Footer Longint 100
Example
Refer to the example of the SET PRINT MARKER command.
See Also
MOVE OBJECT, SET PRINT MARKER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
PRINT SETTINGS
Description
PRINT SETTINGS displays the printing dialog boxes. First, it displays the Print Setup dialog
box. Then, it displays the Print Job dialog box.
You should include PRINT SETTINGS before any group of PRINT FORM commands.
The Print Job dialog box contains a Preview on Screen check box that allows the user to
specify to print to the screen. You can preset or reset this check bok by calling SET PRINT
PREVIEW before calling PRINT SETTINGS.
Example
See example for the command PRINT FORM.
See Also
PAGE BREAK, PRINT FORM, SET PRINT PREVIEW.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET PRINT PREVIEW allows you to programmatically check or uncheck the Preview on
Screen option of the Print dialog box. If you pass TRUE in preview, Preview on Screen will
be checked, if you pass FALSE in preview , Preview on Screen will be unchecked. This
setting is local to a process and does not affect the printing of other processes or users.
Example
The following example turns on the Preview on Screen option to display the results of a
query on screen, and then turns it off.
QUERY([Customers])
If (OK=1)
⇒ SET PRINT PREVIEW (True)
PRINT SELECTION ([Customers] ; *)
⇒ SET PRINT PREVIEW (False)
End if
See Also
PRINT RECORD, PRINT SELECTION, PRINT SETTINGS.
Description
The SET PRINT MARKER command enables the definition of the marker position during
printing. Combined with the Get print marker, MOVE OBJECT or Print form commands,
this command allows you to adjust the size of the print areas.
Pass one of the constants of the Form area theme in the markNum parameter:
Constant Type Value
Form Header Longint 200
Form Header1...10 Longint 201...210
Form Detail Longint 0
Form Break0...9 Longint 300...309
Form Footer Longint 100
If you pass the optional * parameter, all the markers located below the marker specified in
markNum will be moved the same number of pixels and in the same direction as this
marker when the command is executed. Any objects present in the areas located below
the marker are also moved.
Notes:
• This command modifies only the existing marker position. It does not allow the
addition of markers. If you designate a marker that does not exist in the form, the
command will not do anything.
• The print marker mechanism in the Structure mode is retained: a marker cannot go any
higher than the one that precedes it, nor any lower than the one that follows it (when
the * parameter is not used).
Example
This complete example enables you to generate the printing of a three-column report, the
height of each row being calculated on the fly according to the contents of the fields.
The output form used for printing is as follows:
While(Not(End selection([Film])))
vSprint_area:="Detail" `Printing of detail area
$vLheight:=Print form([Film];"Print_List3";Form Detail)
`Detail calculation is carried out in the form method
vLprinted_height:=vLprinted_height+$vLheight
If(OK=0) `CANCEL has been carried out in the form method
PAGE BREAK
vLprinted_height:=0
vSprint_area:="Header" `Reprinting of the header area
$vLheight:=Print form([Film];"Print_List3";Form Header)
$vLheight:=21
vLprinted_height:=vLprinted_height+$vLheight
vSprint_area:="Detail"
$vLheight:=Print form([Film];"Print_List3";Form Detail)
vLprinted_height:=vLprinted_height+$vLheight
End if
NEXT RECORD([Film])
End while
PAGE BREAK `Make sure that the last page is printed
Case of
: (vSprint_area="Detail") `Printing of detail underway
GET OBJECT RECT([Film]Actors;$l;$t;$r;$b)
$fixed_wdth:=$r-$l `Calculation of the Actors text field size
$exact_hght:=$b-$t
BEST OBJECT SIZE([Film]Actors;$wdth;$hght;$fixed_wdth)
`Optimal size of the field according to its contents
$movement:=$hght-$exact_hght
If($movement>0)
$position:=Get print marker(Form Detail)
$final_pos:=$position+$movement
`We move the Detail marker and those that follow it
⇒ SET PRINT MARKER(Form Detail ;$final_pos;*)
`Resizing of text areas
MOVE OBJECT([Film]Actors;$l;$t;$r;$hght+$t;*)
MOVE OBJECT([Film]Summary;$l1;$t1;$r1;$hght1+$t1;*)
See Also
BEST OBJECT SIZE, GET OBJECT RECT, Get print marker, MOVE OBJECT, PAGE BREAK, Print
form, PRINT RECORD, PRINT SELECTION.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET PRINTABLE MARGIN returns the current values of the different
margins defined using the Print form command.
The values are returned in pixels with respect to the paper edges.
It is possible to obtain the paper size as well as to calculate the printable area using the
GET PRINTABLE AREA function.
Beginning with 4th Dimension version 6.8.1, it is possible to base the form printing
carried out using the Print form, PRINT RECORD and PRINT SELECTION commands on a
fixed margin which is identical on each printer: the paper margins, i.e. the physical limits
of the sheet. To do this, simply use the GET PRINTABLE MARGIN, SET PRINTABLE MARGIN
and GET PRINTABLE AREA commands.
See Also
GET PRINTABLE AREA, Print form, SET PRINTABLE MARGIN.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET PRINTABLE MARGIN enables you to set the values of various printing
margins by using the Print form command.
You can pass one of the following values into the left, top, right and bottom parameters:
• 0 = use paper margins
• -1 = use printer margins
• value > 0 = margin in pixels (1 pixel in 72 dpi represents approximately 0.4 mm)
The values of the right and bottom parameters relate to the right and bottom edges of the
paper respectively.
Note: For more information regarding Printing management and terminology in 4D,
refer to the GET PRINTABLE MARGIN command description.
By default, 4th Dimension bases its printouts on the printer margins. Once the SET
PRINTABLE MARGIN command is executed, the modified parameters are retained in the
same process for the entire session.
Examples
(1) The following example enables you to obtain the size of the dead margin:
(2) The following example enables you to obtain the paper size:
SET PRINTABLE MARGIN (0;0;0;0) `Sets the paper margin
GET PRINTABLE AREA($height;$width)
`For size A4: $height=842 ; $width=595 pixels
See Also
GET PRINTABLE MARGIN, Get printed height, Print form.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET PRINTABLE AREA returns the size, in pixels, of the height and width
parameters of the printable area. This size depends on the current printing parameters,
the paper orientation, etc.
The sizes returned do not vary from one page to another (after a page break, for
instance).
Associated with the Get printed height command, this command is useful for knowing the
number of pixels available for printing or for centering an object on the page.
Note: For more information regarding Printing management and terminology in 4D,
refer to the GET PRINTABLE MARGIN command description.
See Also
GET PRINTABLE MARGIN, Print form.
version 6.8.1
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get printed height returns the overall height (in pixels) of the section
printed using the Print form command.
The value returned will be included between 0 (the top edge of the page) and the overall
height returned by the GET PRINTABLE AREA command (the maximum size of the
printable area).
If you print a new section using the Print form command, the height of the new section
is added to this value. If the printable area available is insufficient to contain this section,
a new page is generated and the value returned is 0.
The right and left printable margins, unlike the top and bottom margins (which may be
defined using the SET PRINTABLE MARGIN command), do not influence the value
returned.
Note: For more information regarding Printing management and terminology in 4D,
refer to the GET PRINTABLE MARGIN command description.
See Also
GET PRINTABLE AREA, Print form, SET PRINTABLE MARGIN.
Pictures
Supported Formats
The following charts summarize the support for various picture formats on the Macintosh
and Windows platforms.
See Also
BLOB TO PICTURE, COMPRESS PICTURE, COMPRESS PICTURE FILE, LOAD COMPRESS
PICTURE FROM FILE, PICTURE PROPERTIES, Picture size, PICTURE TO BLOB, PICTURE TYPE
LIST, READ PICTURE FILE, SAVE PICTURE TO FILE, WRITE PICTURE FILE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command COMPRESS PICTURE compresses the picture contained in the field or
variable picture.
The parameter quality is an integer between 1 and 1000 indicating the quality of the
compressed picture. In general, reducing the quality will allow for greater compression of
the picture.
Warning: The compression ratio possible for a given quality depends on the size and
nature of the picture you are compressing. Compressing small pictures may not produce
any decrease in size.
See Also
COMPRESS PICTURE FILE, LOAD COMPRESS PICTURE FROM FILE, Pictures.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command compresses a picture loaded from a document on disk.
You can open a PICT document using the Open document function. You can then use the
document reference returned by this function to load and compress the PICT found in
the document. This command loads the picture into memory, compresses it using the
method and quality you have specified, and then returns it into Picture.
The picture is loaded into memory before it is compressed. If there is not enough memory
to load the picture, use COMPRESS PICTURE FILE before calling LOAD COMPRESS PICTURE
FROM FILE.
The parameter quality is an integer between 1 and 1000 indicating the quality of the
compressed picture. In general, reducing the quality will allow for greater compression of
the picture.
Warning: The compression ratio possible for a given quality depends on the size and
nature of the picture you are compressing. Compressing small pictures may not produce
any decrease in size.
See Also
COMPRESS PICTURE, COMPRESS PICTURE FILE, Pictures, SAVE PICTURE TO FILE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command compresses a picture document on disk. Use this command to compress a
picture that you know cannot be loaded with the available memory. Once compressed, it
can be loaded into memory using LOAD COMPRESS PICTURE FROM FILE.
The parameter quality is an integer between 1 and 1000 indicating the quality of the
compressed picture. In general, reducing the quality will allow for greater compression of
the picture.
Warning: The compression ratio possible for a given quality depends on the size and
nature of the picture you are compressing. Compressing small pictures may not produce
any decrease in size.
Example
The following example presents the Open File dialog box that allows you to select a PICT
file. Only PICT files will be displayed. The picture is compressed, loaded into memory, and
stored in a picture variable. The file is then closed.
vRef:=Open document ("";"PICT")
If (OK=1)
⇒ COMPRESS PICTURE FILE(vRef;"jpeg";500)
LOAD COMPRESS PICTURE FROM FILE(vRef;"";500;vPict)
CLOSE DOCUMENT(vRef)
End if
See Also
COMPRESS PICTURE, LOAD COMPRESS PICTURE FROM FILE, SAVE PICTURE TO FILE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command saves picture in a document that was created using the Create document
function.
Example
The following example creates a document and saves a picture in it:
vRef:=Create document("";"PICT")
If (OK=1)
⇒ SAVE PICTURE TO FILE(vRef;vPict)
CLOSE DOCUMENT(vRef)
End if
See Also
COMPRESS PICTURE FILE, LOAD COMPRESS PICTURE FROM FILE.
Description
The command PICTURE TO GIF allows you to convert a PICT picture stored in a variable
or in a 4D field into a GIF picture.
You pass a picture variable or a picture field in pict and a BLOB variable or a BLOB field in
blobGIF. After executing the command, blobGIF contains the image in GIF format.
Note: The GIF picture format cannot contain more than 256 colors. If the original PICT
picture contains more colors, some may be lost. The GIF generated by this command is
optimized according to the colors of the original picture. The GIF type of the generated
picture is of type 87a (opaque) and normal (not interlaced).
You can then save the picture located in blobGIF in a file using the BLOB TO DOCUMENT
command or you can even publish it on the Web.
If the conversion was successful, the OK system variable is set to 1. Otherwise, it will be
equal to 0.
Example
Let us assume that you want to generate a GIF picture on the fly by displaying a
connection counter. In the database’s picture library, place all the numbers as pictures:
$div:=10^($ndigits-1)
For ($i;1;$ndigits)
$ref:=Int($1/$div)%10
GET PICTURE FROM LIBRARY($ref+1000;picture)
$img:=$img+picture
$div:=$div/10
End for
⇒ PICTURE TO GIF($img;$0)
When sending a page to the Web browser, 4D displays a GIF picture that looks like the
following picture:
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command PICTURE TO BLOB converts a picture stored in a 4D variable or field to
another format and places the resulting picture in a BLOB.
Pass in the format parameter a 4-characters string setting the conversion format. This
format can be:
• either a QuickTime format (see command PICTURE TYPE LIST description), in this case
QuickTime version 4 or above must be installed on the machine,
• either "GIFf" (GIF format) or "WBMP" (Wireless Bitmap); these last two formats do not
require QuickTime 4.
Once the command has been executed, the pictureBlob contains the picture in the
specified format.
If the conversion was successful, the system variable OK is set to 1. If the conversion has
failed (QuickTime is not installed or the convertor is not available), OK is set to 0 and the
generated BLOB is empty (0 byte).
See Also
BLOB TO PICTURE, PICTURE TO GIF, PICTURE TYPE LIST, WRITE PICTURE FILE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command BLOB TO PICTURE inserts a picture stored in a BLOB into a 4D picture
variable or field, regardless its original format — however the format should be QuickTime
4 compatible.
Warning: This command requires QuickTime version 4 or above for MacOS and Windows.
If Quicktime 4 is not installed, the command does nothing.
This command is similar to the command READ PICTURE FILE, it just applies to a BLOB
instead of a file. It allows you to display pictures stored in native format into BLOBs. You
can load a picture into a BLOB using, for example, the command DOCUMENT TO BLOB or
PICTURE TO BLOB.
A BLOB variable or field containing a picture is passed in the pictureBlob parameter. The
picture can be in any QuickTime 4 supported format. You can obtain the list of available
formats using the PICTURE TYPE LIST command. Refer to the PICTURE TYPE LIST
command for a description of QuickTime 4 standard format codes.
Pass in the picture parameter the 4D picture field or variable which should display the
picture.
Note: The internal picture format is stored by QuickTime within the 4D variable or field.
Consequently, it is necessary to get QuickTime to read the picture within 4D.
Once the command has been executed, the picture parameter contains the picture to
display.
If the conversion has been done successfully, the system variable OK is set to 1. If the
conversion has failed (QuickTime 4 is not installed, or the BLOB does not contain a
readable picture), OK is set to 0 and the picture variable or field is empty.
See Also
PICTURE TO BLOB, PICTURE TYPE LIST, READ PICTURE FILE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command WRITE PICTURE FILE allows you to save the picture passed in the picture
parameter in the defined format to disk.
You can pass in fileName the full pathname to the file to create, or a file name only. If you
just pass the file name, the file will be located next to the database structure file. Under
Windows, the file extension has to be indicated.
If an empty string ("") is passed in fileName, the standard Save file dialog box is displayed
and the user can indicate the name, location and format of the file to create.
You will pass in picture the picture variable or field which contains the picture to save on
disk.
The optional parameter format defines the picture saving format. This parameter should
contain a 4-characters QuickTime code. You can get the list of available formats using the
PICTURE TYPE LIST command. Refer to the PICTURE TYPE LIST command to get a
description for QuickTime 4 standard format codes.
If the format parameter is omitted or if QuickTime is not installed, the picture file is
created with a PICT format.
If the command is executed successfully, the system variable Document contains the full
pathname to the file created and the system variable OK is set to 1. Otherwise, OK is set to
0.
See Also
PICTURE TO BLOB, PICTURE TYPE LIST, Pictures, READ PICTURE FILE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command READ PICTURE FILE allows you to open the picture saved in the fileName
disk file and to load it in the picture 4D field or variable.
You can pass in fileName the full pathname of the file to read, or a file name only. If you
just pass the file name, it should be located next to the database structure file. Under
Windows, the file extension must be indicated.
If an empty string ("") is passed in fileName, the standard Open file dialog box is displayed
and the user can select the file to be read, as well as the available formats (provided with
QuickTime 4).
You can obtain the list of available formats using the PICTURE TYPE LIST command. Refer
to the PICTURE TYPE LIST command for a description of QuickTime 4 standard format
codes.
You pass in picture the picture variable or field which will get the read image.
Note: The internal picture format is stored by QuickTime within the 4D variable or field.
Consequently, it is necessary to get QuickTime to read the picture within 4D.
If the command is executed successfully, the system variable Document contains the full
pathname to the open file and the system variable OK is set to 1. Otherwise, OK is set to
0.
See Also
BLOB TO PICTURE, PICTURE TYPE LIST, Pictures, WRITE PICTURE FILE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This function returns the size of picture in bytes.
See Also
PICTURE PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command PICTURE PROPERTIES returns information about the picture you pass in
picture.
The parameters width and height return the width and height of the picture.
The parameters hOffset, vOffset, and mode return the horizontal and vertical positions and
the transfer mode of the picture when displayed on the background in a form.
See Also
Picture size.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CREATE THUMBNAIL returns a thumbnail from a given source picture.
Thumbnails are usually used for picture preview within multimedia software or Web sites.
Note: This command does not require QuickTime installation.
You pass in the source parameter the 4D variable or field containing the picture to reduce
to a thumbnail. You pass in the dest parameter the 4D picture field or variable which
should host the resulting thumbnail.
The optional parameters width and height define the required thumbnail size (in pixels). If
you omit these parameters, the thumbnail default size will be 48 x 48 pixels.
The optional parameter mode defines the thumbnail creation mode, i.e. the reduction
mode. Three modes are available. The following predefined constants are provided by 4th
Dimension in the “Picture Display Formats” constant theme:
Constants Type Value
Scaled to fit Long integer 2
Scaled to fit proportional Long integer 5
Scaled to fit prop centered Long integer 6 (default)
Note: Only these constants can be used with CREATE THUMBNAIL. The other constants in
the theme “Picture Display Formats” cannot be applied to this command.
If you do not enter any parameter, the “Scaled to fit prop centered” mode (6) is applied
by default.
Note: With the “Scaled to fit proportional” and the “Scaled to fit prop centered”, the free
space will be displayed in white. When these modes are applied to picture field or variable
in 4D forms, the free space is transparent.
The optional parameter depth defines the number of colors (i.e., the screen depth) to keep
for the resulting thumbnail. The parameter is an integer equal to the number of bits per
pixel: 1, 2, 4, 8, 16 or 32. Enter 0 to use the current screen depth (default value).
version 6.0.2
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command PICTURE LIBRARY LIST returns the reference numbers and names of the
pictures currently stored in the Picture Library of the database.
After the call, you retrieve the reference numbers in the array picRefs and the names in
the array picNames. The two arrays are synchronized: the nth element of picRefs is the
reference number of the Picture Library graphic whose name is returned in the nth
element of picNames.
The array picRefs can be a Real, Long Integer or Integer array. In interpreted mode, if the
array is not declared prior to the call to PICTURE LIBRARY LIST, a Real array is created by
default.
The array picNames can be a String or Text array. In interpreted mode, if the array is not
declared prior to the call PICTURE LIBRARY LIST, a Text array is created by default.
The maximum length of a Picture Library graphic name is 31 characters. If you use a
String array as picNames, declare it with a large enough fixed length to avoid having a
truncated name returned.
If there are no pictures in the Picture Library, both arrays are returned empty.
To obtain the number of pictures currently stored in the Picture Library, use the Size of
array command to get the size of one of the two arrays.
2. The following example tests whether or not the Picture Library is empty:
PICTURE LIBRARY LIST(alPicRef;asPicName)
If (Size of array(alPicRef)=0)
ALERT("The Picture Library is empty.")
Else
ALERT("The Picture Library contains "+String(Size of array(alPicRef))+" pictures.")
End if
See Also
GET PICTURE FROM LIBRARY, REMOVE PICTURE FROM LIBRARY, SET PICTURE TO LIBRARY.
Description
The GET PICTURE FROM LIBRARY command returns in the picture parameter the Picture
Library graphic whose reference number is passed in picRef or whose name is passed in
picName.
Note for components developers: If you want a 4D component to use graphics stored in
the Picture Library, you must pass a picture name as first parameter. Indeed, when a
component requiring its own pictures is installed by 4D Insider, the application can
renumber automatically these new pictures if some database pictures have already the
same reference number.
If there is no picture with that reference number or name, GET PICTURE FROM LIBRARY
leaves picture unchanged.
Examples
1. The following example returns in vgMyPicture the picture whose reference number is
stored in the local variable $vlPicRef:
⇒ GET PICTURE FROM LIBRARY($vlPicRef;vgMyPicture)
2. The following example returns in $DDcom_Prot_MyPicture the picture with the name
"DDcom_Prot_Button1" stored in the Picture Library:
⇒ GET PICTURE FROM LIBRARY("DDcom_Prot_Button1";$DDcom_Prot_MyPicture)
3. See the third example for the command PICTURE LIBRARY LIST.
See Also
PICTURE LIBRARY LIST, REMOVE PICTURE FROM LIBRARY, SET PICTURE TO LIBRARY.
Error Handling
If there is not enough memory to return the picture, an error -108 is generated. You can
catch this error using an error-handling method.
version 6.0.2
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET PICTURE TO LIBRARY creates a new picture or replaces a picture in the
Picture Library.
If there is an existing Picture Library graphic with the same reference number, the picture
contents are replaced and the picture is renamed according to the values passed in picture
and picName.
If there is no Picture Library graphic with the reference number passed in picRef, a new
picture is added to the Picture Library.
4D Server: SET PICTURE TO LIBRARY cannot be used from within a method executed on
the server machine (stored procedure or trigger). If you call SET PICTURE TO LIBRARY on a
server machine, nothing happens—the call is ignored.
Warning: Design objects (hierarchical list items, menu items, etc.) may refer to Picture
Library graphics. Use caution when modifying a Picture Library graphic
programmatically.
Note: If you pass an empty picture in picture or a negative or null value in picRef, the
command does nothing.
2. The following example imports into the Picture Library the pictures (stored in a
document on disk) created by the third example for the command PICTURE LIBRARY LIST:
SET CHANNEL(10;"")
If (OK=1)
RECEIVE VARIABLE($vsTag)
If ($vsTag="4DV6PICTURELIBRARYEXPORT")
RECEIVE VARIABLE($vlNbPictures)
If ($vlNbPictures)
For($vlPicture;1;$vlNbPictures)
RECEIVE VARIABLE($vlPicRef)
If (OK=1)
RECEIVE VARIABLE($vlPicName)
End if
If (OK=1)
RECEIVE VARIABLE ($vgPicture)
End if
If (OK=1)
⇒ SET PICTURE TO LIBRARY($vgPicture;$vlPicRef;$vlPicName)
Else
$vlPicture:=$vlNbPictures+1
ALERT("This file looks like being damaged.")
End if
End for
Else
ALERT("This file looks like being damaged.")
End if
Else
ALERT("The file “"+Document+"” is not a Picture Library export file.")
End if
SET CHANNEL(11)
End
Error Handling
If there is not enough memory to add the picture to the Picture Library, an error -108 is
generated. Note that I/O errors may also be returned (i.e., the structure file is locked). You
can catch these errors using an error-handling method.
Description
The command REMOVE PICTURE FROM LIBRARY removes from the Picture Library the
picture whose reference number is passed in picRef or whose name is passed in picName.
If there is no picture with that reference number or name, the command does nothing.
4D Server: REMOVE PICTURE FROM LIBRARY cannot be used from within a method
executed on the server machine (stored procedure or trigger). If you call REMOVE PICTURE
FROM LIBRARY on a server machine, nothing happens—the call is ignored.
Warning: Design objects (hierarchical list items, menu items, etc.) may refer to Picture
Library graphics. Use caution when deleting a Picture Library graphic programmatically.
Examples
1. The following example deletes the picture #4444 from the Picture Library.
2. The following example deletes from the Picture Library any pictures whose names
begin with a dollar sign ($):
PICTURE LIBRARY LIST($alPicRef;$asPicName)
For($vlPicture;1;Size of array($alPicRef))
If ($asPicName{$vlPicture}="$@")
⇒ REMOVE PICTURE FROM LIBRARY($alPicRef{$vlPicture})
End if
End for
See Also
GET PICTURE FROM LIBRARY, PICTURE LIBRARY LIST, SET PICTURE TO LIBRARY.
Process
(Communications)
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
A semaphore is a flag shared among workstations (each user’s computer) or among
processes on the same workstation. A semaphore simply exists or does not exist. The
methods that each user is running can test for the existence of a semaphore. By creating
and testing semaphores, methods can communicate between workstations.
The Semaphore function returns TRUE if semaphore exists. If semaphore does not exist,
Semaphore creates it and returns FALSE. Only one user at a time can create a semaphore. If
Semaphore returns FALSE, it means that the semaphore did not exist, but it also means
that the semaphore has been set for the process in which the call has been made.
Semaphore returns FALSE if the semaphore was not set. It also returns FALSE if the
semaphore is already set by the same process in which the call has been made. semaphore
is limited to 30 characters, including prefixes (<>, $). If you pass a longer string, the
semaphore will be tested with the truncated string.
The optional parameter tickCount allows you to specify a waiting time (in ticks) if
semaphore is already set. In this case, the function will wait either for the semaphore to be
freed or the waiting time to expire before returning True.
There are two types of semaphores in 4th Dimension: local semaphores and global
semaphores.
• A local semaphore is accessible by all processes on the same workstation and only on the
workstation. A local semaphore can be created by prefixing the name of the semaphore
with a dollar sign ($). You use local semaphores to monitor operations among processes
executing on the same workstation. For example, a local semaphore can be used to
monitor access to an interprocess array shared by all the processes in your single-user
database or on the workstation.
• A global semaphore is accessible to all users and all their processes. You use global
semaphores to monitor operations among users of a multi-user database.
Global and local semaphores are identical in their logic. The difference resides in their
scope.
You do not use semaphores to protect record access. This is automatically done by
4th Dimension and 4D Server. Use semaphores to prevent several users from performing
the same operation at the same time.
Examples
1. In this example, you want to prevent two users from doing a global update of the
prices in a Products table. The following method uses semaphores to manage this:
⇒ If (Semaphore("UpdatePrices")) ` Try to create the semaphore
ALERT("Another user is already updating prices. Retry later.")
Else
DoUpdatePrices ` Update all the prices
CLEAR SEMAPHORE("UpdatePrices")) ` Clear the semaphore
End if
2. The following example uses a local semaphore. In a database with several processes, you
want to maintain a To Do list. You want to maintain the list in an interprocess array and
not in a table. You use a semaphore to prevent simultaneous access. In this situation, you
only need to use a local semaphore, because your To Do list is only for your use.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CLEAR SEMAPHORE erases semaphore previously set by the Semaphore function.
As a rule, all semaphores that have been created should be cleared. If semaphores are not
cleared, they remain in memory until the process that creates them ends. A process can
only clear semaphores that it has created. If you try to clear a semaphore from within a
process that did not create it, nothing happens.
Example
See the example for Semaphore.
See Also
Semaphore.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Test semaphore allows you to test the existence of a semaphore.
The difference between the Semaphore function and the Test semaphore function is that
Test semaphore doesn’t create the semaphore if it doesn’t exit. If the semaphore exists, the
function returns True. Otherwise, it returns False.
Example
The following example allows you to know the state of a process (in our case, while
modifying the code) without modifying semaphore:
$Win:=Open window (x1;x2;y1;y2;-Palette window)
Repeat
⇒ If (Test semaphore("Encrypting code"))
POSITION MESSAGE ($x3;$y3)
MESSAGE("Encrypting code being modified.")
Else
POSITION MESSAGE($x3;$y3)
MESSAGE("Modification of the encrypting code authorized.")
End if
Until (StopInfo)
CLOSE WINDOW
See Also
Semaphore.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CALL PROCESS calls the form displayed in the frontmost window of process.
Important: CALL PROCESS only works between processes running on the same machine.
If process (the target process) is not currently displaying a form, nothing happens. The
form displayed in the target process receives an On Outside call event. This event must be
enabled for that form in the Design environment Form Properties window, and you must
manage the event in the form method. If the event is not enabled or if it is not managed
in the form method, nothing happens.
Note: The On Outside call event modifies the entry context of the receiving input form.
In particular, if a field was being edited, the On Data change event is generated.
The caller process (the process from which CALL PROCESS is executed) does not “wait”—
CALL PROCESS has an immediate effect. If necessary, you must write a waiting loop for a
reply from the called process, using interprocess variables or using process variables
(reserved for this purpose) that you can read and write between the two processes (using
GET PROCESS VARIABLE and SET PROCESS VARIABLE).
To communicate between processes that do not display forms, use the commands GET
PROCESS VARIABLE and SET PROCESS VARIABLE.
In order not to slow down the execution of methods, 4th Dimension does not redraw
interprocess variables each time they are modified. If you pass -1 instead of a process
reference number in the process parameter, 4th Dimension does not call any process.
Instead, it redraws all the interprocess variables currently displayed in all windows of any
process running on the same machine.
Example
See example for On Exit Database Method.
See Also
Form event, GET PROCESS VARIABLE, SET PROCESS VARIABLE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
GET PROCESS VARIABLE (process; srcVar; dstVar{; srcVar2; dstVar2; ...; srcVarN; dstVarN})
Description
The GET PROCESS VARIABLE command reads the srcVar process variables (srvVar2, etc.)
from the source process whose number is passed in process, and returns their current
values in the dstVar variables ( dstVar2, etc.) of the current process.
Each source variable can be a variable, an array or an array element. However, see the
restrictions listed later in this section.
In each couple of srcVar;dstVar variables, the two variables must be of compatible types,
otherwise the values you obtain may be meaningless.
The current process “peeks” the variables from the source process—the source process is
not warned in any way that another process is reading the instance of its variables.
4D Server: Using 4D Client, you can write variables in a destination process executed on
the server machine (stored procedure). To do so, put a minus sign before the process ID
number in the process parameter.
“Intermachine” process communication, provided by the commands GET PROCESS
VARIABLE, SET PROCESS VARIABLE and VARIABLE TO VARIABLE, is possible from client to
server only. It is always a client process that reads or write the variables of a stored
procedure.
TIP: If you do not know the ID number of the server process, you can still use the
interprocess variables of the server. To do so, you can use any negative value in process. In
other words, it is not necessary to know the ID number of the process to be able to use
the Set process variable command with the interprocess variables of the server. This is
useful when a stored procedure is launched using the On server startup database method.
As clients machines do not automatically know the ID number of that process, any
negative value can be passed in the process parameter.
Restrictions
GET PROCESS VARIABLE does not accept local variables as source variables.
On the other hand, the destination variables can be interprocess, process or local
variables. You “receive” the values only into variables, not into fields.
The source process must be a user process; it cannot be a kernel process. If the source
process does not exist, this command has no effect.
Note: In interpreted mode, if a source variable does not exist, the undefined value is
returned. You can detect this by using the Type function to test the corresponding
destination variable.
Examples
1. This line of code reads the value of the text variable vtCurStatus from the process whose
number is $vlProcess. It returns the value in the process variable vtInfo of the current
process:
2. This line of code does the same thing, but returns the value in the local variable $vtInfo
for the method executing in the current process:
3. This line of code does the same thing, but returns the value in the variable vtCurStatus
of the current process:
Note: The first vtCurStatus designates the instance of the variable in the source process
The second vtCurStatus designates the instance of the variable in the current process.
4. This example sequentially reads the elements of a process array from the process
indicated by $vlProcess:
Note: In this example, the process variable vl_IPCom_Array contains the size of the array
at_IPCom_Array, and must be maintained by the source process.
6. This example reads the source process instances of the variables v1,v2,v3 and returns
their values in the instance of the same variables for the current process:
7. See the example for the command DRAG AND DROP PROPERTIES.
See Also
CALL PROCESS, Drag and Drop, DRAG AND DROP PROPERTIES, Processes, SET PROCESS
VARIABLE, VARIABLE TO VARIABLE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SET PROCESS VARIABLE (process; dstVar; expr{; dstVar2; expr2; ...; dstVarN; exprN})
Description
The SET PROCESS VARIABLE command writes the dstVar process variables (dstVar2, etc.)
of the destination process whose number is passed in process using the values passed in
expr1 (expr2, etc.).
Each destination variable can be a variable or an array element. However, see the
restrictions listed later in this section.
For each couple of dstVar;expr variables, the expression must be of a type compatible with
the destination variable, otherwise you may end up with a meaningless value in the
variable. In interpreted mode, if a destination variable does not exist, it is created and
assigned with the expression.
The current process “pokes” the variables of the destination process—the destination
process is not warned in any way that another process is writing the instance of its
variables.
4D Server: Using 4D Client, you can write variables in a destination process executed on
the server machine (stored procedure). To do so, put a minus sign before the process ID
number in the process parameter.
“Intermachine” process communication, provided by the commands GET PROCESS
VARIABLE, SET PROCESS VARIABLE and VARIABLE TO VARIABLE, is possible from client to
server only. It is always a client process that reads or write the variables of a stored
procedure.
TIP: If you do not know the ID number of the server process, you can still use the
interprocess variables of the server. To do so, use any negative value in process. In
other words, it is not necessary to know the ID number of the process to be able to use
the Set process variable command with the interprocess variables of the server. This is
useful when a stored procedure is launched using the On server startup database method.
As client machines do not automatically know the ID number of that process, any
negative value can be passed in the process parameter.
SET PROCESS VARIABLE accepts any type of destination process or interprocess variable,
except:
• Pointers
• Arrays of any type. To write an array as a whole from one process to another one, use
the command VARIABLE TO VARIABLE. Note, however, that SET PROCESS VARIABLE allows
you to write the element of an array.
• You cannot write the element of an array of pointers or the element of a two-
dimensional array.
The destination process must be a user process; it cannot be a kernel process. If the
destination process does not exist, an error is generated. You can catch this error using
an error-handling method installed with ON ERR CALL.
Examples
1. This line of code sets (to the empty string) the text variable vtCurStatus of the process
whose number is $vlProcess:
2. This line of code sets the text variable vtCurStatus of the process whose number is
$vlProcess to the value of the variable $vtInfo from the executing method in the current
process:
3. This line of code sets the text variable vtCurStatus of the process whose number is
$vlProcess to the value of the same variable in the current process:
Note: The first vtCurStatus designates the instance of the variable in the destination
process. The second vtCurStatus designates the instance of the variable in the current
process.
4. This example sequentially sets to uppercase all elements of a process array from the
process indicated by $vlProcess:
GET PROCESS VARIABLE($vlProcess;vl_IPCom_Array;$vlSize)
For($vlElem;1;$vlSize)
GET PROCESS VARIABLE($vlProcess;at_IPCom_Array{$vlElem};$vtElem)
⇒ SET PROCESS VARIABLE($vlProcess;at_IPCom_Array{$vlElem};Uppercase($vtElem))
End for
Note: In this example, the process variable vl_IPCom_Array contains the size of the array
at_IPCom_Array and must be maintained by the source/destination process.
See Also
CALL PROCESS, GET PROCESS VARIABLE, Processes, VARIABLE TO VARIABLE.
version 6.0.2
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
VARIABLE TO VARIABLE (process; dstVar; srcVar{; dstVar2; srcVar2; ...; dstVarN; srcVarN})
Description
The command VARIABLE TO VARIABLE writes the dstVar process variables (dstVar2, etc.) of
the destination process whose number is passed in process using the values of the
variables srcVar1 srcVar2, etc.
VARIABLE TO VARIABLE has the same action as SET PROCESS VARIABLE, with the following
differences:
• You pass source expressions to SET PROCESS VARIABLE, and therefore cannot pass an
array as a whole. You must exclusively pass source variables to VARIABLE TO VARIABLE, and
therefore can pass an array as a whole.
• Each destination variable of SET PROCESS VARIABLE can be a variable or an array
element, but cannot be an array as a whole. Each destination variable of VARIABLE TO
VARIABLE can be a variable or an array or an array element.
4D Server: “Intermachine” process communication, provided by the commands GET
PROCESS VARIABLE, SET PROCESS VARIABLE and VARIABLE TO VARIABLE, is possible from
client to server only. It is always a client process that reads or write the variables of a
stored procedure.
For each couple of dstVar;expr variables, the source variable must be of a type compatible
with the destination variable, otherwise you may end up with a meaningless value in the
variable. In interpreted mode, if a destination variable does not exist, it is created and
assigned with the type and value of the source variable.
The current process “pokes” the variables of the destination process—the destination
process is not warned in any way that another process is writing the instance of its
variables.
Restrictions
VARIABLE TO VARIABLE does not accept local variables as destination variables.
VARIABLE TO VARIABLE accepts any type of destination process or interprocess variables
except:
• Pointers
• Array of pointers
• Two-dimensional arrays
Example
The following example reads a process array from the process indicated by $vlProcess,
sequentially sets the elements to uppercase and then writes back the array as a whole:
GET PROCESS VARIABLE($vlProcess;at_IPCom_Array;$anArray)
For($vlElem;1;Size of array($anArray))
$anArray{$vlElem}:=Uppercase($anArray{$vlElem})
End for
⇒ VARIABLE TO VARIABLE($vlProcess;at_IPCom_Array;$anArray)
See Also
GET PROCESS VARIABLE, Processes, SET PROCESS VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
HIDE PROCESS hides all windows that belong to process. All interface elements of process
are hidden until the next SHOW PROCESS. The menu bar of the process is also hidden.
This means that opening a window while the process is hidden does not make the screen
redraw or display. If the process is already hidden, the command has no effect.
The only exception to this rule is the Debugger window. If the Debugger window is
displayed when process is a hidden process, process is displayed and becomes the
frontmost process.
If you do not want a process to be displayed when it is created, HIDE PROCESS should be
the first command in the process method. The User/Custom Menus and Cache Manager
processes cannot be hidden using this command.
Example
The following example hides all the windows belonging to the current process:
See Also
Process state, SHOW PROCESS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SHOW PROCESS displays all the windows belonging to process. This command does not
bring the windows of process to the frontmost level. To do this, use the BRING TO FRONT
command.
If the process was already displayed, the command has no effect.
Example
The following example displays a process called Customers, if it has been previously
hidden. The process reference to the Customers process is stored in the interprocess
variable <>Customers:
See Also
BRING TO FRONT, HIDE PROCESS, Process state.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
BRING TO FRONT brings all the windows belonging to process to the front. The order of
the windows is retained. If the process is already the frontmost process, the command
does nothing. If the process is hidden, you must use SHOW PROCESS to display the
process, otherwise BRING TO FRONT has no effect.
The User/Custom Menus and Design processes can be brought to the front using this
command.
Example
The following example is a method that can be executed from a menu. It checks to see if
<>vlAddCust_PID is the frontmost process. If not, the method brings it to the front:
If (Frontmost process#<>vlAddCust_PID)
⇒ BRING TO FRONT (<>vlAddCust_PID)
End if
See Also
HIDE PROCESS, Process state, SHOW PROCESS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Frontmost process returns the number of the process whose window (or windows) are in
the front.
When you have one or more floating windows open, there are two window layers:
• Regular windows
• Floating windows
If the Frontmost process function is used from within a floating window form method or
object method, the function returns the process reference number of the frontmost
floating window in the floating window layer. If you specify the optional * parameter, the
function returns the process reference number of the frontmost active window in the
regular window layer.
Example
See the example for BRING TO FRONT.
See Also
BRING TO FRONT, WINDOW LIST.
Processes
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Multi-tasking in 4th Dimension is the ability to have distinct database operations that are
executed simultaneously. These operations are called processes.
Multiple processes are like multiple users on the same computer, each working on his or
her own task. This essentially means that each method can be executed as a distinct
database task.
Note: This section does not cover stored procedures. See the section Stored Procedures in
the 4D Server Reference manual.
A process can be cleared under the following conditions. The first two conditions are
automatic:
• When the process method finishes executing
• When the user quits from the database
• If you stop the process procedurally or use the Abort button in the Debugger
• If you choose Abort from the Process menu in the Design environment
A process can create another process. Processes are not organized hierarchically—all
processes are equal, regardless of the process from which they have been created. Once
the “parent” process creates a “child” process, the child process will continue regardless of
whether or not the parent process is still executing.
Each process contains specific elements. There are three types of distinctly different
elements in a process:
• Interface elements: Elements that are necessary to display a process.
• Data elements: Information that is related to the data in the database.
• Language elements: Elements that are used procedurally or are that are important for
developing your own application.
Interface Elements
Interface elements consist of the following:
• Menu bar: Each process can have its own current menu bar. The menu bar of the
frontmost process is the current menu bar for the database.
• One or more windows: Each process can have more than one window open
simultaneously. On the other hand, some processes have no windows at all.
• One active (frontmost) window: Even though a process can have several windows open
simultaneously, each process has only one active window. To have more than one active
window, you must start more than one process.
Data Elements
Data elements refer to the data used by the database. The data elements are:
• Current selection per table: Each process has a separate current selection. One table can
have a different current selection in different processes.
• Current record per table: Each table can have a different current record in each process.
Note: This description of the data elements is valid if your processes are global in scope.
By default, all processes are global. See the “Global and Local Processes” section below.
Language Elements
The language elements of a process are the elements related to programming in
4th Dimension.
• Variables: Every process has its own process variables. See Variables for more
information. Process variables are recognized only within the domain of their native
process.
• Default table: Each process has its own default table. However, note that the DEFAULT
TABLE command is only a typing convention for programming.
• Input and Output forms: Default input and output forms can be set procedurally for
each table in each process.
• Process sets: Each process has its own process sets. UserSet and LockedSet are process sets.
Process sets are cleared as soon as the process method ends.
• On Error Call per process: Each process has its own error-handling method.
• Debugger window: Each process can have its own Debugger window.
User processes are processes that you create to perform certain tasks. They share
processing time with the kernel processes. As an example, Web connection processes are
user processes.
Processes can be either global or local in scope. By default, all processes are global.
Global processes can perform any operation, including accessing and manipulating data.
In most cases, you will want to use global processes.
Local processes should be used only for operations that do not access data. For example,
you can use a local process to run an event-handling method or to control interface
elements such as floating windows.
You specify that a process is local in scope through its name. The name of local process
must start with a dollar sign ($).
4D Server: Using local processes on the Client side for operations that do not require data
access reserves more processing time for server-intensive tasks.
A record is locked when another process has successfully loaded the record for
modification. A locked record can be loaded by another process, but cannot be modified.
The record is unlocked only in the process in which the record is being modified. A table
must be in read/write mode for a record to be loaded unlocked.
See Also
Methods, Project Methods, Variables.
New process (method; stack{; name{; param{; param2; ...; paramN}{; *}}}) → Number
Description
The command New process starts a new process (on the same machine) and returns the
process number for that process.
If the process could not be created (for example, if there is not enough memory), New
process returns zero (0) and an error is generated. You can catch this error using an error-
handling method installed using ON ERR CALL.
Process Method: In method, you pass the name of the process method for the new
process. After 4D has set up the context for the new process, it starts executing this
method, which therefore becomes the process method.
Process Stack: In stack, you pass the amount of memory allocated for the stack of the
process. It is the space in memory used to “pile up” method calls, local variables,
parameters in subroutines, and stacked records. It is expressed in bytes; you will usually
pass at least 32K (around 32000 bytes), but you can pass more if the process can perform
large chain calls (subroutines calling subroutines in cascade). For example, you can pass
200K (around 200000 bytes), if necesary.
Note: The stack is NOT the total memory for the process. Processes share memory for
records, interprocess variables, and so on. A process also uses extra memory for storing its
process variables. The stack contains various 4D informations ; the amount of
information kept on the stack depends on the number of nested methods calls the
process will employ, the number of forms that it will open before closing them and the
number and size of local variables used in each nested method call.
Important: Remember that local processes should not access data in Client/Server.
Parameter to Process Method: Starting with version 6, you can pass parameters to the
process method. You can pass parameters in the same way as you would pass them to a
subroutine. However, there is a restriction—you cannot pass pointer expressions. Also,
remember that arrays cannot be passed as parameters to a method. Upon starting
execution in the context of the new process, the process method receives the parameters
values in $1, $2, etc.
Note: If you pass parameters to the process method, you must pass the name parameter; it
cannot be omitted in this case.
The optional * parameter: Specifying this last parameter tells 4D to first check whether or
not a process with the name you passed in name is already running. If it is, 4D does not
start a new process and returns the process number of the process with that name.
Example
Given the following project method:
` ADD CUSTOMERS
MENU BAR (1)
Repeat
ADD RECORD([Customers];*)
Until (OK=0)
If you attach this project method to a custom menu item in the Design environment
Menu Bar Editor window whose Start a New Process property is set, 4D will automatically
start a new process running that method. The call MENU BAR(1) adds a menu bar to the
new process. In the absence of any window (that you could open with Open window), the
call to ADD RECORD will automatically open one.
To be able to start this Add Customers process when you click on a button in a custom
control panel, you can write:
` bAddCustomers button object method
⇒ $vlProcessID:=New process("Add Customers";32*1024;"Adding Customers")
The button does the same thing as the custom menu item.
In the Menu Bar editor, you replace the method ADD CUSTOMERS with the method
START ADD CUSTOMERS, and you deselect the Start a New Process property for the menu
item.
See Also
Execute on server, Methods, Processes, Project Methods, Variables.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Execute on server (procedure; stack{; name{; param{; param2; ...; paramN}{; *}}}) → Number
Description
The command Execute on server starts a new process on the Server machine (if it is called
in Client/Server) or on the same machine (if it is called in single-user) and returns the
process number for that process.
You use Execute on server to start a stored procedure. For more information about stored
procedures, see the section Stored Procedures in the 4D Server Reference manual.
If you call Execute on server on a Client machine, the command returns a negative
process number. If you call Execute on server on the Server machine, Execute on server
returns a positive process number. Note that calling New process on the Server machine
does the same thing as calling Execute on server.
If the process could not be created (for example, if there is not enough memory), Execute
on server returns zero (0) and an error is generated. You can catch this error using an
error-handling method installed using ON ERR CALL.
Process Method: In method, you pass the name of the process method for the new
process. After 4D has set up the context for the new process, it starts executing this
method, which therefore becomes the process method.
Process Stack: In stack, you pass the amount of memory allocated for the stack of the
process. It is the space in memory used to “pile up” method calls, local variables,
parameters in subroutines, and stacked records. It is expressed in bytes; you will usually
pass at least 32K (around 32000 bytes), but you can pass more if the process can perform
large chain calls (subroutines calling subroutines in cascade). For example, you can pass
200K (around 200000 bytes), if necesary.
Process Name: You pass the name of the new process in name. In single-user, this name
will appear in the Process List window of the Design environment, and will be returned
by the command PROCESS PROPERTIES when applied to this new process. In
Client/Server, this name will appear in blue in the Stored Procedure list of the 4D Server
main window.
A process name can be up to 31 characters long. You can omit this parameter; if you do
so, the name of the process will be the empty string.
Warning: Contrary to New Process, do not attempt to make a process local in scope by
prefixing its name with the dollar sign ($) while using Execute on server. This will work in
single-user, because Execute on server acts as New Process in this environment. On the
other hand, in Client/Server, this will generate an error.
Parameter to Process Method: Starting with version 6, you can pass parameters to the
process method. You can pass parameters in the same way as you would pass them to a
subroutine. However, there is a restriction—you cannot pass pointer expressions. Also,
remember that arrays cannot be passed as parameters to a method. Upon starting
execution in the context of the new process, the process method receives the parameters
values in $1, $2, etc.
Note: If you pass parameters to the process method, you must pass the name parameter; it
cannot be omitted in this case.
The optional * parameter: Specifying this last parameter tells 4D to first check whether or
not a process with the name you passed in name is already running. If it is, 4D does not
start a new process and returns the process number of the process with that name.
Example
(1) The following example shows how importing data can be dramatically accelerated in
Client/Server. The Regular Import method listed below allows you to test how long it takes
to import records using the IMPORT TEXT command on the Client side:
` Regular Import Project Method
$vhDocRef:=Open document("")
If (OK=1)
CLOSE DOCUMENT($vhDocRef)
INPUT FORM([Table1];"Import")
$vhStartTime:=Current time
IMPORT TEXT([Table1];Document)
$vhEndTime:=Current time
ALERT("It took "+String(0+($vhEndTime-$vhStartTime))+" seconds.")
End if
C_POINTER($1)
C_STRING(31;$2)
C_TIME($vhDocRef)
C_BLOB($vxData)
C_LONGINT(spErrCode)
spErrCode:=1
End if
Until (spErrCode<=0)
C_LONGINT($1)
C_STRING(31;$2)
C_BLOB($3)
C_LONGINT(spErrCode)
Once these two project methods have been implemented in a database, you can perform a
“Stored Procedure-based” import data by, for instance, writing:
CLIENT IMPORT (->[Table1];"Import")
With some benchmarks you will discover that using this method you can import records
up to 60 times faster than the regular import.
See Also
New process, Stored Procedures.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DELAY PROCESS delays the execution of a process for a number of ticks (1 tick = 1/60th of
a second). During this period, process does not take any processing time. Even though
the execution of a process may be delayed, it is still in memory.
If the process is already delayed, this command delays it again. The parameter duration is
not added to the time remaining, but replaces it. Therefore pass zero (0) for duration if
you no longer want to delay a process.
Warning: DELAY PROCESS has no effect on the Kernel processes (all environments),
including the User/Custom Menus process.
Tip: To “delay” the User/Custom Menus process, write a small “waiting” subroutine that
loops measuring the elasped time using Current time, or Tickcount or Milliseconds). For
example, if you want to display, for a given time period, a message in a window that you
open and close for this purpose.
Examples
1. See example in Record Locking.
2. See example for the command Process number.
See Also
HIDE PROCESS, PAUSE PROCESS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PAUSE PROCESS suspends the execution of process until it is reactivated by the RESUME
PROCESS command. During this period, process does not take any time on your machine.
Even though a process may be paused, the process is still in memory.
If process is already paused, PAUSE PROCESS does nothing. If the process has been delayed
using the DELAY PROCESS command, the process is paused. RESUME PROCESS resumes the
process immediately.
While process execution is suspended, the windows belonging to this process are not
enterable. In this case, to avoid confusing the user, consider hiding the process. If process
does not exist, the command does nothing.
Warning: Use PAUSE PROCESS only in processes that you have started. PAUSE PROCESS will
not affect the original User/Custom Menus process.
See Also
DELAY PROCESS, HIDE PROCESS, RESUME PROCESS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
RESUME PROCESS resumes a process whose execution has been paused or delayed. If
process is not paused or delayed, RESUME PROCESS does nothing.
If process has been delayed before, see the PAUSE PROCESS or DELAY PROCESS commands.
If process does not exist, the command does nothing.
See Also
DELAY PROCESS, PAUSE PROCESS.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Process aborted returns True if the process in which it is called is about to
be interrupted unexpectedly, which means that the execution of the command was
unable to reach its “normal” completion. For example, this can occur after calling QUIT
4D.
Example
This command can be used as a particular type of programming on the Web server, only
in compiled mode. When you use a method to send Web pages by using a loop like
While...End while (cf. example), the mechanism of the Web server doesn’t allow you to
stop the loop in case of a timeout (end of the inactivity period authorized) on a Web
browser. If the Web process is not closed, a context is therefore still in use.
The Process aborted command, placed in the initial test of the loop, will return True in
case of a timeout. The loop can then be interrupted and the process can be aborted.
Here is a method that can be used to send HTML pages. In compiled mode, this loop
cannot be interrupted in case of a timeout:
While (True)
SEND HTML FILE (HTMLFile)
End while
The Process aborted command allows you to use the same type of method, while still
being able to exit the loop and abort the Web process in case of a timeout:
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Current process returns the process reference number of the process within which this
command is called.
Example
See the examples for DELAY PROCESS and PROCESS PROPERTIES.
See Also
Process number, PROCESS PROPERTIES, Process state.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Process state returns the state of the process whose number you pass in
process.
The function result can be one of the values provided by the following predefined
constants:
Constant Type Value
Aborted Long Integer -1
Delayed Long Integer 1
Does not exist Long Integer -100
Executing Long Integer 0
Hidden modal dialog Long Integer 6
Paused Long Integer 5
Waiting for input output Long Integer 3
Waiting for internal flag Long Integer 4
Waiting for user event Long Integer 2
If the process does not exist (which means you did not pass a number in the range 1 to
Count tasks), Process state returns Does not exist (-100).
$vlNbTasks:=Count tasks
ARRAY STRING(31;arProcName; $vlNbTasks)
ARRAY INTEGER(aiProcNum; $vlNbTasks)
$vlActualCount:=0
For ($vlProcess;1; $vlNbTasks)
If (Process state($vlProcess)>=Executing)
$vlActualCount:=$vlActualCount+1
PROCESS PROPERTIES($vlProcess; asProcName{$vlActualCount};
$vlState;$vlTime)
aiProcNum{$vlActualCount}:=$vlProcess
End if
End for
` Eliminate unused extra elements
ARRAY STRING(31;asProcName;$vlActualCount)
ARRAY INTEGER(aiProcNum;$vlActualCount)
See Also
Count tasks, PROCESS PROPERTIES.
Description
The command PROCESS PROPERTIES returns information about the process whose process
number you pass in process.
If the process does not exist, which means you did not pass a number in the range 1 to
Count tasks, PROCESS PROPERTIES leaves the variable parameters unchanged.
Examples
1. The following example returns the name, state, and time taken in the variables vName,
vState, and vTimeSpent for the current process:
C_STRING(80; vName) ` Initialize the variables
C_INTEGER(vState)
C_INTEGER(vTime)
PROCESS PROPERTIES (Current process; vName; vState; vTimeSpent)
See Also
Count tasks, Process state.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Process number returns the number of the process whose name you pass in name. If no
process is found, Process number returns 0.
The optional parameter * allows you to retrieve, from 4D Client, the process ID of a
process that is executed on the server (a stored procedure). In this case, the returned value
is negative. This option is especially useful when using the PROCESS VARIABLE and SET
PROCESS VARIABLE commands. Please refer to the descriptions of these commands for
details.
If the command is executed with the * parameter from a process on the server machine,
the returned value is positive.
Example
You create a custom floating window, run in a separate process, in which you implement
your own tools to interact with the Design environment. For example, when selecting an
item in a hierarchical list of keywords, you want to paste some text into the frontmost
window of the Design environment. To do so, you can use the clipboard, but the pasting
event must occur within the Design process. The following small function returns the
process number of the Design process (if running):
` Design process number Project Method
` Design process number -> LongInt
` Design process number -> Design process number
C_TEXT($1)
C_LONGINT($vlDesignPID;$vlCount)
See Also
GET PROCESS VARIABLE, PROCESS PROPERTIES, Process state, SET PROCESS VARIABLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Count users function returns the number of users connected to the database. If the
server executes any stored procedure(s), Count users returns the number of users + 1.
See Also
Count tasks, Count user processes.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Count tasks returns the number of processes open in 4D Client, 4D Server (stored
procedures) or in single-user 4th Dimension.
This number takes into account all processes, even those that are automatically managed
by 4th Dimension. These include the User/Custom Menus process, Design process, Cache
Manager process, Indexing process, and Web Server process.
The number returned by Count tasks also takes into account processes that have been
aborted.
Example
See the example for Process state and On Exit Database Method.
See Also
Count user processes, Count users, PROCESS PROPERTIES, Process state.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Count user processes function returns the number of open processes, except those
processes that are managed automatically by 4th Dimension.
The User/Custom Menus process, the Design process and the Web server process are
considered to be user processes since they can be closed by users. Therefore, these
processes will be counted when determining the number of user processes.
See Also
Count tasks, Count users.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command EXECUTE ON CLIENT forces the execution of the methodName method,
with the parameters param1... paramN, if necessary, on the registered 4D Client whose
name is clientName. 4D Client’s registered name is defined by the REGISTER CLIENT
command.
This command can be called from a 4D Client or a stored method from 4D Server.
If the method requires one or more parameters, pass them after the name of the method.
The execution of the method on 4D Client is done in a global process automatically
created on the client workstation, and its name will be the 4D Client’s registered name.
If this command is called many times in a row on the same 4D Client, the execution
orders will be stacked. Therefore, the methods will be treated one after another in
asynchronous mode. The more methods that are stacked, the bigger the workload is for
the 4D Client. You can know the state of the workload of each client by using the GET
REGISTERED CLIENTS command.
Note: The stacking of the execution orders cannot be modified or stopped unless 4D
Client is unregistered by using the UNREGISTER CLIENT command.
You can simultaneously execute the same method on many or all of the registered 4D
Clients. To do so, use the wildcard character (@) in the clientName parameter.
The OK system variable is equal to 1 if 4D Server has correctly received the execution
request of a method; however, this does not guarantee that the method has been properly
executed by 4D Client.
Examples
(1) Let’s assume that you want to execute the “GenerateNums” method on the “Client1”
client station:
⇒ EXECUTE ON CLIENT("Client1";"GenerateNums";12;$a;"Text")
⇒ EXECUTE ON CLIENT("@";"EmptyTemp")
See Also
GET REGISTERED CLIENTS, REGISTER CLIENT, UNREGISTER CLIENT.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command REGISTER CLIENT “registers” a 4D Client station with the name specified in
clientName on 4D Server, so as to allow other clients or eventually 4D Server (by using
stored methods) to execute methods on it by using the EXECUTE ON CLIENT command.
Once it is registered, a 4D Client can then execute one or more methods for other clients.
Note: You can also automatically register each client station that connects to 4D Server
by using the “Register clients at startup” option in the Database properties dialog box.
When this command is executed, a process, named clientName, is created on the client
station. This process can only be aborted by the UNREGISTER CLIENT command.
If you pass the optional * parameter, the created process is local. 4D will automatically add
the dollar sign ($) at the beginning of the process name. Else, the process is global.
After executing the command, the client station will periodically ask 4D Server to see if
another 4D Client or the server itself is calling it.
By default, this interrogation is done every two seconds. You can modify this time period
by modifying period. The minimum value is one second.
Note: If this command is used with a single-user version of 4th Dimension, it has no
effect.
Once the command is executed, it is not possible to modify 4D Client’s name or the
server’s interrogation period on the fly. To do so, you must call the UNREGISTER CLIENT
command, then the REGISTER CLIENT command.
Note: More than one 4D Client can have the same registered name.
2) The following instruction allows you to get a list of the registered 4D Clients. It can be
placed in the On Startup Database Method:
PrClientList:=New process("4D Client List";32000;"List of registered clients")
3) The method 4D Client List allows you to recuperate all the registered 4D Clients and
those that can receive messages:
If (Application type=4D Client)
` the code below is only valid in client-server mode
$Ref:=Open window(100;100;300;400;-(Palette window+Has window title);"List of
registered clients")
Repeat
GET REGISTERED CLIENTS($ClientList;$ListeCharge)
`Retrieve the registered clients in $ClientList
ERASE WINDOW($Ref)
GOTO XY(0;0)
For ($p;1;Size of array($ClientList))
MESSAGE($ClientList{$p}+Char(Carriage return))
End for
`Display each second
DELAY PROCESS(Current process;60)
Until (False) ` Infinite loop
End if
6) Finally, this method allows a client station to no longer be visible by the other 4D
Clients and to no longer receive messages:
⇒ UNREGISTER CLIENT
See Also
EXECUTE ON CLIENT, GET REGISTERED CLIENTS, UNREGISTER CLIENT.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
UNREGISTER CLIENT
Description
The command UNREGISTER CLIENT “unregisters” a 4D Client station. The client must
have already been registered by the REGISTER CLIENT command.
Note: A 4D Client is automatically unregistered when the user quits the application.
If the client workstation was not previously registered or if the command was executed
on a single-user 4th Dimension, the command has no effect.
If the client is correctly unregistered, the OK system variable is equal to 1. If the client
wasn’t registered, OK is equal to 0.
Example
Refer to the example for the REGISTER CLIENT command.
See Also
EXECUTE ON CLIENT, GET REGISTERED CLIENTS, REGISTER CLIENT.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET REGISTERED CLIENTS fills two arrays:
• clientLists contains the list of clients who were “registered” by using the REGISTER
CLIENT command.
• methods supplies the list of each client’s “workload”. The workload is the number of
methods that a 4D Client must still execute by calling the EXECUTE ON CLIENT command
(for more information, please refer to the description of the EXECUTE ON CLIENT
command).
Examples
(1) Let’s assume that you want to obtain a list of all the registered clients and the
methods that remain to be executed:
ARRAY TEXT($clients;0)
ARRAY LONGINT($methods;0)
⇒ GET REGISTERED CLIENTS($clients;$methods)
See Also
EXECUTE ON CLIENT, REGISTER CLIENT, UNREGISTER CLIENT.
Queries
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY BY EXAMPLE performs the same action as the Query by Example menu command
in the User environment. It displays the current input form as a query window.
QUERY BY EXAMPLE queries table for the data that the user enters into the query window.
The form must contain the fields that you want the user to be able to query. The query is
optimized; indexed fields are automatically used to optimize the query.
See the 4th Dimension User Reference for information about using the Query by Example
menu command in the User environment.
Example
The method in this example displays the MyQuery form to the user. If the user accepts
the form and performs the query (that is, if the OK system variable is set to 1), the
records that meet the query criteria are displayed:
INPUT FORM ([People]; "MyQuery") ` Switch to query form
⇒ QUERY BY EXAMPLE ([People]) ` Display form and perform query
If (OK=1) ` If the user performed the query
DISPLAY SELECTION ([People]) ` Display the records
End if
See Also
ORDER BY, QUERY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY looks for records matching the criteria specified in queryArgument and returns a
selection of records for table. QUERY changes the current selection of table for the current
process and makes the first record of the new selection the current record.
If the table parameter is omitted, the command applies to the default table. If no default
table has been set, an error occurs.
If you do not specify queryArgument or the * parameters, QUERY displays the Query editor
for table. The User environment Query editor is shown here:
For more information about using the Query Editor, refer to the 4th Dimension User
Reference manual.
Examples
1. The following line displays the Query editor for the [Products] table:
⇒ QUERY([Products])
2. The following line displays the Query editor for the default table (if it has been set)
⇒ QUERY
If you specify the queryArgument parameter, the standard Query editor is not presented
and the query is defined programmatically. For simple queries (search on only one field)
you call QUERY once with queryArgument. For multiple queries (search on multiple fields
or with multiple conditions), you call QUERY as many times as necessary with
queryArgument, and you specify the optional * parameter, except for the last QUERY call,
which starts the actual query operation. The queryArgument parameter is described further
in this section.
Examples
3. The following line looks for the [People] whose name starts with an “a”:
⇒ QUERY([People];[People]Last name="a@")
4. The following line looks for the [People] whose name starts with “a” or “b”:
• The conjunction is used to join QUERY calls when defining multiple queries. The
conjunctions available are the same as those in the User environment Query editor:
Conjunction Symbol to use with QUERY
AND &
OR |
Except #
The conjunction is optional and not used for the first QUERY call of a multiple query, or if
the query is a simple query.
• The comparator is the comparison that is made between field and value. The comparator
is one of the symbols shown here:
Comparison Symbol to use with QUERY
Equal to =
Not equal to #
Less than <
Greater than >
Less than or equal to <=
Greater than or equal to >=
• The value is the data against which field will be compared. The value can be any
expression that evaluates to the same data type as field. The value is evaluated once, at the
beginning of the query. The value is not evaluated for each record. To query for a string
contained in a string (a “contains” query), use the wildcard symbol (@) in value.
Note: Each table maintains its own current built query. This means that you can create
multiple built queries simultaneously, one for each table. You must use the table
parameter or set the default table to specify which table to use.
• If any indexed fields are specified, the query is optimized every time that it is possible
(indexed fields are searched first) resulting in a query that takes the least amount of time
possible.
⇒ QUERY([People];[People]Last Name="Smith")
Note: If the Last Name field were indexed, the QUERY command would automatically use
the index for a fast query.
Reminder: This query will find records like “Smith”, “smith”,“SMITH”, etc. To distinguish
lowercase from uppercase, perform additional queries using the ASCII codes.
6. The following example finds the records for all people named John Smith. The Last
Name field is indexed. The First Name field is not indexed.
⇒ QUERY ([People]; [People]Last Name = "smith"; *) ` Find every person named Smith
⇒ QUERY ([People]; &; [People]First Name = "john") ` with John as first name
When the query is performed, it quickly does an indexed search on Last Name and
reduces the selection of records to those of people named Smith. The query then
sequentially searches on First Name in this selection of records.
7. The following example finds the records of people named Smith or Jones. The Last
Name field is indexed.
The QUERY command uses the Last Name index for both queries. The two queries are
performed, and their results put into internal sets that are eventually combined using a
union.
8. The following example finds the records for people who do not have a company name.
It does this by finding entries with empty fields (the empty string).
9. The following example finds the record for every person whose last name is Smith and
who works for a company based in New York. The second query uses a field from another
table. This query can be done because the [People] table is related to the [Company] table
with a many to one relation:
⇒ QUERY ([People]; [People]Last Name = "smith"; *) ` Find every person named Smith…
⇒ QUERY ([People]; & ; [Company]State = "NY") ` ... and who works for a
company based in NY
11. The following example finds the records for all the people living in the San Francisco
or Los Angeles areas (ZIP codes beginning with 94 or 90):
⇒ QUERY ([People]; [People]ZIP Code = "94@"; *) ` Find every person in the SF…
⇒ QUERY ([People]; | ; [People]ZIP Code = "90@") ` ...or Los Angeles areas
12. The following example queries an indexed subfield. The query returns a selection of
parent records (records for the [People] table). It does not return a selection of subrecords.
The result of the query would be the selection of records for all the people who have a
child named Sabra:
⇒ QUERY ([People]; [People]Children'Name= "Sabra") `Find people with child named Sabra
13. The following example finds the record that matches the invoice reference entered in
the request dialog box:
vFind:=Request("Find invoice reference:") ` Get an invoice reference from the user
If (OK = 1) ` If the user pressed OK
⇒ QUERY([Invoice]; [Invoice]Ref = vFind) `Find the invoice reference that matches vFind
End if
14. The following example finds the records for the invoices entered in 1996. It does this
by finding all records entered after 12/31/95 and before 1/1/97:
⇒ QUERY ([Invoice]; [Invoice]In Date > !12/31/95!; *) ` Find invoices after 12/31/95…
⇒ QUERY ([Invoice]; &; [Invoice]In Date < !1/1/97!) ` and before 1/1/97
15. The following example finds the record for each employee whose salary is between
$10,000 and $50,000. The query includes the employees who make $10,000, but excludes
those who make $50,000:
17. The following example queries for information that was entered into the variable
myVar.
⇒ QUERY ([Laws]; [Laws]Text = myVar) ` Find all laws that match myVar
The query could have many different results, depending on the value of myVar. The query
will also be performed differently. For example:
• If myVar equals "Copyright@", the selection contains all laws with texts beginning with
Copyright.
• If myVar equals "@Copyright@", the selection contains all laws with texts containing at
least one occurrence of Copyright.
See Also
QUERY SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY SELECTION looks for records in table. QUERY SELECTION command changes the
current selection of table for the current process and makes the first record of the new
selection the current record.
QUERY SELECTION works and performs the same actions as QUERY. The difference
between the two commands is the scope of the query:
• QUERY looks for records among all the records in the table.
• QUERY SELECTION looks for records among the records currently selected in the table.
Example
This example illustrates the difference between QUERY and QUERY SELECTION. Here are
two queries:
` Find ALL companies located in New York City
QUERY ([Company]; [Company]City="New York City")
` Find ALL companies doing Stock Exchange business
` no matter where they are located
QUERY ([Company]; [Company]Type Business="Stock Exchange")
Note that the second QUERY simply “ignores” the result of the first one. Compare this
with:
` Find ALL companies located in New York City
QUERY ([Company]; [Company]City="New York City")
` Find companies doing Stock Exchange business
` and that are located in New York City
QUERY SELECTION ([Company]; [Company]Type Business="Stock Exchange")
See Also
QUERY, SET DATABASE PARAMETER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY BY FORMULA looks for records in table. QUERY BY FORMULA changes the current
selection of table for the current process and makes the first record of the new selection
the current record.
QUERY BY FORMULA and QUERY SELECTION BY FORMULA work exactly the same way,
except that QUERY BY FORMULA queries every record in the entire table and QUERY
SELECTION BY FORMULA queries only the records in the current selection.
Both commands apply queryFormula to each record in the table or selection. The
queryFormula is a Boolean expression that must evaluate to either TRUE or FALSE. If
queryFormula evaluates as TRUE, the record is included in the new selection.
When the query is complete, the first record of the new selection is loaded from disk and
made the current record.
These commands always perform a sequential search, not an indexed search. QUERY BY
FORMULA and QUERY SELECTION BY FORMULA are slower than QUERY when used on
indexed fields. The query time is proportional to the number of records in the table or
selection.
4D Server: The server does not execute the query formula. Each record is sent to the local
workstation and the query formula is evaluated on the workstation. This makes the
command less efficient with 4D Server than the QUERY command.
2. The following example finds records for all the people who have names with more
than ten characters:
` Find names longer than ten characters
⇒ QUERY BY FORMULA ([People]; Length ([People]Name)>10)
See Also
QUERY, QUERY SELECTION, QUERY SELECTION BY FORMULA.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY SELECTION BY FORMULA looks for records in table. QUERY SELECTION BY FORMULA
changes the current selection of table for the current process and makes the first record of
the new selection the current record.
QUERY SELECTION BY FORMULA performs the same actions as QUERY BY FORMULA. The
difference between the two commands is the scope of the query:
• QUERY BY FORMULA looks for records among all the records in the table.
• QUERY SELECTION BY FORMULA looks for records among the records currently selected
in the table.
For more information, see the description of the command QUERY BY FORMULA.
See Also
QUERY, QUERY BY FORMULA, QUERY SELECTION.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command QUERY WITH ARRAY searches all the records for which the value of
indexedField is equal, at least, to one of the values of the elements in array. The records
found will become the new current selection.
This command allows you to quickly and simply build a search on multiple values.
Notes:
• This command only works with indexed fields. It cannot be used with fields of type
Text, Picture, Subfield, or BLOB.
• Remember that an array of type Longint is compatible with fields of type Time.
Example
The following example allows you to retrieve the records of both French and American
clients:
ARRAY STRING (2;SearchArray;30)
SearchArray{1}:="FR"
SearchArray{2}:="US"
⇒ QUERY WITH ARRAY ([Clients]Country;SearchArray)
Description
SET QUERY DESTINATION enables you to tell 4th Dimension where to put the result of any
subsequent query for the current process.
You specify the type of the destination in the parameter destinationType. 4th Dimension
provides the following predefined constants:
Constant Type Value
Into current selection Long Integer 0
Into set Long Integer 1
Into named selection Long Integer 2
Into variable Long Integer 3
You specify the destination of the query itself in the optional destinationObject parameter
according to the following table:
destinationType destinationObject
parameter parameter
0 (current selection) You omit the parameter
1 (set) You pass the name of a set (existing or to be created)
2 (named selection) You pass the named of a named selection (existing or to be created)
3 (variable) You pass a numeric variable (existing or to be created)
• With:
SET QUERY DESTINATION(Into current selection)
The records found by any subsequent query will end up in a new current selection for the
table involved by the query.
Warning: SET QUERY DESTINATION affects all subsequent queries made within the current
process. REMEMBER to always counterbalance a call to SET QUERY DESTINATION (where
destinationType#0) with a call to SET QUERY DESTINATION(0) in order to restore normal
query mode.
SET QUERY DESTINATION changes the behavior of the query commands only:
• QUERY
• QUERY SELECTION
• QUERY BY EXAMPLE
• QUERY BY FORMULA
• QUERY SELECTION BY FORMULA
• QUERY WITH ARRAY
On the other hand, SET QUERY DESTINATION does not affect other commands that may
change the current selection of a table such as ALL RECORDS, RELATE MANY and so on.
In your application, the [Phone Book] table contains a set of quite static data, so you do
not want to (or need to) perform a query each time you select a Tab. In this way, you can
save precious database engine time.
To do so, you can redirect your queries into named selections that you reuse as needed.
You write the object method of the Tab Control asRolodex as follows:
` asRolodex object method
Case of
: (Form event=On Load)
` Before the form appears on the screen,
` initialize the rolodex and a array of booleans that
` will tell us if a query for the corresponding letter
` has been performed or not
ARRAY STRING(1;asRolodex;26)
ARRAY BOOLEAN(abQueryDone;26)
For ($vlElem;1;26)
asRolodex{$vlElem}:=Char(64+$vlElem)
abQueryDone{$vlElem}:=False
End for
2. The Unique values project method in this example allows you to verify the uniqueness
of the values for any number of fields in a table. The current record can be an existing or
a newly created record.
` Unique values project method
` Unique values ( Pointer ; Pointer { ; Pointer... } ) -> Boolean
` Unique values ( ->Table ; ->Field { ; ->Field2... } ) -> Yes or No
C_BOOLEAN($0;$2)
C_POINTER(${1})
C_LONGINT($vlField;$vlNbFields;$vlFound;$vlCurrentRecord)
$vlNbFields:=Count parameters-1
$vlCurrentRecord:=Record number($1->)
If ($vlNbFields>0)
If ($vlCurrentRecord#-1)
If ($vlCurrentRecord<0)
` The current record is an unsaved new record (record number is -3)
` therefore we can stop the query as soon as at least one record is found
SET QUERY LIMIT(1)
Else
` The current record is an existing record,
` therefore we can stop the query as soon as at least two records are found
SET QUERY LIMIT(2)
End if
` The query will return its result in $vlFound
` without changing the current record nor the current selection
⇒ SET QUERY DESTINATION(Into variable;$vlFound)
` Make the query according to the number of fields that are specified
Case of
: ($vlNbFields=1)
QUERY($1->;$2->=$2->)
: ($vlNbFields=2)
QUERY($1->;$2->=$2->;*)
QUERY($1->; & ;$3->=$3->)
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET QUERY LIMIT allows you to tell 4th Dimension to stop any subsequent query for the
current process as soon as at least the number of records you pass in limit has been found.
For example, if you pass limit equal to 1, any subsequent query will stop browsing an index
or the data file as soon as one record that matches the query conditions has been found.
To restore queries with no limit, call SET QUERY LIMIT again with limit equal to 0.
Warning: SET QUERY LIMIT affects all the subsequent queries made within the current
process. REMEMBER to always counterbalance a call to SET QUERY LIMIT(limit) (where
limit>0) with a call to SET QUERY LIMIT(0) in order to restore queries with no limit.
On the other hand, SET QUERY LIMIT does not affect the other commands that may
change the current selection of a table, such as ALL RECORDS, RELATE MANY, and so on.
Examples
1. To perform a query corresponding to the request “...give me any ten customers whose
gross sales are greater than $1 M...”, you would write:
2. See the second example for the command SET QUERY DESTINATION.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Find index key returns the number of the first record whose indexedArray
field is equal to value.
If no records are found, Find index key returns -1.
After calling this command, value contains the value found. This feature allows you to
execute searches using the wildcard character (“@”) on Alpha fields and then retrieve the
value found.
This command doesn’t modify the current selection or the current record.
This command is fast because it only uses the index, and is particularly useful to prevent
creating double entries during data entry.
Example
In an audio CD database, during data entry let’s assume that you want to verify the
singer’s name to see if it already exists in the database. Because homonyms can exist, you
don’t want the [Singer]Name field to be unique. Therefore, in the input form, you can
write the following code in the [Singer]Name field’s object method:
If (Form event=On Data Change)
⇒ $RecNum:=Find index key([Singer]Name;[Singer]Name)
If ($RecNum # -1) ` If this name has already been entered
CONFIRM("A singer with the same already exists. Do you want to see the
record?";"Yes";"No")
If (OK=1)
GOTO RECORD([Singer];$RecNum)
End if
End if
End if
version 5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
ORDER BY ({table}{; field}{; > or <}{; field2; > or <2; ...; fieldN; > or <N}{; *})
Description
ORDER BY sorts (reorders) the records of the current selection of table for the current
process. After the sort has been completed, the new first record of the selection becomes
the current record.
If you omit the table parameter, the command applies to the default table. If no default
table has been set, an error occurs.
If you do not specify the field, the > or < or the * parameters, ORDER BY displays the Order
By editor for table. The User environment's Order By editor is shown here:
For more information about using the Order By editor, refer to the 4th Dimension User
Reference manual.
Examples
1. The following line displays the Order By editor for the [Products] table:
⇒ ORDER BY([Products])
2. The following line displays the Order By editor for the default table (if it has been set):
⇒ ORDER BY
If you specify the field and > or < parameters, the standard Order By editor is not
presented and the sort is defined programmatically. You can sort the selection on one
level or on several levels. For each sort level, you specify a field in field and the sorting
order in > or <. If you pass the “greater than” symbol (>), the order is ascending. If you
pass the “less than” symbol (<), the order is descending.
Examples
3. The following line orders the selection of [Products] by name in ascending order:
⇒ ORDER BY([Products];[Products]Name;>)
4. The following line orders the selection of [Products] by name in descending order:
⇒ ORDER BY([Products];[Products]Name;<)
5. The following line orders the selection of [Products] by type and price in ascending
order for both levels:
⇒ ORDER BY([Products];[Products]Type;>;[Products]Price;>)
6. The following line orders the selection of [Products] by type and price in descending
order for both levels:
⇒ ORDER BY([Products];[Products]Type;<;[Products]Price;<)
7. The following line orders the selection of [Products] by type in ascending order and by
price in descending order:
⇒ ORDER BY([Products];[Products]Type;>;[Products]Price;<)
⇒ ORDER BY([Products];[Products]Type;<;[Products]Price;>)
If you omit the sorting order parameter > or <, ascending order is the default.
Example
9. The following line orders the selection of [Products] by name in ascending order:
⇒ ORDER BY([Products];[Products]Name)
If only one field is specified (one level sort) and it is indexed, the index is used for the
order. If the field is not indexed or if there is more than one field, the order is performed
sequentially. The field may belong to the (selection’s) table being reordered or to a One
table related to table with an automatic relation. (Remember, the table to which ORDER
BY is applied must be the Many table.) In this case, the sort is always sequential.
Examples
10. The following line performs an indexed sort if [Products]Name is indexed:
⇒ ORDER BY([Products];[Products]Name;>)
11. The following line performs a sequential sort, whether or not the fields are indexed:
⇒ ORDER BY([Products];[Products]Type;>;[Products]Price;>)
12. The following line performs a sequential sort using a related field:
For multiple sorts (sorts on multiple fields), you can call ORDER BY as many times as
necessary and specify the optional * parameter, except for the last ORDER BY call, which
starts the actual sort operation. This feature is useful for multiple sorts management in
customized user interfaces.
Warning: with this syntax, you can pass only one sort level (field) per ORDER BY call.
Each column header contains a highlight button attached with the following object
method:
MULTILEVEL (->[CDs]Title) `Title column header button
Each button calls the MULTILEVEL project method with a pointer to the corresponding
column field. The MULTILEVEL project method is the following:
` MULTILEVEL Project Method
` MULTILEVEL (Pointer)
` MULTILEVEL (->[Table]Field)
No matter what way a sort has been defined, if the actual sort operation is going to take
some time to be performed, 4th Dimension automatically displays a message containing a
progress thermometer. These messages can be turned on and off by using the commands
MESSAGES ON and MESSAGES OFF. If the progress thermometer is displayed, the user can
click the Stop button to interrupt the sort. If the sort is completed, OK is set to 1.
Otherwise, if the sort is interrupted, OK is set to 0 (zero).
See Also
ORDER BY FORMULA.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
ORDER BY FORMULA (table{; expression}{; > or <}{; expression2; > or <2; ...; expressionN;
> or <N})
Description
ORDER BY FORMULA sorts (reorders) the records of the current selection of table for the
current process. After the sort has been completed, the new first record of the selection
becomes the current record.
Note that you must specify table. You cannot use a default table.
You can sort the selection on one level or on several levels. For each sort level, you specify
a expression in expression and the sorting order in > or <. If you pass the “greater than”
symbol (>), the order is ascending. If you pass the “less than” symbol (<), the order is
descending. If you do not specify the sorting order, ascending order is the default.
The parameter expression can be of type Alphanumeric, Real, Integer, Long Integer, Date,
Time or Boolean.
No matter what way a sort has been defined, if the actual sort operation is going to take
some time to be performed, 4th Dimension automatically displays a message containing a
progress thermometer. These messages can be turned on and off by using the commands
MESSAGES ON and MESSAGES OFF. If the progress thermometer is displayed, the user can
click the Stop button to interrupt the sort. If the sort is completed, OK is set to 1.
Otherwise, if the sort is interrupted, OK is set to 0 (zero).
4D Server: Since expression cannot be interpreted by 4D Server, each record is sent to the
local workstation; the order formula is evaluated on the workstation. This will make the
order inefficient. Use the ORDER BY command whenever possible.
See Also
ORDER BY.
Quick Report
Description
QR REPORT prints a report for table, created with the Quick Report editor shown here.
The Quick Report editor allows users to create their own reports. When the Quick Report
editor is displayed, the user is in the same context as when the editor is displayed in user
mode, at the exception of the possible presence of the Master table selection drop-down
list and of the New Query button. The user has complete control over the editor. See the
4th Dimension User Reference for details on creating reports with the Quick Report editor.
If the Quick Report editor is not involved, the OK variable is set to 1 if a report is printed;
it is set to 0 (zero) if not (i.e., if the user clicked Cancel in the printing dialog boxes).
Examples
1. The following example lets the user query the [People] table, and then automatically
prints the report “Detailed Listing”:
QUERY ([People])
If (OK=1)
⇒ QR REPORT ([People];"Detailed Listing";False;False;False;*)
End if
2. The following example lets the user query the [People] table, and then lets the user
choose which report to print:
QUERY ([People])
If (OK=1)
⇒ QR REPORT ([People];"";False;False;False)
End if
3. The following example lets the user query the [People] table, and then displays the
Report editor to design, save, load and print any reports with or without the wizard:
QUERY ([People])
If (OK=1)
⇒ QR REPORT ([People];Char(1);False;True)
End if
See Also
PRINT LABEL, PRINT SELECTION.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR REPORT TO BLOB command places the report whose reference was passed in area
in a BLOB (variable or field).
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid blob parameter, the error 64 will be generated (“A picture field or
variable was expected”).
Example
The following statement assigns the Quick Report stored in MyArea into a BLOB Field.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR BLOB TO REPORT command places the report contained in blob in the Quick
Report area passed in area.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid blob parameter, the error 9852 will be generated.
Examples
(1) The following code allows you to display in MyArea, a report file named “report.4qr”
located next to the database structure. The report file does not have to be created with 4th
Dimension 2003, it can originate from previous versions:
C_BLOB($doc)
C_LONGINT (MyArea)
DOCUMENT TO BLOB("report.4qr";$doc)
⇒ QR BLOB TO REPORT(MyArea;$doc)
(2) The following statement retrieves the Quick Report stored in Field4 and displays it in
MyArea:
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR New offscreen area command creates a new Quick Report offscreen area and
returns its reference.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR DELETE OFFSCREEN AREA command deletes in memory the Quick Report offscreen
area whose reference was passed as parameter.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET DESTINATION command sets the output type of the report for the area whose
reference was passed in area.
The following table describes the values that can be passed in both type and specifics
parameters:
Destination Constant (value) Specifics
Printer qr printer (1) N.A.
Text file qr text file (2) Pathname to the file
4D View qr 4D View area (3) N.A.
4D Chart qr 4D Chart area (4) N.A.
HTML file qr HTML file (5) Pathname to the HTML file
HTML BLOB qr HTML Blob (6) N.A.
Text file (2): If you pass an empty string as the file’s pathname, a Save file dialog is
displayed, otherwise the file is saved at the location indicated by the path.
The default field delimiter is the tab character (ASCII 9). The default record delimiter is
the carriage return character (ASCII 13). You can change these defaults by assigning
values to the two delimiter system variables: FldDelimit and RecDelimit. If under Windows,
FldDelimit equals 13, a char 10 (line feed) will be appended after the carriage return. Be
aware that these variables are used by other commands such as IMPORT TEXT for example.
Changing them for the Quick Report editor, changes them everywhere in the
application.
4D View (3): If 4D View is active for the user, a 4D View external window is created and
populated with the results of the current settings of the Quick Report area.
4D Chart(4): A 4D Chart external window is created and populated with the results of the
current settings of the Quick Report area. For detailed information on how the translation
is performed, please refer to the User Reference section of the Quick Report Editor
documentation.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid destination value, the error 9852 will be generated.
Example
The following code sets the destination as being the text file Mydoc.txt and executes the
Quick Report:
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR GET DESTINATION command retrieves the output type of the report for the area
whose reference was passed in area.
You can compare the value of the type parameter with the constants of the QR
Destination theme.
The following table describes the values that can be retrieved in both type and specifics
parameters:
Destination Constant (value) Specifics
Printer qr printer (1) N.A.
Text file qr text file (2) File pathname
4D View qr 4D View area (3) N.A.
4D Chart qr 4D Chart area (4) N.A.
HTML file qr HTML file (5) Pathname to the HTML file
HTML BLOB qr HTML Blob (6) N.A.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET DOCUMENT PROPERTY command allows you to display the printing dialog or
to define the unit used for the document.
You can pass in property the following constants, located in the QR Document properties
constant theme:
Constant Value
qr printing dialog 1
qr unit 2
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid property value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get document property command allows you to retrieve the display status for the
print dialog or the unit used for the ruler.
You can use in property the following constants, located in the QR Document properties
constant theme:
Constant Value
qr printing dialog 1
qr unit 2
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid property value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET REPORT KIND command sets the report type for the area whose reference was
passed in area.
You can also use the constants of the QR Report Types theme:
Constant Value
qr list report 1
qr cross report 2
If you set a new type for an existing current report, it removes the previous settings and
creates a new empty report, ready to be set.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get report kind command retrieves the report type for the area whose reference
was passed in area.
You can also compare the function result with the constants of the QR Report Types
theme:
Constant Value
qr list report 1
qr cross report 2
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET AREA PROPERTY command allows you to display or hide the interface element
(palette or menu bar) whose reference is passed in property.
The menu bar and toolbars are numbered from 1 to 6 (top to bottom) and the value 7 is
dedicated to the contextual menu. You can use the constants from the QR Area Properties
theme to designate the interface item:
You can use the constants from the QR Area Properties theme to designate the interface
item:
Constant Description
qr view menubar (1) Display status of the menu bar (Displayed=1, Hidden=0)
qr view standard toolbar (2) Display status of the Standard palette (Displayed=1,
Hidden=0)
qr view style toolbar (3) Display status of the Style palette (Displayed=1,
Hidden=0)
qr view computation toolbar (4) Display status of the Computation palette (Displayed=1,
Hidden=0)
qr view column toolbar (5) Display status of the Column palette (Displayed=1,
Hidden=0)
qr view color toolbar (6) Display status of the Color palette (Displayed=1,
Hidden=0)
qr view contextual menu (7) Display status of the Contextual menu (Displayed=1,
Hidden=0)
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid property parameter, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get area property command returns 0 if the interface element (palette or menu
bar) passed in property is not displayed; otherwise, it returns 1.
The menu bar and toolbars are numbered from 1 to 6 (top to bottom) and the value 7 is
dedicated to the contextual menu.
You can use the constants from the QR Area Properties theme to designate the interface
item:
Constant Description
qr view menubar (1) Display status of the menu bar (Displayed=1, Hidden=0)
qr view standard toolbar (2) Display status of the Standard palette (Displayed=1,
Hidden=0)
qr view style toolbar (3) Display status of the Style palette (Displayed=1,
Hidden=0)
qr view computation toolbar (4) Display status of the Computation palette (Displayed=1,
Hidden=0)
qr view column toolbar (5) Display status of the Column palette (Displayed=1,
Hidden=0)
qr view color toolbar (6) Display status of the Color palette (Displayed=1,
Hidden=0)
qr view contextual menu (7) Display status of the Contextual menu (Displayed=1,
Hidden=0)
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid property parameter, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET REPORT TABLE command sets the current table for the report area whose
reference was passed in area to the table whose number was passed in table.
It is critical that a table is assigned to the report since the report editor will be using the
current selection for that table to display the data, perform computations and propagate
relations, if needed.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid table value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get report table command returns the current table number for the report area
whose reference was passed in area.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET TEXT PROPERTY command allows you to set the text attributes for the cell
determined by colNum and RowNum.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid colNum number, the error 9852 will be generated.
If you pass an invalid rowNum number, the error 9853 will be generated.
If you pass an invalid property number, the error 9854 will be generated.
Example
This method defines several attributes to the first column’s title:
`The following call assigns the font Times:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr font;Font number("Times"))
`assigning the font size 10 points:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr font size;10)
`assigning the font attribute Bold:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr bold;1)
`assigning the font attribute Italic:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr italic;1)
`assigning the font attribute Underline:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr underline;1)
`assigning the color bright green:
⇒ QR SET TEXT PROPERTY(qr_area;1;-1;qr text color;0x0000FF00)
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get text property command returns the property value for the text attributes for
the cell determined by colNum and RowNum.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid colNum number, the error 9852 will be generated.
If you pass an invalid rowNum number, the error 9853 will be generated.
If you pass an invalid property number, the error 9854 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
QR RUN (area)
Description
The QR RUN command executes the report area whose reference was passed as parameter
with the Quick Report current settings, including the output type.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR EXECUTE COMMAND command executes the menu command or toolbar button
whose reference was passed in command. The most common use for this command is to
execute a command after the user selected that command and your code intercepted it
through the QR ON COMMAND command.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid command number, the error 9852 will be generated..
You can pass in command a value or one of the following constants, placed in the QR
Commands constant theme:
Constant Value
qr cmd bold 500
qr cmd italic 501
qr cmd underline 502
qr cmd left justified 503
qr cmd center justified 504
qr cmd right justified 505
qr cmd sum 506
qr cmd average 507
qr cmd max 508
qr cmd min 509
qr cmd count 510
qr cmd plain 511
qr cmd default justified 512
qr cmd font dropdown 1000
qr cmd font color palette 1002
qr cmd back color palette 1003
qr cmd alt back color palette 1004
qr cmd new 2000
qr cmd open 2001
qr cmd save 2002
qr cmd save as 2003
qr cmd revert to save 2004
qr cmd header and footer 2005
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get command status command returns 0 if the command is disabled or 1 if it is
enabled.
value returns the value of the selected sub-item, if any. For example, if the command that
was selected is the Font menu (1000) and the font selected was “Arial”, value would return
“Arial”, or if the command that was selected is a color menu (1002, 1003 or 1004), value
would return the color number.
You can pass in command a value or one of the following constants, placed in the QR
Commands constant theme:
Constant Value
qr cmd bold 500
qr cmd italic 501
qr cmd underline 502
qr cmd left justified 503
qr cmd center justified 504
qr cmd right justified 505
qr cmd sum 506
qr cmd average 507
qr cmd max 508
qr cmd min 509
qr cmd count 510
qr cmd plain 511
qr cmd default justified 512
qr cmd font dropdown 1000
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid command number, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR ON COMMAND command executes the 4D method passed in methodName when
a Quick Report command is invoked by the user, by the selection of a menu command or
by a click on a button.
If area equals zero, methodName will apply to each Quick Report area until the database is
closed or until the following call to QR ON COMMAND is made: QR ON COMMAND(0;"").
If you want the initial command to be executed you need to include the following in the
called method: QR EXECUTE COMMAND($1;$2).
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Find column command returns the number of the first column whose contents
match the expression passed in parameter.
If you pass an invalid area number, the error 9850 will be generated.
Example
The following code retrieves the column number that holds the field [G.NQR
Tests]Quarter and deletes that column:
followed by:
If ($NumColumn#-1)
QR DELETE COLUMN (MyArea ; $NumColumn)
End if
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET SELECTION command allows you to highlight a cell, a row, a column or the
entire area as you would with a mouse click. It also allows you to deselect the current
selection.
left is the number of the left boundary. If left equals 0, the entire row is selected.
top is the number of the top boundary. If top equals 0, the entire column is selected.
right is the number of the right boundary.
bottom is the number of the bottom boundary.
Notes:
• If both left and top equal 0, the entire area is highlighted.
• If you want no selection, pass -1 to left, right, top and bottom.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR GET SELECTION command returns the coordinates of the cell that is selected.
left returns the number of the column that is the left boundary of the selection. If left
equals 0, the entire row is selected.
top returns the number of the row that is the top boundary of the selection. If top equals
0, the entire column is selected.
Note: If both left and top equal 0, the entire area is highlighted.
right is the number of the column that is the right boundary of the selection.
bottom is the number of the row that is the top boundary of the selection.
Note: If there is no selection, left, top, right and bottom are set to -1.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
QR SET HEADER AND FOOTER (area; selector; leftTitle; centerTitle; rightTitle; height{; picture{;
pictJustification}})
Description
The QR SET HEADER AND FOOTER command allows you to set the contents and size of the
header or footer.
leftTitle, centerTitle and rightTitle are the values for, respectively, the left, center and right
header/footer.
height is the height of the header/footer, expressed in the unit selected for the quick
report.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid selector value, the error 9852 will be generated.
Example
The following statement places the title “Center title” in the header for the Quick Report
in MyArea and sets the header height to 200 pixels:
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
QR GET HEADER AND FOOTER (area; selector; leftTitle; centerTitle; rightTitle; height{;
picture{; pictAlignment}})
Description
The QR GET HEADER AND FOOTER command allows you to retrieve the contents and size
of the header or footer.
leftTitle, centerTitle and rightTitle returns the values for, respectively, the left, center and
right header/footer.
height returns the height of the header/footer, expressed in the unit selected for the
report.
pictAlignment is the alignment attribute for the picture displayed in the header/footer.
• If pictAlignment returns 0, the picture is aligned to the left.
• If pictAlignment returns 1, the picture is centered.
• If pictAlignment returns 2, the picture is aligned to the right.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid selector value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET BORDERS command allows you to set the border style for a given cell.
border is a composite value that indicates whose borders of the cell are to be affected:
• 1 indicates the left border
• 2 indicates the top border
• 4 indicates the right border
• 8 indicates the bottom border
For example, a value of 5 passed in border would affect the right and left borders.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR GET BORDERS command allows you to retrieve the border style for a border of a
given cell.
You can use constants from the QR Rows for Properties theme to designate the row item
(qr title= -1, qr detail=-2, qr grand total=-3).
color is the color of the line, it returns the value of the color applied to the line segment.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid column number, the error 9852 will be generated.
If you pass an invalid row number, the error 9853 will be generated.
If you pass an invalid border parameter, the error 9854 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
QR SET INFO COLUMN (area; colNum; title; object; hide; size; repeatedValue; displayFormat)
Description
List mode
The QR SET INFO COLUMN command allows you to set the parameters of an existing
column.
title is the title that will be displayed in the header of the column.
size is the size in pixels to assign to the column. If size equals -1, the size is made
automatic.
repeatedValue is the status for data repetition. For example, if the value for a field or
variable does not change from one record to the other it may or may not be repeated
when they do not change.
• If repeatedValue equals 0, values are not repeated.
• If repeatedValue equals 1, values are repeated.
displayFormat is the display format. Display formats are the 4D formats compatible with
the data displayed.
Cross-tab mode
The QR SET INFO COLUMN command allows you to set the same parameters but the
reference of the areas to which it applies is different and varies depending on the
parameter you want to set.
First of all, the parameters title, hide, and repeateValue are not used when that command is
used in cross-tab mode. The value to use for colNum varies depending on whether you
want to set the column size or the data source and display format.
• Column size
This is a “visual” attribute, therefore columns are numbered from left to right, as depicted
below.
The following statement will set the size to automatic for all the columns in a cross-tab
report and leaves other elements unchanged:
For ($i;1;3)
QR GET INFO COLUMN(qr_area;$i;$title;$obj;$hide;$size;$rep;$format)
⇒ QR SET INFO COLUMN(qr_area;$i;$title;$obj;$hide;0;$rep;$format)
End for
You will notice that since you want to alter only the column size, you have to use QR GET
INFO COLUMN to retrieve the column properties and pass them to QR SET INFO COLUMN
to leave it unchanged, except for the column size.
You will notice that not all cells can be addressed through the command QR SET INFO
COLUMN, the cells that are not numbered above are addressed through QR SET TOTALS
DATA.
The following code assigns data sources to the three cells required for creating a basic
cross-tab report:
QR SET REPORT TABLE(qr_area;Table(->[Invoices]))
ALL RECORDS([Invoices])
QR SET REPORT KIND(qr_area;2)
⇒ QR SET INFO COLUMN(qr_area;1;"";->[Invoices]Item;1;-1;1;"")
⇒ QR SET INFO COLUMN(qr_area;2;"";->[Invoices]Quarter;1;-1;1;"")
⇒ QR SET INFO COLUMN(qr_area;3;"";->[Invoices]Quantity;1;-1;1;"")
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid colNum value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
QR GET INFO COLUMN (area; colNum; title; object; hide; size; repeatedValue; displayFormat)
Description
List mode
The QR GET INFO COLUMN command allows you to retrieve the parameters of an existing
column.
title returns the title that will be displayed in the header of the column.
object returns the name of the actual object of the column (variable, field name or
formula).
size returns the size of the column in pixels. If size equals -1, the size is automatic.
repeatedValue returns the status for data repetition For example, if the value for a field or
variable does not change from one record to the other it may or may not be repeated
when they do not change:
• if repeatedValue equals 0, values are not repeated,
• if repeatedValue equals 1, values are repeated.
format is the display format. Display formats are the 4D formats compatible with the data
displayed.
The following statement sets the size to automatic for all the columns in a cross-tab report
and leaves other elements unchanged:
For ($i;1;3)
⇒ QR GET INFO COLUMN(qr_area;$i;$title;$obj;$hide;$size;$rep;$format)
⇒ QR SET INFO COLUMN(qr_area;$i;$title;$obj;$hide;0;$rep;$format)
End for
You will notice that since you want to alter only the column size, you have to use QR GET
INFO COLUMN to retrieve the column properties and pass them to QR SET INFO COLUMN
to leave it unchanged, except for the column size.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET INFO ROW command displays/hides the row whose reference was passed in
row.
You can use constants from the QR Rows for Properties theme to designate the row item
(qr title= -1, qr detail=-2, qr grand total=-3).
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid row value, the error 9852 will be generated.
Example
The following statement hides the detail row:
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get info row command retrieves the display status of the row whose reference was
passed in row.
You can use constants from the QR Rows for Properties theme to designate the row item
(qr title= -1, qr detail=-2, qr grand total=-3)
The function result specifies whether the row is visible or hidden. If it equals 1, the row is
set to hidden; if it equals 0, the row is set to visible.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid row value, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET SORTS command allows you to set the sort orders for the columns in the
report whose reference is passed in area.
aColumns: in this array, you need to store the column numbers of columns to which you
want to assign a sort order.
aOrders: each element of this array must contain the sort orders for the matching column
in the aColumns array.
• If aOrders{$i} equals 1, the sort order is ascending.
• If aOrders{$i} equals - 1, the sort order is descending.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR GET SORTS command populates two arrays:
• aColumns
This array includes all the columns that have a sort order.
• aOrders
Each element of this array contains the sort orders for the matching column.
- If aOrders{$i} equals 1, the sort order is ascending.
- If aOrders{$i} equals - 1, the sort order is descending.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
List Mode
The QR SET TOTALS DATA command allows you to set the details of a specific break (total
or subtotal).
colNum is the column number of the cell whose data is going to be set.
breakNum is the number of the break whose data will be set (subtotal or grand total). For a
Subtotal, breaknum is the sort number. For the Grand total, breaknum equals -3 or the
constant qr grand total.
operator is an addition of all the operators present in the cell. You can use the constants
of the QR Operators theme to set the value:
Constant Value
qr sum 1
qr average 2
qr max 4
qr min 8
qr count 16
Cross-tab Mode
The QR SET TOTALS DATA command allows you to set the details of a specific cell.
colNum is the column number of the cell whose data is going to be set.
breakNum is the row number of the cell whose data is going to be set.
operator is an addition of all the operators present in the cell. You can use the constants
of the QR Operators theme to set the value (see above).
Here is a depiction of how the parameters column and break have to be combined in
cross-tab mode:
• Operator
An operator or a combination of operators (as described above) can be passed for the
following cells:
column=2, breakNum=2
column=3, breakNum=2
column=2, breakNum=3
Please note that these last two values affect the cell (Column 3; Row 3) as well. If a
computation is defined in the cell (Column 2; Row 3), the contents of the cell (Column
2; Row 3) always define the contents of the cell (Column 3; Row 3).
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid colNum number, the error 9852 will be generated.
If you pass an invalid breakNum number, the error 9853 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
List Mode
The QR GET TOTALS DATA command allows you to retrieve the details of a specific break.
breakNum is the number of the break whose data will be retrieved (subtotal or grand
total):
- Subtotal : between 1 and the number of Subtotal/sort.
- Grand total : -3 / constant : qr grand total
operator returns the sum of all the operators present in the cell. You can use the constants
of the QR Operators theme to process the returned value:
Constant Value
qr sum 1
qr average 2
qr max 4
qr min 8
qr count 16
Cross-tab Mode
The QR GET TOTALS DATA command allows you to retrieve the details of a specific cell.
breakNum is the row number of the cell whose data is going to be retrieved.
operator returns the sum of all the operators present in the cell. You can use the constants
of the QR Operators theme to process the returned value (see above).
Here is a depiction of how the parameters colNum and breakNum have to be combined in
cross-tab mode:
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid colNum number, the error 9852 will be generated.
If you pass an invalid breakNum number, the error 9853 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET TOTALS SPACING command allows you to set a space above a subtotal row. It
applies only to the list mode.
Note: If the space above a subtotal row “pushes” the row to the next page, there will be
no space inserted above the row on that page.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid subtotalNumber, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR GET TOTALS SPACING command allows you to retrieve a space above a subtotal
row. It applies only to the list mode.
subtotal is the subtotal level (or break level) that will be affected.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid subtotalNumber, the error 9852 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR INSERT COLUMN command inserts or creates a column at the specified position.
Columns located to the right of that position will be shifted accordingly.
The default title for the column will be the value passed in object.
If you pass an invalid area number, the error 9850 will be generated.
Example
The following statement inserts (or creates) a first column in a Quick Report area, inserts
“Field1” as column title (default behavior) and populates the contents of the body with
values from Field1.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get drop column command returns a value depending on where the drop was
performed:
• if the value is negative, it indicates a column number (i.e. -3 if the the drop was
performed on column number 3)
• if the value is positive, it indicates that the drop was performed on a separator preceding
the column (i.e. 3 if the drop was performed after column 2). Keep in mind that the drop
does not have to take place before an existing column.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Count columns command returns the number of columns present in the Quick
Report area.
If you pass an invalid area number, the error 9850 will be generated.
Example
The following code retrieves the column count and inserts a column to the right of the
rightmost existing column:
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR DELETE COLUMN command deletes the column in area whose number was passed
in colNumber. This command does not apply to cross-tab reports.
If you pass an invalid area number, the error 9850 will be generated.
If you pass an invalid column number, the error 9852 will be generated.
Example
The following example makes sure the report is a list report and deletes the third column:
If(QR Get report kind(MyArea )=qr list report)
⇒ QR DELETE COLUMN (MyArea;3)
End if
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR SET HTML TEMPLATE command sets the HTML template currently used for the
Quick Report area. The template will be used when building the report in HTML format.
The template uses a set of tags to process the data to either retain a layout close to the
original report or to adopt your own custom HTML.
If you pass an invalid area number, the error 9850 will be generated.
Note: You first need to call QR SET DESTINATION to set the output to HTML file.
HTML Tags
<!--#4DQRheader> ... <!--/#4DQRheader>
The HTML contents that are included between those tags come from the column titles.
You will typically use these tags to define the title row of the report.
<!--#4DQRbgcolor>
This color tag will be replaced by the current color for the current cell.
<!--#4DQRdata>
This tag will be replaced by the current data for the current cell.
If you pass an invalid area number, the error 9850 will be generated.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The QR Get HTML template command returns the HTML template currently used for the
Quick Report area. The returned value is a text value and includes all the contents of the
HTML template.
If no specific template was defined, the template that is returned is the default template.
Please note that no template will be returned if the output was not set to HTML file,
either manually or programmatically.
Record Locking
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
There are three important concepts to be aware of when using commands in a multi-
processing database:
• Each table is in either a read-only or a read/write state.
• Records become locked when they are loaded and unlocked when they are unloaded.
• A locked record cannot be modified.
Locked Records
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A locked record cannot be modified by the local user or the current process. A locked
record can be loaded, but cannot be modified. A record is locked when one of the other
users or processes has successfully loaded the record for modification. Only the user who is
modifying the record sees that record as unlocked. All other users and processes see the
record as locked, and therefore unavailable for modification. A table must be in a
read/write state for a record to be loaded unlocked.
Each table in a database is in either a read/write or a read-only state for each user and
process of the database. Read-only means that records for the table can be loaded but not
modified. Read/write means that records for the table can be loaded and modified if no
other user has locked the record first.
Read-Only State
When a table is read-only and a record is loaded, the record is always locked. In other
words, the record can be displayed, printed, and otherwise used, but it cannot be
modified.
Note that read-only status applies only to editing existing records. Read-only status does
not affect the creation of new records. You can add records to a read-only table using
CREATE RECORD and ADD RECORD or the New Record menu command from the User
environment’s Enter menu.
4th Dimension automatically sets a table to read-only for commands that do not require
write access to records. These commands are:
• DISPLAY SELECTION
• DISTINCT VALUES
• EXPORT DIF
• EXPORT SYLK
• EXPORT TEXT
• GRAPH TABLE
• PRINT SELECTION
• PRINT LABEL
• REPORT
• SELECTION TO ARRAY
• SELECTION RANGE TO ARRAY
Before executing any of these commands, 4th Dimension saves the current state of the
table (read-only or read/write) for the current process. After the command has executed,
the state is restored.
Read/Write State
When a table is read/write and a record is loaded, the record will become unlocked if no
other user has locked the record first. If the record is locked by another user, the record is
loaded as a locked record that cannot be modified by the local user.
A table must be set to read/write and the record loaded for it to become unlocked and
thus modifiable.
If a user loads a record from a table in read/write mode, no other users can load that
record for modification. However, other users can add records to the table, either through
the CREATE RECORD or ADD RECORD commands or manually in the User environment.
Read/write is the default state for all tables when a database is opened and a new process is
started.
Each process has its own state (read-only or read/write) for each table in the database.
Before the local user can modify a record, the table must be in the read/write state and the
record must be loaded and unlocked.
Any of the commands that loads a current record (if there is one) — such as NEXT
RECORD, QUERY, ORDER BY, RELATE ONE, etc. — sets the record as locked or unlocked.
The record is loaded according to the current state of its table (read-only or read/write)
and its availability. A record may also be loaded for a related table by any of the
commands that cause an automatic relation to be established.
If a table is in the read-only state, then a record loaded from that table is locked. A locked
record cannot be saved or deleted. Read-only is the preferred state, because it allows other
users to load, modify, and then save the record.
If a table is in the read/write state, then a record that is loaded from that table is unlocked
only if no other users have locked the record first. An unlocked record can be modified
and saved. A table should be put into the read/write state before a record needs to be
loaded, modified, and then saved.
If the record is to be modified, you use the Locked function to test whether or not a
record is locked by another user. If a record is locked (Locked returns True), load the
record with the LOAD RECORD command and again test whether or not the record is
locked. This sequence must be continued until the record becomes unlocked (Locked
returns False).
When modifications to be made to a record are finished, the record must be released (and
therefore unlocked for the other users) with UNLOAD RECORD. If a record is not
unloaded, it will remain locked for all other users until a different current record is
selected. Changing the current record of a table automatically unlocks the previous
current record. You need to explicitly call UNLOAD RECORD if you do not change the
current record. This discussion applies to existing records. When a new record is created, it
can be saved regardless of the state of the table to which it belongs.
Note: When it is used in a transaction, the UNLOAD RECORD command unloads the
current record only for the process that manages the transaction. For other processes, the
record stays locked as long as the transaction has not been validated (or cancelled).
The following example shows the simplest loop with which to load an unlocked record:
READ WRITE ([Customers]) ` Set the table’s state to read/write
Repeat ` Loop until the record is unlocked
LOAD RECORD ([Customers]) ` Load record and set locked status
Until (Not (Locked([Customers])))
` Do something to the record here
READ ONLY ([Customers]) ` Set the table’s state to read-only
A loop like this is used only if the record is unlikely to be locked by anyone else, since the
user would have to wait for the loop to terminate. Thus, it is unlikely that the loop would
be used as is unless the record could only be modified by means of a method.
The following example uses the previous loop to load an unlocked record and modify the
record:
READ WRITE([Inventory])
Repeat ` Loop until the record is unlocked
LOAD RECORD([Inventory]) ` Load record and set it to locked
Until (Not (Locked([Inventory])))
[Inventory]Part Qty := [Inventory]Part Qty – 1 ` Modify the record
SAVE RECORD ([Inventory]) ` Save the record
UNLOAD RECORD ([Inventory]) ` Let other users modfiy it
READ ONLY([Inventory])
The MODIFY RECORD command automatically notifies the user if a record is locked, and
prevents the record from being modified. The following example avoids this automatic
notification by first testing the record with the Locked function. If the record is locked,
the user can cancel.
A number of commands in the language perform specific actions when they encounter a
locked record. They behave normally if they do not encounter a locked record.
See Also
LOAD RECORD, Locked, LOCKED ATTRIBUTES, Methods, READ ONLY, Read only state, READ
WRITE, UNLOAD RECORD, Variables.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
READ WRITE changes the state of table to read/write for the process in which it is called. If
the optional * parameter is specified, all tables are changed to read/write state.
After a call to READ WRITE, when a record is loaded, the record is unlocked if no other user
has locked the record. This command does not change the status of the currently loaded
record, only that of subsequently loaded records.
Use READ WRITE when you must modify a record and save the changes. Also use READ
WRITE when you must lock a record for other users, even if you are not making any
changes. Setting a table to read/write mode prevents other users from editing that table.
However, other users can create new records.
Note: This command is not retroactive. A record is loaded according to the table’s
read/write status at the time of loading. To load a record from a read-only table in
read/write mode, you must first change the table state to read/write.
See Also
READ ONLY, Read only state, Record Locking.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
READ ONLY changes the state of table to read-only for the process in which it is called. All
subsequent records that are loaded are locked, and you cannot make any changes made to
them. If the optional * parameter is specified, all tables are changed to read-only state.
Use READ ONLY when you do not need to modify the record or records.
Note: This command is not retroactive. A record is loaded according to the table’s
read/write status at the time of loading. To load a record from a read/write table in read-
only mode, you must first change the table state to read-only.
See Also
Read only state, READ WRITE, Record Locking.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This function is used to test whether or not the state of table is read-only for the process
in which it is called. Read only state returns TRUE if the state of table is read-only. Read
only state returns FALSE if the state of table is read/ write.
Example
The following example tests the state of an [Invoice] table. If the state of the [Invoice]
table is read-only, it is set to read/write, and then the current record is reloaded.
Note: The invoice record is reloaded to allow the user to modify it. A record that was
previously loaded in a read-only state will remain locked until it is reloaded in a read/write
state.
See Also
READ ONLY, READ WRITE, Record Locking.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
LOAD RECORD loads the current record of table. If there is no current record, LOAD
RECORD has no effect.
You can then use the Locked function to determine whether you can modify the record:
• If the table is in read-only state, the Locked function returns TRUE, and you cannot
modify the record.
• If the table is in read/write state but the record was already locked, the record will be
read-only, and you cannot modify the record.
• If the table is in read/write state and the record is not locked, you can modify the record
in the current process. The Locked function returns TRUE for all other users and processes.
Note: If the LOAD RECORD command is executed after a READ ONLY, the record is
automatically unloaded and loaded without having to use the UNLOAD RECORD
command.
Usually, you do not need to use the LOAD RECORD command, because commands like
QUERY, NEXT RECORD, PREVIOUS RECORD, etc., automatically load the current record.
See Also
Locked, Record Locking, UNLOAD RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
UNLOAD RECORD unloads the current record of table.
If the record is unlocked for the local user (locked for the other users), UNLOAD RECORD
unlocks the record for the other users.
Although UNLOAD RECORD unloads it from memory, the record remains the current
record. When another record is made the current record, the previous current record is
automatically unloaded and therefore unlocked for other users. Always execute this
command when you have finished modifying a record and want to make it available to
other users, while retaining the record as your current record.
If a record has a large amount of data, picture fields, or external documents (such as 4D
Write or 4D Draw documents), you may not want to keep the current record in memory
unless you need to modify it. In this case, use the UNLOAD RECORD command to keep
the current record without having it in memory. You free the memory occupied by the
record, but you do not have access to its field values. If you later need access to the values
of the record, use the LOAD RECORD command.
Note: When it is used in a transaction, the UNLOAD RECORD command unloads the
current record only for the process that manages the transaction. For other processes, the
record stays locked as long as the transaction has not been validated (or cancelled).
See Also
LOAD RECORD, Record Locking.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Locked tests whether or not the current record of table is locked. Use this function to find
out whether or not the record is locked; then take appropriate action, such as giving the
user the choice of waiting for the record to be free or skipping the operation.
If Locked returns TRUE, then the record is locked by another user or process and cannot
be saved. In this case, use LOAD RECORD to reload the record until Locked returns FALSE.
If Locked returns FALSE, then the record is unlocked, meaning that the record is locked
for all other users. Only the local user or current process can modify and save the record.
A table must be in read/write state in order for you to modify the record.
If you try to load a record that has been deleted, Locked continues to return TRUE. To
avoid waiting for a record that does not exist anymore, use the LOCKED ATTRIBUTES
command. If the record has been deleted, the LOCKED ATTRIBUTES command returns -1
in the process parameter.
During transaction processing, LOAD RECORD and Locked are often used to test record
availability. If a record is locked, it is common to cancel the transaction.
See Also
LOAD RECORD, LOCKED ATTRIBUTES, Record Locking.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
LOCKED ATTRIBUTES returns information about the user and process that have locked a
record. The process number, user name, machine name, and process name are returned in
the process, user, machine, and processName variables. You can use this information in a
custom dialog box to warn the user when a record is locked.
If the record is not locked, process returns 0 and user, machine, and processName return
empty strings. If the record you try to load in read/write has been deleted, process returns
-1 and user, machine, and processName return empty strings.
In single-user mode, this command returns values in process and processName only if a
record is locked. The values returned in user and machine are empty strings.
In Client/Server mode, the returned process number is the number of the process on the
server.
The User parameter returned is the user name from the 4th Dimension password system,
even if user name is blank. If there is no password system, “Manager” is returned.
The machine parameter returned is the owner name from the operating system file
sharing setup. A name change does not take effect until you restart.
See Also
Locked, Record Locking.
Records
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DISPLAY RECORD displays the current record of table, using the current
input form. The record is displayed only until an event redraws the window. Such an
event might be the execution of an ADD RECORD command, returning to an input form,
or returning to the menu bar. DISPLAY RECORD does nothing if there is no current
record.
DISPLAY RECORD is often used to display custom progress messages. It can also be used to
generate a free-running slide show.
WARNING: Do not call DISPLAY RECORD from within a Web connection process, because
the command will be executed on the 4th Dimension Web server machine and not on
the Web browser client machine.
Example
The following example displays a series of records as a slide show:
ALL RECORDS([Demo]) ` Select all of the records
INPUT FORM ([Demo]; "Display") ` Set the form to use for display
For ($vlRecord;1;Records in selection([Demo])) ` Loop through all of the records
⇒ DISPLAY RECORD([Demo]) ` Display a record
DELAY PROCESS (Current process; 180) ` Pause for 3 seconds
NEXT RECORD([Demo]) ` Move to the next record
End for
See Also
MESSAGE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CREATE RECORD creates a new empty record for table, but does not display the new
record. Use ADD RECORD to create a new record and display it for data entry.
CREATE RECORD is used instead of ADD RECORD when data for the record is assigned with
the language. The new record becomes the current record and the current selection (a
one-record current selection).
The record exists in memory only until a SAVE RECORD command is executed for the
table. If the current record is changed (for example, by a query) before the record is saved,
the new record is lost.
Example
The following example archives records that are over 30 days old. It does does this by
creating new records in an archival table. When the archiving is finished, the records that
were archived are deleted from the [Accounts] table:
` Find records more than 30 days old
QUERY ([Accounts]; [Accounts]Entered < (Current date – 30))
For ($vlRecord;1; Records in selection([Accounts])) ` Loop once for each record
⇒ CREATE RECORD ([Archive]) ` Create a new archive record
[Archive]Number:=[Account]Number ` Copy fields to the archive record
[Archive]Entered:=[Account]Entered
[Archive]Amount:=[Account]Amount
SAVE RECORD([Archive]) ` Save the archive record
NEXT RECORD([Accounts]) ` Move to the next account record
End for
DELETE SELECTION([Accounts]) ` Delete the account records
See Also
SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DUPLICATE RECORD creates a new record for table that is a duplicate of the current record.
The new record becomes the current record. If there is no current record, then DUPLICATE
RECORD does nothing. You must use SAVE RECORD to save the new record.
DUPLICATE RECORD can be executed during data entry. This allows you to create a clone
of the currently displayed record. Remember that you must first execute SAVE RECORD in
order to save any changes made to the original record.
See Also
SAVE RECORD.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is new record returns True when the table’s current record is being created
and has not yet been saved in the current process.
Compatibility Note: You can obtain the same information by using the existing
command Record number, and by testing if it returns -3.
However, we strongly advise you to use Is new record instead of Record number in this
case. Actually, the Is new record command ensures compatibility with future versions of
4th Dimension.
Example
The following two instructions are identical. The second one is strongly advised so that
the code will be compatible with future versions of 4D:
If (Record number([Table])=-3) `Not advised
` ...
End if
See Also
Modified record, Record number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Modified record returns True if the current record of table has been modified but not
saved; otherwise it returns False. This function allows the designer to quickly test whether
or not the record needs to be saved. It is especially valuable in input forms to check
whether or not to save the current record before proceeding to the next one. This
function always returns TRUE for a new record.
Example
The following example shows a typical use for Modified record:
See Also
Modified, Old, SAVE RECORD.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is record loaded returns True if the table’s current record is loaded in the
current process.
Example
Instead of using the “Next record” or “Previous record” automatic actions, you can write
object methods for these buttons to improve their operation. The “Next” button will
display the beginning of the selection if the user is at the end of the selection and the
“Previous” button will show the end of the selection when the user is at the beginning of
the selection.
` Object method of the “Previous” button (without an automatic action)
If (Form event=On Clicked)
PREVIOUS RECORD([Group])
⇒ If (Not(Is record loaded([Group])))
GOTO SELECTED RECORD([Group];Records in selection([Group]))
`Go to the last record in the selection
End if
End if
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SAVE RECORD saves the current record of table in the current process. If there is no
current record, then SAVE RECORD is ignored.
You use SAVE RECORD to save a record that you created or modified with code. A record
that has been modified and validated by the user in a form does not need to be saved
with SAVE RECORD. A record that has been modified by the user in a form, but has been
canceled, can still be saved with SAVE RECORD.
You should not execute a SAVE RECORD during the On Validate event for a form that has
been accepted. If you do, the record will be saved twice.
Example
The following example is part of a method that reads records from a document. The code
segment receives a record, and then, if it is received properly, saves it:
RECEIVE RECORD ([Customers]) ` Receive record from disk
If (OK= 1) ` If the record is received properly…
⇒ SAVE RECORD ([Customers]) ` save it
End if
See Also
CREATE RECORD, Locked, Triggers.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DELETE RECORD deletes the current record of table in the process. If there is no current
record for table in the process, DELETE RECORD has no effect. In a form, you can create a
Delete Record button instead of using this command. After the record is deleted, the
current selection for table is empty.
If a record is deleted, the record number will be reused when new records are created. Do
not use the record number as the record identifier if you will ever delete records from the
database.
Example
The following example deletes an employee record. The code asks the user what employee
to delete, searches for the employee’s record, and then deletes it:
vFind := Request ("Employee ID to delete:") ` Get an employee ID
If (OK = 1)
QUERY ([Employee]; [Employee]ID = vFind) ` Find the employee
DELETE RECORD ([Employee]) ` Delete the employee
End if
See Also
Locked, Triggers.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Records in table returns the total number of records in table. Records in selection returns
the number of records in the current selection only. If Records in table is used within a
transaction, records created during the transaction will be taken into account.
Example
The following example displays an alert that shows the number of records in a table:
See Also
Records in selection.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Record number returns the physical record number for the current record of table. If there
is no current record, such as when the record pointer is before or after the current
selection, Record number returns –1. If the record is a new record that has not been saved,
Record number returns –3.
Record numbers can change. The record numbers of deleted records are reused. Record
numbers will also change if you compact the database or perform a recover by tags
operation on the database using 4D Tools. During a transaction, a newly created record
has a temporary record number. After the transaction has been accepted, the record is
assigned a regular record number.
Example
The following example saves the current record number and then searches for any other
records that have the same data:
See Also
About Record Numbers, GOTO RECORD, Is new record, Selected record number, Sequence
number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GOTO RECORD selects the specified record of table as the current record. The record
parameter is the number returned by the Record number function. After executing this
command, the record is the only record in the selection.
If record is less than the smallest record number in the database or greater than the
greatest record number in the database, 4th Dimension generates an error message stating
that the record number is out of range. If record is equal to the record number of a
deleted record, the selection becomes empty.
Note: With this command, you should not use temporary record numbers issued during
transactions.
Example
See the example for Record number.
See Also
About Record Numbers, Record number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Sequence number returns the next sequence number for table. The sequence number is
unique for each table. It is a nonrepeating number that is incremented for each new
record created for the table. The numbering starts at 1.
You should use the Sequence number function instead of the #N symbol if:
• You are creating records procedurally
• The sequence number needs to start at a number other than 1
• The sequence number needs an increment greater than 1
• The sequence number is part of a code, for example a part number code
To store the sequence number by means of a method, create a long integer field in the
table and assign the sequence number to the field.
The sequence number is the same number assigned by using the #N symbol as the default
value for a field in a form. For information on assigning default values, see the
4th Dimension Design Reference .
If the sequence number needs to start at a number other than 1, just add the difference to
Sequence number. For example, if the sequence number must start at 1000, you would use
the following statement to assign the number:
See Also
About Record Numbers, Record number, Selected record number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Record Number
The record number is the absolute/physical record number for a record. The record
number is automatically assigned to each new record and remains constant for the record
until the record is deleted or the file is permanently reordered using 4D Tools. Record
numbers start at zero. Record numbers are not unique because record numbers of deleted
records are reused for new records. Record numbers also change when the file is
permanently reordered using 4D Tools or when the database is compacted or repaired.
New records added in transaction are assigned temporary record numbers. They are
assigned final record numbers when the transaction is validated.
Sequence Number
The sequence number is a unique nonrepeating number that may be assigned to a field of
a record. It is not automatically stored with each record. It starts at 1 and is incremented
for each new record that is created. Unlike record numbers, a sequence number is not
reused when a record is deleted or when a table is compacted, repaired, or permanently
reordered using 4D Tools. Sequence numbers provide a way to have unique ID numbers
for records. If a sequence number is incremented during a transaction, the number is not
decremented if the transaction is canceled.
The following tables illustrate the numbers that are associated with records. Each line in
the table represents information about a record. The order of the lines is the order in
which records would be displayed in an output form.
Note: The records remain in the default order after a command changes the current
selection without reordering it; for example, after the Show All menu command is chosen
in the User environment, or after the ALL RECORDS command is executed.
See Also
Record number, Selected record number, Sequence number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PUSH RECORD pushes the current record of table (and its subrecords, if any) onto the
table’s record stack. PUSH RECORD may be executed before a record is saved.
If you push a record that was unlocked, this record stays locked for all the other processes
and users until you pop and unload it.
Example
The following example pushes the record for the customer onto the record stack:
See Also
POP RECORD, Using the Record Stack.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
POP RECORD pops a record belonging to table from the table’s record stack, and makes
the record the current record.
If you push a record, change the selection to not include the pushed record, and then pop
the record, the current record is not in the current selection. To designate the popped
record as the current selection, use ONE RECORD SELECT. If you use any commands that
move the record pointer before saving the record, you will lose the copy in memory.
Example
The following example pops the record for the customer off the record stack:
See Also
PUSH RECORD, Using the Record Stack.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The commands PUSH RECORD and POP RECORD allow you to put (“push”) records onto
the record stack, and to remove (“pop”) them from the stack.
Each process has its own record stack for each table. 4th Dimension maintains the record
stacks for you. Each record stack is a last-in-first-out (LIFO) stack. Stack capacity is limited
by memory.
PUSH RECORD and POP RECORD should be used with discretion. Each record that is
pushed uses part of free memory. Pushing too many records can cause an out-of-memory
or stack full condition.
4th Dimension clears the stack of any unpopped records when you return to the menu at
the end of execution of your method.
PUSH RECORD and POP RECORD are useful when you want to examine records in the
same file during data entry. To do this, you push the record, search and examine records
in the file (copy fields into variables, for example), and finally pop the record to restore
the record.
Note to version 3 users: While entering a record, if you have to check a multiple field
unique value, use the new SET QUERY DESTINATION command. This will save you the calls
to PUSH RECORD and POP RECORD that you were making before and after the call to
QUERY in order to preserve the data entered in the current record. SET QUERY
DESTINATION allows you to make a query that does not change the selection nor the
current record.
See Also
POP RECORD, PUSH RECORD, SET QUERY DESTINATION.
Relations
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The commands in this theme, in particular RELATE ONE and RELATE MANY, establish and
manage the automatic and non-automatic relations between tables. Before using any of
the commands in this theme, refer to the 4th Dimension Design Reference manual for
information about creating relations between tables.
Two tables can be related with automatic table relations. In general, when an automatic
table relation is established, it loads or selects the related records in a related table. Many
operations cause the relation to be established.
To optimize performance, when 4th Dimension establishes automatic relations, only one
record becomes the current record for a table. For each of the operations listed above, the
related record is loaded according to the following principles:
• If a relation selects only one record of a related table, that record is loaded from disk.
• If a relation selects more than one record of a related table, a new selection of records is
created for that table, and the first record in that selection is loaded from disk.
For example, using the database structure displayed here, if a record for the [People] table
is loaded and displayed for data entry, the related record from the [Companies] table is
selected and is loaded. Similarly, if a record for the [Companies] table is loaded and
displayed for data entry, the related records from the [People] table are selected.
Similarly, the Company field in the [People] table is referred to as the Many field, and the
Name field in the [Companies] table is referred to as the One field.
It is not always possible to have the related field be unique. For example, the
[Companies]Name field may have several company records containing the same value.
This non-unique situation can be easily handled by creating a relation, which will always
be unique, on another field in the related table. This field could be a company ID field.
The following table lists commands that use automatic relations to load related records
during operation of the command. All of the commands will establish a Many-to-One
relation automatically. Only those commands with Yes in the Many Established column
will create a One-to-Many relation automatically.
Automatic relations do not mean that the related record or records for a table will be
selected simply because a command loads a record. In some cases, after using a command
that loads a record, you must explicitly select the related records by using RELATE ONE or
RELATE MANY if you need to access the related data.
Some of the commands listed in the previous table (such as the query commands) load a
current record after the task is completed. In this case, the record that is loaded does not
automatically select the records related to it. Again, if you need to access the related data,
you must explicitly select the related records by using RELATE ONE or RELATE MANY.
See Also
AUTOMATIC RELATIONS, CREATE RELATED ONE, OLD RELATED MANY, OLD RELATED ONE,
RELATE MANY, RELATE MANY SELECTION, RELATE ONE, RELATE ONE SELECTION, SAVE OLD
RELATED ONE, SAVE RELATED ONE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
AUTOMATIC RELATIONS temporarily changes all manual relations into automatic relations
for the entire database. The relations stay automatic unless a subsequent call to
AUTOMATIC RELATIONS is made.
If one is true, then all manual Many-to-One relations will become automatic. If one is
false, all previously changed Many-to-One relations will revert to manual relations.
The same is true for the many parameter, except that manual One-to-Many relations are
affected.
Relations that are set as automatic in the Design environment are not affected by this
command.
If all relations have been set as manual in the Design environment, this command makes
it possible to change them to be automatic, just before executing operations that need the
relation to be automatic (such as relational searches and sorts). After the operation is
finished, the relation can be changed back to manual.
Example
The following example makes all manual Many-to-One relations automatic and reverts
any previously changed One-to-Many relations:
See Also
Relations, SELECTION RANGE TO ARRAY, SELECTION TO ARRAY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
RELATE ONE has two forms.
The first form, RELATE ONE(manyTable), establishes all automatic Many-to-One relations
for manyTable in the current process. This means that for each field in manyTable that has
an automatic Many-to-One relation, the command will select the related record in each
related table. This changes the current record in the related tables for the process.
The second form, RELATE ONE(manyField{;choiceField}), looks for the record related to
manyField. The relation does not need to be automatic. If it exists, RELATE ONE loads the
related record into memory, making it the current record and current selection for its
table.
The optional choiceField can be specified only if manyField is an Alpha field. The choiceField
must be a field in the related table. The choiceField must be an Alpha, Numeric, Date,
Time, or Boolean field; it cannot be a text, picture, BLOB, or subtable field.
If choiceField is specified and more than one record is found in the related table, RELATE
ONE displays a selection list of records that match the value in manyField. In the list, the
left column displays related field values, and the right column displays choiceField values.
More than one record may be found if manyField ends with the wildcard character (@). If
there is only one match, the list does not appear. Specifying choiceField is the same as
specifying a wildcard choice when establishing the table relation. For information about
specifying a wildcard choice, refer to the 4th Dimension Design Reference.
RELATE ONE works with relations to subtables, but you must have a relation to the parent
table and to the subtable’s related field in order for the relation to be properly established.
When using a relation to a subrecord, you must first use RELATE ONE to load the related
record into memory, then use a second RELATE ONE command for the subtable.
Since both relations are to the same table, [Customers], you cannot obtain the billing and
shipment information at the same time. Therefore, displaying both addresses in a form
should be performed using variables and calls to RELATE ONE. If the [Customers] fields
were displayed instead, data from only one of the relations would be displayed.
The following two methods are the object methods for the [Invoice]Bill to and [Invoice]Ship
to fields. They are executed when the fields are entered.
See Also
OLD RELATED ONE, RELATE MANY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
RELATE MANY has two forms.
The first form, RELATE MANY(oneTable), establishes all One-to-Many relations for
oneTable. It changes the current selection for each table that has a One-to-Many relation
to oneTable. The current selections in the Many tables depend on the current value of
each related field in the One table. Each time this command is executed, the current
selections of the Many tables will be regenerated.
The second form, RELATE MANY(oneField), establishes the One-to-Many relation for
oneField. It changes the current selection for only those tables that have relations with
oneField. This means that the related records become the current selection for the Many
table.
Note: If the current selection in the One table is empty while the RELATE MANY
command is executed, it has no effect.
Example
In the following example, three tables are related with automatic relations. Both the
[People] table and the [Parts] table have a Many-to-One relation to the [Companies] table.
When the People and Parts forms are displayed, the related records for both the [People]
table and the [Parts] table are loaded and become the current selections in those tables.
On the other hand, the related records are not loaded if a record for the [Companies] table
is selected programmatically. In this case, you must use the RELATE MANY command.
Note: When the RELATE MANY command is applied to an empty selection, the command
is not executed and the selection for the MANY table does not change.
For example, the following method moves through each record of the [Companies] table.
An alert box is displayed for each company. The alert box shows the number of people in
the company (the number of related [People] records), and the number of parts they
supply (the number of related [Parts] records). In the example, the argument to the
ALERTcommand is printed on multiple lines for clarity.
See Also
OLD RELATED MANY, RELATE ONE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CREATE RELATED ONE performs two actions. If a related record does not exist for field (that
is, if a match is not found for the current value of field), CREATE RELATED ONE creates a
new related record.
To save a value in the appropriate field, assign values to the One field from the Many
field. Call SAVE RELATED ONE to save the new record.
If a related record exists, CREATE RELATED ONE acts just like RELATE ONE and loads the
related record into memory.
See Also
SAVE RELATED ONE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SAVE RELATED ONE saves the record related to field. Execute a SAVE RELATED ONE
command to update a record created with CREATE RELATED ONE, or to save modifications
to a record loaded with RELATE ONE.
SAVE RELATED ONE does not apply to subtables, because saving the parent record
automatically saves the subrecords.
SAVE RELATED ONE will not save a locked record. When using this command, you must
first be sure that the record is unlocked. If the record is locked, the command is ignored,
the record is not saved, and no error is returned.
See Also
CREATE RELATED ONE, Locked, RELATE ONE, Triggers.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
OLD RELATED ONE operates the same way as RELATE ONE does, except that OLD RELATED
ONE uses the old value of field to establish the relation.
Note: OLD RELATED ONE uses the old value of the Many field as returned by the Old
function. For more information, see the description of the Old command.
OLD RELATED ONE loads the record previously related to the current record. The fields in
that record can then be accessed. If you want to modify this old related record and save it,
you must call SAVE OLD RELATED ONE. Note that there is no old related record for a newly
created record.
See Also
Old, OLD RELATED MANY, RELATE ONE, SAVE OLD RELATED ONE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SAVE OLD RELATED ONE operates the same way as SAVE RELATED ONE does, but uses the
old relation to the field to save the old related record. Before you use SAVE OLD RELATED
ONE, you must load the record with OLD RELATED ONE. Use SAVE OLD RELATED ONE
when you want to save modifications to a record loaded with OLD RELATED ONE.
SAVE OLD RELATED ONE will not save a locked record. When using this command, you
must first be sure that the record is unlocked. If the record is locked, the command is
ignored, the record is not saved, and no error is returned.
See Also
Locked, OLD RELATED ONE, Triggers.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
OLD RELATED MANY operates the same way RELATE MANY does, except that OLD RELATED
MANY uses the old value in the one field to establish the relation.
Note: OLD RELATED MANY uses the old value of the many field as returned by the Old
function. For more information, see the description of the Old command.
OLD RELATED MANY changes the selection of the related table, and selects the first record
of the selection as the current record.
See Also
OLD RELATED ONE, RELATE MANY.
Description
The command RELATE ONE SELECTION creates a new selection of records for the table
oneTable, based on the selection of records in the table manyTable.
This command can only be used if there is a relation from manyTable to oneTable. RELATE
ONE SELECTION can work across several levels of relations. There can be several related
tables between manyTable and oneTable. The relations can be manual or automatic.
Example
The following example finds all the clients whose invoices are due today.
Here is one way of creating a selection in the [Customers] table, given a selection of
records in the [Invoices] table:
CREATE EMPTY SET([Customers];"Payment Due")
QUERY([Invoices];[Invoices]DueDate = Current date)
While(Not(End selection([Invoices])))
RELATE ONE ([Invoices]CustID)
ADD TO SET([Customers];"Payment Due")
NEXT RECORD([Invoices])
End while
The following technique uses RELATE ONE SELECTION to accomplish the same result:
QUERY([Invoices];[Invoices]DueDate = Current date)
⇒ RELATE ONE SELECTION([Invoices];[Customers])
See Also
QUERY, RELATE MANY SELECTION, RELATE ONE, Sets.
Description
The command RELATE MANY SELECTION generates a selection of records in the Many
table, based on a selection of records in the One table.
Note: RELATE MANY SELECTION changes the current record for the One table.
Example
This example selects all invoices made to the customers whose credit is greater than or
equal to $1,000. The [Invoices] table field [Invoices]Customer ID relates to the [Customer]
table field [Customers]ID Number.
` Select the Customers
QUERY ([Customers];[Customers]Credit>=1000)
` Find all invoices related to any of these customers
RELATE MANY SELECTION ([Invoices]Customer ID)
See Also
QUERY, RELATE ONE, RELATE ONE SELECTION.
Resources
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A resource is data of any kind stored in a defined format in a .RSR Windows file or in the
resource fork of a Macintosh file. Resources typically include data such as strings, pictures,
icons and so on. As a matter of fact, you can create and use your own kinds of resources
and store whatever data you want into them.
On Macintosh, each file can have a data fork and a resource fork. The data fork of a
Macintosh file is the equivalent of a file on Windows and UNIX. The resource fork of a
Macintosh file contains the Macintosh-based resources of the file and has no direct
equivalent on Windows or UNIX.
Windows-based resources are stored and mixed with the other data of the file. For
example, in a Windows application, a .EXE file can contain both resource data and code.
In order to maintain the platform independence of your 4D applications, 4th Dimension
works with Macintosh-based resources on both the Macintosh and Windows platforms.
4D Transporter
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Since resource forks do not exist on Windows, the 4D Transporter utility program
(delivered with the Macintosh version of 4th Dimension) enables you to transport a 4D
database from Windows to Macintosh and vice-versa.
When you transport a 4D database from Windows to Macintosh, the .4DB and .RSR files
of the database structure file are merged into one Macintosh file. The .4DB file becomes
the data fork of the Macintosh structure file, and the .RSR file becomes the resource fork
the Macintosh structure file. Conversly, when you transport a 4D database from
Macintosh to Windows, the Macintosh structure file is split into two files. Its data fork
becomes the .4DB file and the resource fork becomes the .RSR file.
In fact, this is the sole purpose of the 4D Transporter utility—splitting or merging data
and resource forks of files. It does not translate or modify the actual data stored in the
forks and files. For more information about transporting 4D databases between platforms,
refer to the 4D Transporter Reference manual.
No matter what platform you are using, a 4D database structure file is not the only type
of file with resources. The 4D application itself contains resources. On Macintosh, the 4D
resources are stored in the resource fork of the application. On Windows, they are stored
in the 4D.RSR file, the resource part of the 4D application whose executable code is stored
in the 4D.EXE file.
4D Plug-ins can also contain resources. For example, the 4D Write plug-in contains
resources. On Macintosh, these are stored in the resource fork of 4D Write. On Windows,
they are stored in the 4DWRITE.RSR file.
The data file of a 4D database can also contains resources. For example, if you lock a data
file for exclusive use with a particular structure file (using the Customizer Plus utility), this
operation adds the same WEDD (“WEDD” for “wedding”) resource into the structure and
data files. On Macintosh, the resource is added to the resource fork of the data file. On
Windows, the resource is stored in the .4DR file, the resource file for the data file.
Note: Customizer Plus is delivered with the Windows and Macintosh versions of 4th
Dimension)
On Windows, with the exception of the data file’s .4DR file, you usually detect standard
4D files containing Macintosh-based resources as files with the file extension .RSR. Note
that the command Create resource files uses .RES as default file extension.
When you work with a 4D database, you can either work with all the currently open
resource files or with a specific resource file.
Multiple resource files can be open at the same time. This is always the case from within a
4D database. The following files are open:
• On Macintosh, the System resource file.
• On Windows, the ASIPORT.RSR file (it contains part of the Macintosh system resources).
• The 4D application resource file.
• The database structure resource file.
• The database data file resource file may be optionally open.
• Finally, you can open your own resource file using the command Open resource file.
Here is an example:
$vhResFile:=Create resource file("Just_a_file")
If (OK=1)
ARRAY STRING(63;asSomeStrings;0)
STRING LIST TO ARRAY(8;asSomeStrings;$vhResFile)
ALERT("The size of the array is "+String(Size of array(asSomeStrings))+" element(s).")
STRING LIST TO ARRAY(8;asSomeStrings)
ALERT("The size of the array is "+String(Size of array(asSomeStrings))+" element(s).")
CLOSE RESOURCE FILE($vhResFile)
End if
At execution of this method, the first alert will display “The size of the array is 0
element(s)” and the second alert will display “The size of the array is 634 element(s)”.
looks for the resource "STR#" ID=8 only in the resource file just created and open by the
call to Create resource file. Because the file is new and therefore empty, the resource is not
found.
looks for the resource "STR#" ID=8 in all the currently open resource files. Since the file
just created and opened (by the call to Create resource file) does not contain that resource,
STRING LIST TO ARRAY then looks for the resource in the database structure resource file.
This resource file does not contain that resource either, so STRING LIST TO ARRAY then
examines the 4D resource file, locates the resource in this file, and populates the array
with it.
Conclusion: When working with resource files, if you want to access a specific file, make
sure to pass the resource file reference number to a 4D Resources command. Otherwise,
the command assumes that you do not care which file is the source of the resources.
A resource file is highly structured. In addition to the data of each resource, it contains a
header and a map that fully describe its contents.
Resources are classified by types. A resource type is always denoted by a 4-character string.
A resource type is both case sensitive and diacritical sensitive. For example, the resource
types “Hi_!”, “hi_!” and “HI_!” are all different.
Important: Resource types with lowercase characters are reserved for use by the Operating
System. Avoid designating your own resource types with lowercase characters.
• A resource of type “cicn” is a resource containing a Macintosh-based color icon that you
can use and display with 4D on both Macintosh and Windows. This resource is called a
color icon resource. For example, a “cicn” resource can be associated with an item of a
hierarchical list, using the command SET LIST ITEM PROPERTIES.
In addition to the standard resource types, you can create you own types. For example,
you can decide to work with resources of type “MTYP” (for “My Type”).
To obtain the list of resource types currently present in all open resource files or in a
particular resource file, use the command RESOURCE TYPE LIST. Then, to obtain the list of
a specified type of resource present in all open resource files or in a particular resource file,
use the command RESOURCE LIST. This command returns the IDs and Names (see next
section) of all resources of a given type.
WARNING: Many applications rely on the resource type for working with its contents. For
example, while accessing a “STR#” resource, applications expect to find a string list in the
resource. Do NOT store inconsistent data in resources of standard types; this may lead to
system errors in your 4D application or in other applications.
WARNING: A resource is a highly structured file—do NOT access the file with commands
other than Resources commands. Note that nothing prevents you from passing a resource
file reference number (formally a 4D time expression like the document reference
number) to a command such as SEND PACKET. However, if you do so, you will probably
damage the resource file.
A resource has a resource name. A resource name can be up to 255 characters, and is
diacritical sensitive but not case sensitive. Resource names are useful for describing a
resource, but you access a resource using its type and ID number. Resource names are not
unique; several resources can have the same name.
A resource has a resource ID number (for short, resource ID or ID). This ID is unique
within a resource type and a resource file. For example:
• One resource file can contain a resource “ABCD” ID=1 and a resource “EFGH” ID=1.
• Two resource files can contain a resource with the same type and ID.
When you access a resource using a 4D command, you indicate its type and ID. If you do
not specify the resource file in which you are looking for this resource, the command
returns the occurrence of the resource found in the first examined resource file.
Remember that resource files are examined in the reverse order in which they have been
opened.
Important: Use the range 15,000..32,767 for your own resources. Do NOT use negative
resource IDs; these are reserved for use by the Operating System. Do NOT use resource IDs
in the range 0..14,999; this range is reserved for use by 4th Dimension.
To obtain the IDs and names of a given resource type, use the command RESOURCE LIST.
To obtain the name of an individual resource, use the command Get resource name.
To change the name of and individual resource, use the command SET RESOURCE NAME.
To obtain the current (actual) number for a resource installed by a 4D component, use the
command Get component resource ID.
Besides its type, name and ID, a resource has additional properties (also called attributes).
For example, a resource may or may not be purged. This attribute tells the Operating
System whether or not a loaded resource can be purged from memory when free memory
is required for allocating another object. As shown in the previous example, when
creating or copying a resource, it can be important to not only copy the resource, but also
its name and properties. For a complete explanation of resource properties, see the
description of the commands Get resource properties and SET RESOURCE PROPERTIES.
To load a resource of any type into memory, call GET RESOURCE, which returns the
contents of the resource in a BLOB.
To add or rewrite a resource on disk, call SET RESOURCE, which sets the contents of the
resource to the contents of the BLOB you pass.
To delete an existing resource, use the command DELETE RESOURCE.
To simplify handling of standard resource types, 4D provides additional built-in
commands that save you from having to parse a BLOB in order to extract the resource
data:
• STRING LIST TO ARRAY populates a String or Text array with the strings contained in a
string list resource.
• ARRAY TO STRING LIST creates or rewrites a string list resource with the elements of a
String or Text array.
• Get indexed string returns a particular string from a string list resource.
• Get string resource returns the string from a string resource.
• SET STRING RESOURCE creates or rewrites a string resource.
• Get text resource returns the text of a text resource.
• SET TEXT RESOURCE creates or rewrites a text resource.
• GET PICTURE RESOURCE returns the picture of a picture resource.
• SET PICTURE RESOURCE creates or rewrites a picture resource.
• GET ICON RESOURCE returns a color icon resource as a picture.
Note that these commands are provided to simplify manipulation of standard resource
types; however, they do not prevent you from using GET RESOURCE and SET RESOURCE
using BLOBs. For example, this line of code:
ALERT(Get text resource(20000))
In addition to the Resources commands described in this chapter, there are other 4D
commands that work with resources and resource files:
• On Macintosh, DOCUMENT TO BLOB and BLOB TO DOCUMENT can load and write the
whole resource fork of a Macintosh file.
• Using the commands SET LIST ITEM PROPERTIES and SET LIST PROPERTIES, you can
associate picture or color icon resources to the items of a list or use color icon resources as
nodes of a list.
• The PLAY command plays “snd ” resources on both Macintosh and Windows.
• The SET CURSOR command changes the appearance of the mouse using “CURS”
resources.
See Also
BLOB Commands, Get component resource ID, OS Resource Manager Errors, Resources and
4D Insider: an Example.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Resources are very convenient way to deal with localization issues when developing and
maintaining a 4D database in different languages for the international market.
Let’s look at an example. The following figure shows the menu bar of a database in
English:
The title of the File menu already refers to a resource, while its menu item Quit does not.
The Examples menu is composed of the menu items Hierarchical Lists and Picture
Menus. This menu and its items do not refer to resources.
Using 4D Insider, it is possible to transform the literals of the menu bar into references to
strings stored in STR# resources. Let’s see how to perform this operation.
Note: 4D Insider is the 4D cross-reference and library management tool delivered with
4D Desktop.
2. At this point, the menu bar can be transformed to refer to a STR# resource. To do so,
select Text to STR# from the 4D Insider Tools Menu:
3. Enter the resource name and ID, then click New. For example, Examples Menu is the
resource name and 20000 is the resource ID. The resource is created.
4. Select STR# in the popup menu of the browser window's main list:
Now that these strings are stored in a resource, it is possible to change their values
without tampering with the logic of your database development.
6. To change the values, select Edit STR# from the 4D Insider Tools menu while the
Examples Menu resource is selected in the main list of the browser window:
7. Translate the strings to another language. In the following figure, the strings have
been translated to French:
8. Once you have performed the translation, close the window. Click Yes in the confirm
dialog box:
If you own the 4D desktop package, refer to the 4D Insider Reference manual for more
information about this process. In addition, for more information about using references
to resources in menus bars as well as objects in your database forms, refer to the
4th Dimension Design Reference manual.
The 4D Resources commands enable you to use the resources created by 4D Insider. The
following method uses the STRING LIST TO ARRAY command to load the STR# resource
(created using 4D Insider) into an array:
See Also
Resources.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Open resource file opens the resource file whose name or pathname you
pass in resFileName.
If you pass a filename, the file should be located in the same folder as the structure file of
the database. Pass a pathname to open a resource file located in another folder.
If you pass an empty string in resFileName, the Open File dialog box is presented. You can
then select the resource file to open. If you cancel the dialog, no resource file is open;
Open resource file returns a null DocRef and sets the OK variable to 0.
If the resource file is opened correctly, Open resource file returns its resource file reference
number and sets the OK variable to 1. If the resource file does not exist, or if the file you
try to open is not a resource file, an error is generated.
On Macintosh, if you use the Open File dialog box, all files are presented by default. To
show a particular type of file, specify the file type in the optional fileType parameter.
On Windows, if you use the Open File dialog box, all files are presented by default. To
show a particular type of file, in fileType, pass a 1- to 3-character Windows file extension or
a Macintosh file type mapped using the command MAP FILE TYPES.
Remember to call CLOSE RESOURCE FILE for the resource file. Note, however, that when
you quit the application (or open another database), 4D automatically closes all the
resource files you opened using Open resource file or Create resource file .
This multiple-opening capability enables you to easily obtain the reference numbers of
the 4D application and database resource files without tampering with normal 4D
operations (see examples 5 and 6).
WARNING
• Use caution when accessing the 4D application resource file. Do NOT modify the
resources of the 4D application; you could inadvertently damage the program and
provoke system errors. Also, remember that your database can be used in various
environments (4D, Runtime, 4D Engine, 4D Server and 4D Client).
• If you access the database resource file and intend to programmatically add, delete or
modify its resources, be sure to test the environment in which you are running. With 4D
Server, this will probably lead to serious issues. For example, if you modify a resource on
the server machine (via a database method or a stored procedure), you will definitely
affect the built-in 4D Server administration service that distributes resources
(transparently) to the workstations. Note that with 4D Client, you do not have direct
access to the structure file; it is located on the server machine.
• For these reasons, if you use resources, store them in your own files.
• When working with your own resources, do NOT use negative resource IDs; they are
reserved for use by the Operating System. Do NOT use resource IDs in the range
0..14,999; this range is reserved for use by 4th Dimension. Use the range 15,000..32,767
for your own resources. Remember that once you have opened a resource file, it will be
the first file to be searched in the resource files chain. If you store a resource in that file
with an ID in the range of system or 4D resources, this resource will be found by
commands such as GET RESOURCE and also by internal routines of the 4D application.
This may be the result you want to achieve, but if you are not sure, do NOT use these
ranges, as they may lead to system errors.
• Resource files are highly structured files and cannot accept more than 2,700 resources
per file. If you work with files containing a large number of resources, it is a good idea to
test that number before adding new resources to a file. See the Count resources examples
listed for the command RESOURCE TYPE LIST.
After you have opened a resource file, you can analyze the contents of the file using the
commands RESOURCE TYPE LIST and RESOURCE LIST.
2. The following example tries to open, on Windows. the resource file “MyPrefs.rsr”
located in the database folder:
3. The following example displays the Open file dialog box showing all types of files:
4. The following example displays the Open file dialog box showing files created by the
Create resource file command, using the default file type:
See Also
CLOSE RESOURCE FILE, Create resource file, Resources.
If the resource file is successfully opened using the Open file dialog box, the Document
variable is set to the pathname of the file.
Error Handling
If the resource file could not be opened due to a resource or I/O problem, an error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Create resource file creates and opens a new resource file whose name or
pathname is passed in resFileName.
If you pass a filename, the file will be located in the same folder as the structure file of the
database. Pass a pathname to create a resource file located in another folder.
If the file already exists and is not currently open, Create resource file overrides it with a
new empty resource file. If the file is currently open, an I/O error is returned.
If you pass an empty string in resFileName, the Save File dialog box is presented. You can
then choose the location and the name of the resource file to be created. If you cancel
the dialog, no resource file is created; Create resource file returns a null DocRef and sets the
OK variable to 0.
If the resource file is correctly created and opened, Create resource file returns its resource
file reference number and sets the OK variable to 1. If the resource file cannot be created,
an error is generated.
On Macintosh, the default file type for a file created with Create resource file is “res ”.
On Windows, the default file extension is “.res”.
Examples
1. The following example tries to create and ope, on Windows, the resource file
“MyPrefs.res” located in the database folder:
On Macintosh, the example tries to create and open the file “MyPrefs”.
2. The following example tries to create and open, on Windows, the resource file
“MyPrefs.rsr” located in the database folder:
On Macintosh, the example tries to create and open the file “MyPrefs”.
See Also
CLOSE RESOURCE FILE, ON ERR CALL, Open resource file, Resources.
If the resource file is successfully created and opened through the Save File dialog box, the
Document variable is set to the pathname of the file.
Error Handling
If the resource file could not be created or opened due to a resource or I/O problem, an
error is generated. You can catch this error with an error-handling method installed using
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CLOSE RESOURCE FILE closes the resource file whose reference number is
passed in resFile.
Even if you have opened the same resource file several times, you need to call CLOSE
RESOURCE FILE only once in order to close that file.
If you apply CLOSE RESOURCE FILE to the 4D application or database resource files, the
command detects it and does nothing.
If you pass an invalid resource file reference number, the command does nothing.
Remember to eventually call CLOSE RESOURCE FILE for a resource file that you have
opened using Open Resource file or Create resource file. Note that when you quit the
application (or open another database), 4D automatically closes all the resource files you
opened.
Example
The following example creates a resource file, adds a string resource and closes the file:
$vhDocRef:=Create resource file("Just a file")
If (OK=1)
SET STRING RESOURCE(20000;"Just a string";$vhDocRef)
⇒ CLOSE RESOURCE FILE($vhDocRef)
End if
See Also
Create resource file, Open resource file.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command RESOURCE TYPE LIST populates the array resTypes with the resource types
of the resources present in the resource files currently open.
If you pass a valid resource file reference number in the optional parameter resFile, only
the resources from that file are listed. If you do not pass the parameter resFile, all the
resources from the current open resource files are listed.
You can predeclare the array resTypes as a String or Text array before calling RESOURCE
TYPE LIST. If you do not predeclare the array, the command creates resTypes as a Text
array.
After the call, you can test the number of resource types found by applying the command
Size of array to the array resTypes.
Examples
1. The following example populates the array atResType with the resource types of the
resources present in all the resource files currently open:
2. The following example tells you if the Macintosh 4D structure file you are using
contains old 4D plug-ins that will need to be updated in order to use the database on
Windows:
$vhResFile:=Open resource file(Structure file)
⇒ RESOURCE TYPE LIST(atResType;$vhResFile)
If (Find in array(atResType;"4DEX")>0)
ALERT("This database contains old model Mac OS 4D plug-ins."+(Char(13)*2)+
"You will have to update them for using this database on Windows.")
End if
Note: The structure file is not the only file where old version plug-ins can be stored. The
database can also include a Proc.Ext file.
C_LONGINT($0)
C_TIME($1)
$0:=0
⇒ RESOURCE TYPE LIST($atResType;$1)
For ($vlElem;1;Size of array($atResType))
RESOURCE LIST($atResType{$vlElem};$alResID;$atResName;$1)
$0:=$0+Size of array($alResID)
End for
See Also
RESOURCE LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command RESOURCE LIST populates the arrays resIDs and resNames with the resource
IDs and names of the resources whose type is passed in resType.
Important: You must pass a 4-character string in resType.
If you pass a valid resource file reference number in the optional parameter resFile, only
the resources from that file are listed. If you do not pass the parameter resFile, all resources
from the current open resource files are listed.
If you predeclare the arrays before calling RESOURCE LIST, you must predeclare resIDs as a
Longint array and resNames as a String or Text array. If you do not predeclare the arrays,
the command creates resIDs as a Longint array and resNames as a Text array.
After the call, you can test the number of resources found by applying the command Size
of array to the array resIDs or resNames.
Examples
1. The following example populates the arrays $alResID and $atResName with the IDs and
names of the string list resources present in the structure file of the database:
If (On Windows)
$vhStructureResFile:=Open resource file(Replace string(Structure file;".4DB";
".RSR"))
Else
$vhStructureResFile:=Open resource file(Structure file)
End if
If (OK=1)
⇒ RESOURCE LIST("STR#";$alResID;$atResName;$vhStructureResFile)
End if
⇒ RESOURCE LIST("PICT";$alResID;$atResName)
Open window(50;50;550;120;5;"Copying PICT resources...")
For ($vlElem;1;Size of array($alResID))
GET PICTURE RESOURCE($alResID{$vlElem};$vgPicture)
If (OK=1)
$vsName:=$atResName{$vlElem}
If ($vsName="")
$vsName:="PICT resID="+String($alResID{$vlElem})
End if
ERASE WINDOW
GOTO XY(2;1)
MESSAGE("Adding picture “"+$vsName+"” to the DB Picture library.")
SET PICTURE TO LIBRARY($vgPicture;$alResID{$vlElem};$vsName)
End if
End for
CLOSE WINDOW
See Also
RESOURCE TYPE LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command STRING LIST TO ARRAY populates the array strings with the strings stored in
the string list ("STR#") resource whose ID is passed in resID.
If the resource is not found, the array strings is left unchanged and the OK variable is set
to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Before calling STRING LIST TO ARRAY, you can predeclare the array strings as a String or
Text array. If you do not predeclare the array, the command creates strings as a Text array.
Note: Each string of a string list resource can contain up to 255 characters.
Tip: Limit your use of string list resources to those up to 32K in total size, and a maximum
of a few hundred strings per resource.
Example
See example for the command ARRAY TO STRING LIST.
See Also
ARRAY TO STRING LIST, Get indexed string, Get string resource, Get text resource.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ARRAY TO STRING LIST creates or rewrites the string list (“STR#”) resource
whose ID is passed in resID. The contents of the resource are created from the strings
passed in the array strings. The array can be a String or Text array.
If you pass a valid resource file reference number in resFile, the resource is added to that
file. If you do not pass resFile, the resource is added to the file at the top the resource files
chain (the last resource file opened).
Note: Each string of a string list resource can contain up to 255 characters.
Tip: Limit your use of string list resources to resources no more than 32K in total size, and
a maximum of a few hundred strings maximum per resource.
Example
Your database relies on a given set of fonts.
See Also
SET STRING RESOURCE, SET TEXT RESOURCE, STRING LIST TO ARRAY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get indexed string returns one of the strings stored in the string list
(“STR#”) resource whose ID is passed in resID.
You pass the number of the string in strID. The strings of a string list resource are
numbered from 1 to N. To get all the strings (and their numbers) of a string list resource,
use the command STRING LIST TO ARRAY.
If the resource or the string within the resource is not found, an empty string is returned
and the OK variable is set to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Example
See example for the command Month of.
See Also
Get string resource, Get text resource, STRING LIST TO ARRAY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get string resource returns the string stored in the string (“STR ”) resource
whose ID is passed in resID.
If the resource is not found, an empty string is returned and the OK variable is set to 0
(zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Example
The following example displays the contents of the string resource ID=20911, which
must be located in at least one of the currently open resource files:
See Also
Get indexed string, Get text resource, SET STRING RESOURCE, STRING LIST TO ARRAY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET STRING RESOURCE creates or rewrites the string (“STR ”) resource
whose ID is passed in resID with the string passed in resData.
If you pass a valid resource file reference number in resFile, the resource is added to that
file. If you do not pass resFile, the resource is added to the file at the top the resource files
chain (the last resource file opened).
See Also
Get string resource, SET TEXT RESOURCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get text resource returns the text stored in the text (“TEXT”) resource
whose ID is passed in resID.
If the resource is not found, empty text is returned, and the OK variable is set to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Example
The following example displays the contents of the text resource ID=20800, which must
be located in at least one of the currently open resource files:
See Also
Get indexed string, Get string resource, SET TEXT RESOURCE, STRING LIST TO ARRAY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET TEXT RESOURCE creates or rewrites the text (“TEXT”) resource whose
ID is passed in resID with the text or string passed in resData.
If you pass a valid resource file reference number in resFile, the resource is added to that
file. If you do not pass resFile, the resource is added to the file at the top the resource files
chain (the last resource file opened).
See Also
Get text resource, SET STRING RESOURCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET PICTURE RESOURCE returns in the picture field or variable resData the
picture stored in the picture (“PICT”) resource whose ID is passed in resID.
If the resource is not found, the resData parameter is left unchanged, and the OK variable
is set to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Example
See example for the command RESOURCE LIST.
See Also
GET ICON RESOURCE, ON ERR CALL, SET PICTURE RESOURCE.
Error Handling
If there is not enough memory to load the picture, an error is generated. You can catch
this error with an error-handling method installed using ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET PICTURE RESOURCE creates or rewrites the picture (“PICT”) resource
whose ID is passed in resID with the picture passed in resData.
If you pass a valid resource file reference number in resFile, the resource is added to that
file. If you do not pass resFile, the resource is added to the file at the top of the resource
files chain (the last resource file opened).
If you pass in resData an empty picture field or variable, the command has no effect and
the OK variable is set to 0.
Note: A picture resource can be several megabytes in size and even more.
See Also
GET PICTURE RESOURCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET ICON RESOURCE returns, in the picture field or variable resData, the
icon stored in the color icon (“cicn”) resource whose ID is passed in resID.
If the resource is not found, the resData parameter is left unchanged and the OK variable
is set to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Example
The following example loads, in a Picture array, the color icons located in the active 4D
application:
If (On Windows)
$vh4DResFile:=Open resource file(Replace string(Application file;".EXE";".RSR"))
Else
$vh4DResFile:=Open resource file(Application file)
End if
RESOURCE LIST("cicn";$alResID;$asResName;$vh4DResFile)
$vlNbIcons:=Size of array($alResID)
ARRAY PICTURE(ag4DIcon;$vlNbIcons)
For ($vlElem;1;$vlNbIcons)
⇒ GET ICON RESOURCE($alResID{$vlElem};ag4DIcon{$vlElem};$vh4DResFile)
End for
See Also
GET PICTURE RESOURCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET RESOURCE returns in the BLOB field or variable resData the contents
of the resource whose type and ID is passed in resType and resID.
If the resource is not found, the resData parameter is left unchanged and the OK variable
is set to 0 (zero).
If you pass a valid resource file reference number in resFile, the resource is searched for in
that file only. If you do not pass resFile, the first occurrence of the resource found in the
resource files chain is returned.
Platform independence: Remember that you are working with MacOS-based resources. No
matter what the platform, internal resource data such as Long Integer is stored using
Macintosh byte ordering. On Windows, the data for standard resources (such as string list
and pictures resources) is automatically byte swapped when necessary. On the other hand,
if you create and use your own internal data structures, it is up to you to byte swap the
data you extract from the BLOB (i.e., passing Macintosh byte ordering to a command such
BLOB to longint).
Example
See the example for the command SET RESOURCE.
Error Handling
If there is not enough memory to load the resource, an error is generated. You can catch
this error with an error-handling method installed using ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET RESOURCE command creates or rewrites the resource whose type and ID is passed
in resType and resID with the data passed in the BLOB resData.
If you pass a valid resource file reference number in resFile, the resource is added to that
file. If you do not pass resFile, the resource is added to the file at the top of the resource
files chain (the last resource file opened).
Platform independence: Remember that you are working with MacOS-based resources. No
matter what the platform, internal resource data such as Long Integer is stored using
Macintosh byte ordering. On Windows, the data for standard resources (such as string list
and pictures resources) is automatically byte swapped when necessary. On the other hand,
if you create and use your own internal data structures, it it up to you to byte swap the
data you write into the BLOB (i.e., passing Macintosh byte ordering to a command such
LONGINT TO BLOB).
Example
During a 4D session you maintain some user preferences in interprocess variables. To save
these preferences from session to session, you can:
1. Use the commands SAVE VARIABLES and LOAD VARIABLES to store and retrieve the
variables in variable documents on disk.
2. Use the commands VARIABLE TO BLOB, BLOB TO DOCUMENT, DOCUMENT TO BLOB
and BLOB TO VARIABLE to store and retrieve the variables in BLOB documents on disk.
3. Use the commands VARIABLE TO BLOB, SET RESOURCE, GET RESOURCE and BLOB TO
VARIABLE to to store and retrieve the variables in resource files on disk.
See Also
BLOB Commands, GET RESOURCE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get resource name returns the name of the resource whose type is passed
in resType and whose ID number is passed in resID.
If you pass a valid resource file reference number in the parameter resFile, the resource is
searched for within that file only. If you do not pass the parameter resFile, the resource is
searched for within the current open resource files.
If the resource does not exist, Get resource name returns an empty string and sets the OK
variable to 0 (zero).
Example
The following project method copies a resource, and its resource name and attributes,
from one resource file to another:
` COPY RESOURCE Project Method
` COPY RESOURCE ( String ; Long ; Time ; Time )
` COPY RESOURCE ( resType ; resID ; srcResFile ; dstResFile )
C_STRING (4;$1)
C_LONGINT ($2)
C_TIME ($3;$4)
C_BLOB ($vxResData)
GET RESOURCE ($1;$2;$vxData;$3)
If (OK=1)
SET RESOURCE ($1;$2;$vxData;$4)
If (OK=1)
⇒ SET RESOURCE NAME ($1;$2; Get resource name ($1;$2;$3);$4)
SET RESOURCE PROPERTIES ($1;$2; Get resource properties ($1;$2;$3);$4)
End if
End if
See Also
SET RESOURCE PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET RESOURCE NAME changes the name of the resource whose type is
passed in resType and whose ID number is passed in resID.
If you pass a valid resource file reference number in the parameter resFile, the resource is
searched for within that file only. If you do not pass the parameter resFile, the resource is
searched for within the current open resource files.
If the resource does not exist, SET RESOURCE NAME does nothing and sets the OK variable
to 0 (zero).
WARNING: DO NOT change the names of resources that belong to 4D or to any System
files. If you do so, you may provoke undesired system errors.
Note: Resource names can be up to 255 characters in length. They are not case sensitive,
but are diacritical sensitive.
Example
See example for the command Get resource name.
See Also
SET RESOURCE PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get resource properties returns the attributes of the resource whose type is
passed in resType and whose ID number is passed in resID.
If you pass a valid resource file reference number in the parameter resFile, the resource is
searched for within that file only. If you do not pass the parameter resFile, the resource is
searched for within the current open resource files.
If the resource does not exist, Get resource properties returns 0 (zero) and sets the OK
variable to 0 (zero).
The numeric value returned by Get resource properties must be seen as a bit field value
whose bits have special meaning. For a description of the resource attributes and their
effects, please refer to the command SET RESOURCE PROPERTIES.
Example
See example for the command Get resource name.
See Also
SET RESOURCE NAME.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET RESOURCE PROPERTIES changes the attributes of the resource whose
type is passed in resType and whose ID number is passed in resID.
If you pass a valid resource file reference number in the parameter resFile, the resource is
searched for within that file only. If you do not pass the parameter resFile, the resource is
searched for within the current open resource files.
If the resource does not exist, SET RESOURCE PROPERTIES does nothing and sets the OK
variable to 0 (zero).
The numeric value you pass in resAttr must be seen as a bit field value whose bits have
special meaning. The following predefined constants are provided by 4th Dimension:
Constant Type Value
System heap resource mask Long Integer 64
System heap resource bit Long Integer 6
Purgeable resource mask Long Integer 32
Purgeable resource bit Long Integer 5
Locked resource mask Long Integer 16
Locked resource bit Long Integer 4
Protected resource mask Long Integer 8
Protected resource bit Long Integer 3
Preloaded resource mask Long Integer 4
Preloaded resource bit Long Integer 2
Changed resource mask Long Integer 2
Changed resource bit Long Integer 1
Using these constants, you can build any resource attributes value. See examples below.
You will usually use the attribute purgeable and, more rarely, Preloaded and Protected.
2. The following example makes the resource 'STR#' ID=17000 purgeable, but leaves the
other attributes unchanged:
$vlResAttr:=Get resource properties ('STR#';17000;$vhResFile)
SET RESOURCE PROPERTIES('STR#';17000;
$vlResAttr ?+ Purgeable resource bit;$vhMyResFile)
3. The following example makes the resource 'STR#' ID=17000 preloaded and non
purgeable:
SET RESOURCE PROPERTIES('STR#';17000;Preloaded resource mask;$vhResFile)
4. The following example makes the resource 'STR#' ID=17000 preloaded but purgeable:
SET RESOURCE PROPERTIES('STR#';17000;
Preloaded resource mask+Purgeable resource mask;$vhResFile)
See Also
SET RESOURCE NAME.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE RESOURCE deletes the resource whose type is passed in resType and
whose ID number is passed in resID.
If you pass a valid resource file reference number in the parameter resFile, the resource is
searched for within that file only. If you do not pass resFile, the resource is searched for
within the current open resource files.
If the resource does not exist, DELETE RESOURCE does nothing and sets the OK variable to
0 (zero). If the resource is found and deleted, the OK variable is set to 1.
WARNING: DO NOT delete resources that belong to 4D or to any System files. If you do
so, you may provoke undesired system errors.
Examples
1. The following example deletes the resource "STR#" ID=20000:
` Note that this example will delete the first "STR#" ID=20000 resource
` found in any resource file currently open:
⇒ DELETE RESOURCE ("STR#";20000)
2. The following example deletes the resource "STR#" ID=20000 if it is found in a specified
resource file:
` Note that this example will delete the resource "STR#" ID=20000
` only if it is present in the resource file specified by $vhResFile:
⇒ DELETE RESOURCE ("STR#";20000;$vhResFile)
` Note also that if there is such a resource in a currently open
` resource file other than that specified by $vhResFile, this resource
` is left untouched
C_TIME($1)
C_STRING(4;$2)
RESOURCE LIST($2;$aiResID;$asResName;$1)
If(OK=1)
For($vlElem;1;Size of array($aiResID))
⇒ DELETE RESOURCE($2;$aiResID{$vlElem};$1)
End for
End if
4. The project method DELETE RESOURCE BY NAME deletes a resource (of a specific type)
whose name is known:
` DELETE RESOURCE BY NAME Project Method
` DELETE RESOURCE BY NAME ( Time ; String ; String )
` DELETE RESOURCE BY NAME ( resFile ; resType ; resName )
C_TIME($1)
C_STRING(4;$2)
C_STRING(255;$3)
RESOURCE LIST($2;$aiResID;$asResName;$1)
If(OK=1)
$vlElem:=Find in array($asResName;$3)
If($vlElem>0)
⇒ DELETE RESOURCE($2;$aiResID{$vlElem};$1)
End for
End if
See Also
RESOURCE LIST, SET RESOURCE PROPERTIES.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get component resource ID allows component developers to verify that
their customized PICT or STR# resource calls will be properly executed even though the
resource numbers have been modified while installing the component.
Indeed, when 4D Insider installs a component requiring its own resources, the application
can automatically renumber these new resources if some database resources already have
the same ID.
Note: For further information on components in 4th Dimension, refer to the 4D Insider
documentation.
The command Get component resource ID reveals the current (actual) number for each
resource used by a component, based on its type and its original number.
In resType, you put the resource type (4 characters only). The Get component resource ID
command only accepts resources of type PICT and STR#.
Note: Pictures stored in the Picture Library are NOT managed by the Get component
resource ID command. To use Picture Library pictures in a 4D component, you must call
the GET PICTURE FROM LIBRARY command and pass a String (picture name) as a first
parameter. For more information, refer to the GET PICTURE FROM LIBRARY command
description.
Put in originalResNum the original resource number, i.e. the number defined at the design
stage.
The function then returns the current resource ID used by the database.
See Also
GET SERIAL INFORMATION.
Secured Protocol
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GENERATE ENCRYPTION KEYPAIR generates a new pair of RSA keys. The
security system offered in 4D is based on keys designed to encrypt/decrypt information.
They can be used within the SSL protocol, with 4D Web server (encryption and secured
communications) and in all databases (for data encryption).
Once the command has been executed, the BLOBs passed in privKey and pubKey
parameters contain a new pair of encryption keys.
The optional parameter length can be used to set the key size (in bits). The larger the key,
the more difficult it is to break the encryption code.
However, large keys require longer execution or reply time, especially within a SSL
connection.
By default (if the length parameter is omitted), the generated key size is set to 512 bits,
which is a good compromise for the security/efficiency ratio. To increase the security
factor, you can change keys more often, for example every six months.
You can generate 1024 bits keys to increase the encryption security but the Web
application connections will be slowed down.
Notes:
• If you generate keys in order to establish a SSL certificate request, pay attention to the
fact that only 512 bits and 1024 bits key length are admitted.
• Many browsers will not accept keys with a length greater than 512 bits. Additionaly, the
"Export" version of the encryption system library which is provided by default by 4D,
Inc., does not provide support for key length greater than 512 bits. For more
information, please refer to the section Web Services, Using SSL Protocol).
This command will generate keys at the PKCS standard format, which means that their
content can be copied/pasted in an email without any change. Once the pair of keys has
been generated, a text document can be produced (using the BLOB TO DOCUMENT
command for example) and the keys can be stored in a safe place.
This encryption mode is also used by the first syntax of the ENCRYPT BLOB and DECRYPT
BLOB commands. The public key should be confidentially published.
It is possible to mix the public and private keys from two persons to encrypt information
so that the recipient is the only person to be able to decrypt them and the sender is the
only person to have encrypted them. This principle is given by the two commands
ENCRYPT BLOB and DECRYPT BLOB second syntax.
Example
See example for command ENCRYPT BLOB.
See Also
DECRYPT BLOB, ENCRYPT BLOB, GENERATE CERTIFICATE REQUEST.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GENERATE CERTIFICATE REQUEST generates a certificate request at the PKCS
format which can be directly used by certificate authorities such as Verisign(R). The
certificate plays an important part in the SSL secured protocol. It is sent to each browser
connecting in SSL mode. It contains the “ID card” of the Web site (made from the
information entered in the command), as well as its public key allowing the browsers to
decrypt the received information. Furthermore, the certificate contains various
information added by the certificate authority which guarantees its integrity.
Note: For more information on the SSL protocol use with 4D Web server, refer to the
section Web Services, Using SSL Protocol.
The certificate request uses keypairs generated with the command GENERATE
ENCRYPTION KEYPAIR and contains various information. The certificate authority will
generate its certificate combining this request with other parameters.
Pass in privKey a BLOB containing the private key generated with the command
GENERATE ENCRYPTION KEYPAIR.
Pass in certifRequest an empty BLOB. Once the command has been executed, it contains
the certificate request at the PKCS format. You can store this request in a text file, for
example using the BLOB TO DOCUMENT command, to submit it to the certificate
authority.
Warning: The private key is used to generate the request but should NOT be sent to the
certificate authority.
The code and information content entering order does not matter, however the two
arrays must be synchronized: if the third item of the codeArray contains the value 15
(locality name), the nameArray third item should contain this information, in our
example San Jose.
Example
A “Certificate request” form contains the six fields necessary for a standard certificate
request. The Generate button creates a document on disk containing the certificate
request. The “Privatekey.txt” document containing the private key (generated with the
GENERATE ENCRYPTION KEYPAIR command) should be on the disk:
C_BLOB($vbprivateKey;$vbcertifRequest)
C_LONGINT($tableNum)
ARRAY LONGINT($tLCodes;6)
ARRAY STRING(80;$tSInfos;6)
See Also
GENERATE ENCRYPTION KEYPAIR.
Selection
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
ALL RECORDS selects all the records of table for the current process. ALL RECORDS makes
the first record the current record and loads the record from disk. ALL RECORDS returns
the records to the default record order, which is the order in which the records are stored
on disk.
Example
The following example displays all the records from the [People] table:
See Also
DISPLAY SELECTION, MODIFY SELECTION, ORDER BY, QUERY, Records in selection, Records
in table.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Records in selection returns the number of records in the current selection of table. In
contrast, Records in table returns the total number of records in the table.
Example
The following example shows a loop technique commonly used to move through all the
records in a selection. The same action can also be accomplished with the APPLY TO
SELECTION command:
FIRST RECORD ([People]) ` Start at first record in the selection
⇒ For ($vlRecord; 1; Records in selection ([People])) ` Loop once for each record
Do Something ` Do something with the record
NEXT RECORD ([People]) ` Move to the next record
End for
See Also
Records in table.
version 5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DELETE SELECTION deletes the current selection of records from table. If the current
selection is empty, DELETE SELECTION has no effect. After the records are deleted, the
current selection is empty. Records that are deleted during a transaction are locked to
other users and other processes until the transaction is validated or canceled.
The Completely Delete option in the Table Properties dialog box allows you to increase
the speed of deletions when DELETE SELECTION is used.
Examples
1. The following example displays all the records from the [People] table and allows the
user to select which ones to delete. The example has two sections. The first is a method to
display the records. The second is an object method for a Delete button. Here is the first
method:
ALL RECORDS ([People]) ` Select all records
OUTPUT FORM ([People]; "Listing") ` Set the form to list the records
DISPLAY SELECTION ([People]) ` Display all records
The following is the object method for the Delete button, which appears in the Footer
area of the output form. The object method uses the records the user selected (the
UserSet) to delete the selection. Note that if the user did not select any records, DELETE
SELECTION has no effect.
` Confirm that the user really wants to delete the records
CONFIRM("You selected "+String(Records in set ("UserSet"))+" people to delete."
+Char(13)+"Click OK to Delete them.")
If (OK=1)
USE SET ("UserSet") ` Use the records chosen by the user
⇒ DELETE SELECTION([People]) ` Delete the selection of records
End if
ALL RECORDS ([People]) ` Select all records
See Also
DISPLAY SELECTION, MODIFY SELECTION, Record Locking, Sets.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Selected record number returns the position of the current record within the current
selection of table.
If the selection is not empty and if the current record is within the selection, Selected
record number returns a value between 1 and Records in selection. If the selection is empty,
of if there is no current record, it returns 0 (zero).
The selected record number is not the same as the number returned by Record number,
which returns the physical record number in the table. The selected record number
depends on the current selection and the current record.
Example
The following example saves the current selected record number in a variable:
See Also
About Record Numbers, GOTO SELECTED RECORD, Records in selection.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GOTO SELECTED RECORD moves to the specified record in the current selection of table
and makes that record the current record. The current selection does not change. The
record parameter is not the same as the number returned by Record number; it represents
the record’s position in the current selection. The record’s position depends on how the
selection is made and whether or not the selection is sorted.
If there are no records in the current selection, or the number is not in the selection,
then GOTO SELECTED RECORD does nothing.
Example
The following example loads data from the field [People]Last Name into the atNames. An
array of long integers, called alRecNum, is filled with numbers that will represent the
selected record numbers. Both arrays are then sorted:
If the array atNames is displayed in a scrollable area, the user can click one of the items.
Since the sorting of the two arrays is synchronized, any element in alRecNum provides
the selected record number for the record whose name is stored in the corresponding
element in atNames.
See Also
Selected record number.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
FIRST RECORD makes the first record of the current selection of table the current record,
and loads the record from disk. All query, selection, and sorting commands also set the
current record to the first record. If the current selection is empty, FIRST RECORD has no
effect.
This command is most often used after the USE SET command to begin looping through a
selection of records from the first record. However, you can also call it from a subroutine
if you are not sure whether or not the current record is actually the first.
Example
The following example makes the first record of the [Customers] table the first record:
See Also
Before selection, End selection, LAST RECORD, NEXT RECORD, PREVIOUS RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
NEXT RECORD moves the current record pointer to the next record in the current
selection of table for the current process. If the current selection is empty, or if Before
selection or End selection is TRUE, NEXT RECORD has no effect.
If NEXT RECORD moves the current record pointer past the end of the current selection,
End selection returns TRUE, and there is no current record. If End selection returns TRUE,
use FIRST RECORD, LAST RECORD, or GOTO SELECTED RECORD to move the current record
pointer back into the current selection.
Example
See the example for DISPLAY RECORD.
See Also
Before selection, End selection, FIRST RECORD, LAST RECORD, PREVIOUS RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
LAST RECORD makes the last record of the current selection of table the current record
and loads the record from disk. If the current selection is empty, LAST RECORD has no
effect.
Example
The following example makes the last record of the [People] table the current record:
See Also
Before selection, End selection, FIRST RECORD, NEXT RECORD, PREVIOUS RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PREVIOUS RECORD moves the current record pointer to the previous record in the current
selection of table for the current process. If the current selection is empty, or if Before
selection or End selection is TRUE, PREVIOUS RECORD has no effect.
If PREVIOUS RECORD moves the current record pointer before the current selection, Before
selection returns TRUE, and there is no current record. If Before selection returns TRUE, use
FIRST RECORD, LAST RECORD, or GOTO SELECTED RECORD to move the current record
pointer back into the current selection.
See Also
Before selection, End selection, FIRST RECORD, LAST RECORD, NEXT RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Before selection returns TRUE when the current record pointer is before the first record of
the current selection of table. Before selection is commonly used to check whether or not
PREVIOUS RECORD has moved the current record pointer before the first record. If the
current selection is empty, Before selection returns TRUE.
To move the current record pointer back into the selection, use LAST RECORD, FIRST
RECORD, or GOTO SELECTED RECORD. NEXT RECORD does not move the pointer back
into the selection.
Before selection also returns TRUE in the first header when a report is being printed with
PRINT SELECTION or from the Print menu. You can use the following code to test for the
first header and print a special header for the first page:
` Method of a form being used as output form for a summary report
$vpFormTable:=Current form table
Case of
` ...
: (Form event=On Header)
` A header area is about to be printed
Case of
⇒ : (Before selection($vpFormTable->))
` Code for the first break header goes here
` ...
End case
End case
See Also
End selection, FIRST RECORD, Form event, PREVIOUS RECORD, PRINT SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
End selection returns TRUE when the current record pointer is beyond the last record of
the current selection of table. End selection is commonly used to check whether or not
NEXT RECORD has moved the current record pointer past the last record. If the current
selection is empty, End selection returns TRUE.
To move the current record pointer back into the selection, use LAST RECORD, FIRST
RECORD, or GOTO SELECTED RECORD. PREVIOUS RECORD does not move the pointer back
into the selection.
End selection also returns TRUE in the last footer when a report is being printed with
PRINT SELECTION or from the Print menu. You can use the following code to test for the
last footer and print a special footer for the last page:
` Method of a form being used as output form for a summary report
$vpFormTable:=Current form table
Case of
` ...
: (Form event=On Printing Footer)
` A footer is about to be printed
⇒ If(End selection($vpFormTable->))
` Code for the last footer goes here
Else
` Code for a footer goes here
End if
End case
See Also
Before selection, Form event, LAST RECORD, NEXT RECORD, PRINT SELECTION.
Description
DISPLAY SELECTION displays the selection of table, using the output form. The records are
displayed in a scrollable list similar to the User environment’s list. If the user double-clicks
a record, the record is displayed in the input form. The list is displayed in the frontmost
window.
To display a selection and also modify a record after you have double-clicked on it (as you
do in the User environment window), use MODIFY SELECTION instead of DISPLAY
SELECTION.
All of the following information applies to both commands, except for the information
on modifying records.
The following figure shows an output form displayed by the DISPLAY SELECTION
command.
After DISPLAY SELECTION is executed, there may not be a current record. Use a command
such as FIRST RECORD or LAST RECORD to select one.
A button labeled Done is automatically included at the bottom of the list. Adding any
variable or active object on the form removes the Done button. Clicking this button exits
the command. Custom buttons may be used instead; you can put these buttons in the
Footer area of the output form. You can use automatic Accept or Cancel buttons to exit,
or use an object method that calls ACCEPT or CANCEL.
The user can scroll through the selection and click a record to select it. If the user clicks a
different record, the first record is deselected and the second record is selected. A user can
select a group of contiguous records by clicking the first record and Shift+clicking
(Windows or Macintosh) the last record. To select records that are not adjacent, the user
can Ctrl+click (Windows) or Command-click (Macintosh) each record.
During and after execution of DISPLAY SELECTION, the records that the user highlighted
(selected) are kept in a set named UserSet. The UserSet is available within the selection
display for object methods when a button is clicked or a menu item is chosen. It is also
available to the project method that called DISPLAY SELECTION after the command was
completed.
Examples
1. The following example selects all the records in the [People] table. It then uses DISPLAY
SELECTION to display the records, and allows the user to select the records to print.
Finally, it selects the records with USE SET, and prints them with PRINT SELECTION:
ALL RECORDS([People]) ` Select all records
⇒ DISPLAY SELECTION ([People]; *) ` Display the records
USE SET ("UserSet") ` Use only records picked by user
PRINT SELECTION ([People]) ` Print the records that the user picked
2. See example #6 for the Form event command. This example shows all the tests you may
need to check in order to fully monitor the events that occur during a DISPLAY
SELECTION.
You can also use other commands, such as PRINT SELECTION, REPORT, and so on, to
provide all the “standard” menu options you may want each time you display or modify
a selection in the Custom Menus environment. Thanks to the Current form table
command, these methods are generic, and the menu bar they support can be attached to
any output form of any table.
See Also
Form event, MODIFY SELECTION, Sets.
Description
MODIFY SELECTION does almost the same thing as DISPLAY SELECTION. Refer to the
description of DISPLAY SELECTION for details. The differences between the two commands
are:
1. DISPLAY SELECTION enables you to display the current selected records in list mode, or
in the input form when you double-click on a record. Using MODIFY SELECTION, you can
modify a record when you double-click on it, if it is not already in use by another process
or user.
See Also
DISPLAY SELECTION, Form event, Sets.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
APPLY TO SELECTION applies statement to each record in the current selection of table.
The statement can be a statement or a method. If statement modifies a record of table, the
modified record is saved. If statement does not modify a record, the record is not saved. If
the current selection is empty, APPLY TO SELECTION has no effect. If the relation is
automatic, the statement can contain a field from a related table.
APPLY TO SELECTION can be used to gather information from the selection of records (for
example, a total), or to modify a selection (for example, changing the first letter of a field
to uppercase). If this command is used within a transaction, all changes can be undone if
the transaction is canceled.
4D Server: The server does not execute any of the commands that may be passed in
statement. Every record in the selection will be sent back to the local workstation to be
modified.
The progress thermometer is displayed while APPLY TO SELECTION is executing. To hide it,
use MESSAGES OFF prior to the call to APPLY TO SELECTION. If the progress thermometer
is displayed, the user can cancel the operation.
Examples
1. The following example changes all the names in the table [Employees] to uppercase:
See Also
Sets.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
REDUCE SELECTION creates a new selection of records for table. The command returns the
first Number of records from the current selection table. REDUCE SELECTION is applied to
the current selection of table in the current process. It changes the current selection of
table for the current process; the first record of the new selection is the current record.
Example
The following example first finds the correct statistics for a worldwide contest among the
dealers in over 20 countries. For each country, the 3 best dealers who have sold product
worth more than $50,000 and who are among the 100 best dealers in the world are
awarded a prize. With a few lines of code, this complex request can be executed by using
indexed searches:
CREATE EMPTY SET([Dealers];"Winners") ` Create an empty set
SCAN INDEX([Dealers]Sales amount;100;<) ` Scan from the end of the index
CREATE SET([Dealers];"100 best Dealers") ` Put the selected records in a set
For ($Country;1;Records in table([Countries])) ` For each Country
` Search for the dealers in this country who sold for more than $50000
QUERY([Dealers];[Dealers]Country=[Countries]Name;*)
QUERY(&;[Dealers];[Dealers]Sales amount>=50000)
CREATE SET([Dealers];"WinnerDealers") ` Put them in a set
` They should be in the group of 100 best dealers
INTERSECTION("WinnerDealers";"100 best Dealers";"WinnerDealers")
USE SET("WinnerDealers") ` Potential winners for the country
` Sort them by the results in descending order
ORDER BY([Dealers];[Dealers]Sales amount;<)
⇒ REDUCE SELECTION([Dealers];3) ` Take the 3 best Dealers
CREATE SET([Dealers];"WinnerDealers") ` The winners for the country
` Put them in the worldwide winners list
UNION("WinnerDealers";"TheWinners";"TheWinners")
End for
See Also
ORDER BY, QUERY, SCAN INDEX, Sets.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SCAN INDEX returns a selection of number records for table. If you pass <, SCAN INDEX
returns the number of records from the end of the index (high values). If you pass >,
SCAN INDEX returns the number of records for table from the beginning of the index (low
values). This command is very efficient because it uses the index to perform the
operation.
SCAN INDEX works only on indexed fields. This command changes the current selection
of the table for the current process, but there is no current record.
If you specify more records than exist in the table, SCAN INDEX will return all records.
Example
The following example mails letters to 50 of the worst customers and then to 50 of the
best customers:
See Also
ORDER BY, QUERY, REDUCE SELECTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
ONE RECORD SELECT reduces the current selection of table to the current record. If no
current record exists, ONE RECORD SELECT has no effect.
Historical Note: This command was useful to “get back” into the selection a record that
had been pushed and popped from the record stack while the selection for the table was
changed. In version 6, SET QUERY DESTINATION allows you to make a query without
changing the selection or the current record of a table; therefore, you no longer need to
push and pop a current record in order to query its table. Consequently, ONE RECORD
SELECT is less useful, unless you actually want to reduce the selection of a table to the
current record.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command HIGHLIGHT RECORDS allows you to highlight records in an output form.
This operation is identical to manually selecting records in list mode by using the mouse
or the Shift+Click or Ctrl+Click (Command+Click on MacOS) keyboard equivalents.
The “selected” records will be highlighted. The current selection is not modified.
Note: The Userset set is updated after redrawing the records; that is, after executing the
entire calling method — and not just immediately after executing HIGHLIGHT RECORDS.
• If you pass a valid set name to setName, the command will be applied to the records in
that set.
• If you omit the setName parameter, the command will only highlight the records in the
current Userset set.
Example
In an output form displayed by the MODIFY SELECTION command, you want the user to
be able to perform searches without the current selection being modified. To do so, place
a Search button in the form and associate to it the following method:
SET QUERY DESTINATION(Into Set;"UserSet")
QUERY
SET QUERY DESTINATION(Into Current Selection)
⇒ HIGHLIGHT RECORDS
When the user clicks the button, the standard query dialog box appears. Once the search
has been validated, the records found will be highlighted without the current selection
being modified.
Sets
Sets offer you a powerful, swift means for manipulating record selections. Besides the
ability to create sets, relate them to the current selection, and store, load, and clear sets,
4th Dimension offers three standard set operations:
• Intersection
• Union
• Difference
A set is a compact representation of a selection of records. The idea of sets is closely bound
to the idea of the current selection. Sets are generally used for the following purposes:
• To save and later restore a selection when the order does not matter
• To access the selection a user made on screen (the UserSet)
• To perform a logical operation between selections
The current selection is a list of references that points to each record that is currently
selected. The list exists in memory. Only currenly selected records are in the list. A
selection doesn’t actually contain the records, but only a list of references to the records.
Each reference to a record takes 4 bytes in memory. When you work on a table, you
always work with the records in the current selection. When a selection is sorted, only the
list of references is rearranged. There is only one current selection for each table inside a
process.
Like a current selection, a set represents a selection of records. A set does this by using a
very compact representation for each record. Each record is represented by one bit (one-
eighth of a byte). Operations using sets are very fast, because computers can perform
operations on bits very quickly. A set contains one bit for every record in the table,
whether the record is included in the set or not. In fact, each bit is equal to 1 or 0,
depending on whether the record is in the set or not.
Sets are very economical in terms of RAM space. The size of a set, in bytes, is always equal
to the total number of records in the table divided by 8. For example, if you create a set
for a table containing 10,000 records, the set takes up 1,250 bytes, which is about 1.2K in
RAM.
There can be many sets for each table. In fact, sets can be saved to disk separately from
the database. To change a record belonging to a set, first you must use the set as the
current selection, then modify the record or records. The name of an interprocess set
must be unique in the database.
A set “remembers” which record was the current record at the time the set was created.
The following table compares the concepts of the current selection and of sets:
Comparison Current Selection Sets
Number per table 1 0 to many
Sortable Yes No
Can be saved on disk No Yes
RAM per record(in bytes) Number of Total number of
selected records * 4 records/8
Combinable No Yes
Contains current record Yes Yes, as of the time the set
was created
When you create a set, it belongs to the table from which you created it. The set
operations can be performed only between sets belonging to the same table.
Sets are independent from the data. This means that after changes are made to a file, a set
may no longer be accurate. There are many operations that can cause a set to be
inaccurate. For example, if you create a set of all the people from New York City, and
then change the data in one of those records to “Boston” the set would not change,
because the set is just a representation of a selection of records. Deleting records and
replacing them with new ones also changes a set. Sets can be guaranteed to be accurate
only as long as the data in the original selection has not been changed.
A set can be created inside a transaction. It is possible to create a set of the records created
inside a transaction and a set of records created or modified outside of a transaction.
When the transaction ends, the set created during the transaction should be cleared,
because it may not be an accurate representation of the records, especially if the
transaction was canceled.
Set Example
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following example deletes duplicate records from a table which contains information
about people. A For...End for loop moves through all the records, comparing the current
record to the previous record. If the name, address, and zip code are the same, then the
record is added to a set. At the end of the loop, the set is made the current selection and
the (old) current selection is deleted:
As an alternative to immediately deleting records at the end of the method, you could
display them on screen or print them, so that a more detailed comparison can be made.
4th Dimension maintains a system set named UserSet. UserSet automatically stores the
most recent selection of records highlighted on screen by the user. Thus, you can display
a group of records with MODIFY SELECTION or DISPLAY SELECTION, ask the user to select
from among them, and turn the results of that manual selection into a selection or into a
set that you name.
There is only one UserSet for a process. Each table does not have its own UserSet. UserSet
becomes “owned” by a table when a selection of records is displayed for the table.
The following method illustrates how you can display records, allow the user to select
some, and then use UserSet to display the selected records:
` Display all records and allow user to select any number of them.
` Then display this selection by using UserSet to change the current selection.
OUTPUT FORM ([People]; "Display") ` Set the output layout
ALL RECORDS ([People]) ` Select all people
ALERT ("Press Ctrl or Command and Click to select the people required.")
DISPLAY SELECTION ([People]) ` Display the people
USE SET ("UserSet") ` Use the people that were selected
ALERT ("You chose the following people.")
DISPLAY SELECTION ([People]) ` Display the selected people
Note: You must execute either MODIFY SELECTION or DISPLAY SELECTION to retrieve the
UserSet.
The command APPLY TO SELECTION, ARRAY TO SELECTION and DELETE SELECTION create
a set named LockedSet when used in multi-processing environment. LockedSet indicates
which records were locked during the execution of the command.
See Also
ADD TO SET, CLEAR SET, COPY SET, CREATE EMPTY SET, CREATE SET, DIFFERENCE,
INTERSECTION, Is in set, LOAD SET, Records in set, REMOVE FROM SET, SAVE SET, UNION,
USE SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CREATE EMPTY SET creates a new empty set, set, for table. You can add records to this set
with the ADD TO SET command. If a set with the same name already exists, the existing
set is cleared by the new set.
Note: You do not need to use CREATE EMPTY SET before using CREATE SET.
Example
Please refer to the examples of the Sets section.
See Also
CLEAR SET, CREATE SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CREATE SET creates a new set, set, for table, and places the current selection in set. The
current record pointer for the table is saved with set. If set is used with USE SET, the
current selection and current record are restored. As with all sets, there is no sorted order;
when set is used, the default order is used. If a set with the same name already exists, the
existing set is cleared by the new set.
Example
The following example creates a set after doing a search, in order to save the set to disk:
QUERY ([People]) ` Let the user do a search
⇒ CREATE SET ([People]; "SearchSet") ` Create a new set
SAVE SET ("SearchSet"; "MySearch") ` Save the set on disk
See Also
CLEAR SET, CREATE EMPTY SET.
Description
The command CREATE SET FROM ARRAY creates setName from:
• either an array of absolute record numbers recordsArray from table,
• or an array of booleans recordsArray. In this case, the values of the array indicate if each
record in the table belongs (True) or not (False) to setName.
When you use this command and pass a Longint array in recordsArray, all the numbers in
the array represent the list of record numbers that are in setName. If a number is invalid
(for example, if a record has not been created), the error -10503 is generated.
When you use this command and pass a Boolean array in recordsArray, the Nth element
of the array indicates whether the "Nth" record is contained (True) or not (False) in
setName. Usually, the number of elements in the array must equal the number of records
in the table. If the array is smaller than the number of records, only the records defined
by the array will be in the set.
Note: With a Boolean array, this command uses the elements from 0 to N-1.
If you do not pass the setName parameter or if you pass an empty string, the command
will be applied to the Userset system set.
See Also
BOOLEAN ARRAY FROM SET, CREATE SELECTION FROM ARRAY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
USE SET makes the records in set the current selection for the table to which the set
belongs.
When you create a set, the current record is “remembered” by the set. USE SET retrieves
the position of this record and makes the it the new current record. If you delete this
record before you execute USE SET, 4th Dimension selects the first record in the set as the
current record. The set commands INTERSECTION, UNION, DIFFERENCE, and ADD TO SET
reset the current record. Also, if you create a set that does not contain the position of the
current record, USE SET selects the first record in the set as the current record.
Example
The following example uses LOAD SET to load a set of the Acme locations in New York. It
then uses USE SET to make the loaded set the current selection:
LOAD SET ([Companies]; "NY Acme"; "NYAcmeSt") ` Load the set into memory
⇒ USE SET ("NY Acme") ` Change current selection to NY Acme
CLEAR SET ("NY Acme") ` Clear the set from memory
See Also
CLEAR SET, LOAD SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
ADD TO SET adds the current record of table to set. The set must already exist; if it does
not, an error occurs. If a current record does not exist for Table, ADD TO SET has no effect.
See Also
REMOVE FROM SET.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
REMOVE FROM SET removes the current record of table from set. The set must already
exist; if it does not, an error occurs. If a current record does not exist for Table, REMOVE
FROM SET has no effect.
See Also
ADD TO SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CLEAR SET clears set from memory and frees the memory used by set. CLEAR SET does not
affect tables, selections, or records. To save a set before clearing it, use the SAVE SET
command. Since sets use memory, it is good practice to clear them when they are no
longer needed.
Example
See the example for USE SET.
See Also
CREATE EMPTY SET, CREATE SET, LOAD SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Is in set tests whether or not the current record for the table is in set. The Is in set function
returns TRUE if the current record of the table is in set, and returns FALSE if the current
record of the table is not in set.
Example
The following example is a button object method. It tests to see whether or not the
currently displayed record is in the set of best customers:
See Also
ADD TO SET, REMOVE FROM SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Records in set returns the number of records in set. If set does not exist, or if there are no
records in set, Records in set returns 0.
Example
The following example displays an alert telling what percentage of the customers are rated
as the best:
` First calculate the percentage
⇒ $Percent := (Records in set ("Best") / Records in table ([Customers])) * 100
` Display an alert with the percentage
ALERT (String ($Percent; "##0%") + " of our customers are the best.")
See Also
Records in selection, Records in table.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SAVE SET saves Set to document, a document on disk.
The document need not have the same name as the set. If you supply an empty string for
document, a Create File dialog box appears so that the user can enter the name of the
document. You can load a saved set with the LOAD SET command.
If the user clicks Cancel in the Save File dialog box, or if there is an error during the save
operation, the OK system variable is set to 0. Otherwise, it is set to 1.
SAVE SET is often used to save to disk the results of a time-consuming search.
Example
The following example displays the Save File dialog box, wihch the user can enter the
name of the document that contains the set:
See Also
LOAD SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
LOAD SET loads a set from document that was saved with the SAVE SET command.
The set that is stored in document must be from table. The set created in memory is
overwritten if it already exists.
The document parameter is the name of the disk document containing the set. The
document need not have the same name as the set. If you supply an empty string for
document, an Open File dialog box appears so that the user can choose the set to load.
Remember that a set is a representation of a selection of records at the moment that the
set is created. If the records represented by the set change, the set may no longer be
accurate. Therefore, a set loaded from disk should represent a group of records that does
not change frequently. A number of things can make a set invalid: modifying a record of
the set, deleting a record of the set, or changing the criteria that determined a set.
Example
The following example uses LOAD SET to load a set of the Acme locations in New York:
⇒ LOAD SET ([Companies]; "NY Acme"; "NYAcmeSt") ` Load the set into memory
USE SET ("NY Acme") ` Change current selection to NY Acme
CLEAR SET ("NY Acme") ` Clear the set from memory
See Also
SAVE SET.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DIFFERENCE compares set1 and set2 and excludes all records that are in set2 from the
resultSet. In other words, a record is included in the resultSet only if it is in set1, but not
in set2. The following table shows all possible results of a set Difference operation.
The result of a Difference operation is depicted here. The shaded area is the result set.
The resultSet is created by DIFFERENCE. The resultSet replaces any existing set having the
same name, including set1 and set2. Both set1 and set2 must be from the same table. The
resultSet belongs to the same table as set1 and set2.
4D Server: In Client/Server, interprocess and process sets are maintained on the server
machine, while local sets are maintained on the client machines. DIFFERENCE requires the
three sets to be on the same machine. Consequently, all or none of the sets must be local.
See the discussion 4D Server and Sets in the 4D Server Reference manual for more
information.
At the bottom of the list of records is a button with an object method. The object method
excludes the records that the user has selected (the set named “UserSet”), and displays the
reduced selection:
CREATE SET ([Customers]; "$Current") ` Create a set of current selection
⇒ DIFFERENCE ("$Current";"UserSet";"$Current") ` Exclude selected records
USE SET ("$Current") ` Use the new set
CLEAR SET ("$Current") ` Clear the set
See Also
INTERSECTION, UNION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
INTERSECTION compares set1 and set2 and selects only the records that are in both. The
following table lists all possible results of a set Intersection operation.
The graphical result of an Intersection operation is displayed here. The shaded area is the
result set.
The resultSet is created by INTERSECTION. The resultSet replaces any existing set having
the same name, including set1 and set2. Both set1 and set2 must be from the same table.
The resultSet belongs to the same table as set1 and set2.
4D Server: In Client/Server, interprocess and process sets are maintained on the server
machine, while local sets are maintained on the client machines. INTERSECTION requires
the three sets to be on the same machine. Consequently, all or none of the sets must be
local. See the discussion 4D Server and Sets in the 4D Server Reference manual for more
information.
See Also
DIFFERENCE, UNION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
UNION creates a set that contains all records from set1 and set2. The following table
shows all possible results of a set Union operation.
The result of a Union operation is depicted here. The shaded area is the result set.
The resultSet is created by UNION. The resultSet replaces any existing set having the same
name, including set1 and set2. Both set1 and set2 must be from the same table. The
resultSet belongs to the same table as set1 and set2. The current record for the resultSet is
the current record from Set1.
4D Server: In Client/Server, interprocess and process sets are maintained on the server
machine, while local sets are maintained on the client machines. UNION requires the
three sets to be on the same machine. Consequently, all or none of the sets must be local.
See the discussion 4D Server and Sets in the 4D Server Reference manual for more
information.
See Also
DIFFERENCE, INTERSECTION.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command COPY SET copies the contents of the set srcSet into the set dstSet.
4D Server: In Client/Server, interprocess and process sets are maintained on the server
machine, while local sets are maintained on the client machines. COPY SET allows you to
copy sets between the two machines. See the discussion 4D Server and Sets in the 4D
Server Reference manual for more information.
Examples
1. The following example, in Client/Server, copies the local set "$SetA", maintained on the
client machine, to the process set "SetB", maintained on the server machine:
⇒ COPY SET("$SetA";"SetB")
(1) The following example, in Client/Server, copies the process set "SetA", maintained on
the server machine, to the local process set "$SetB", maintained on the client machine:
⇒ COPY SET("SetA";"$SetB")
See Also
Sets.
String
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command String returns the string form of the numeric, Date, or Time expression
you pass in expression.
If you do not pass the optional format parameter, the string is returned with the
appropriate default format. If you pass format, you can force the result string to be of a
specific format.
Numeric Expressions
If expression is a numeric expression (Real, Integer, Long Integer), you can pass an
optional string format. Following are some examples:
Example Result
String(2^15) ` Use default format 32768 (Default format used here)
String(2^15;"###,##0 Inhabitants") 32,768 Inhabitants
String(1/3;"##0.00000") 0.33333
String(1/3) ` Use default format 0.3333333333333333 (Default format used here)
String(Arctan(1)*4) 3.1415926535897931 (Default format used here)
String(Arctan(1)*4;"##0.00") 3.14
String(-1;"&x") 0xFFFFFFFF
String(-1;"&$") $FFFFFFFF
String(0 ?+ 7;"&x") 0x80
String(0 ?+ 7;"&$") $80
String(0 ?+ 14;"&x") 0x4000
String(0 ?+ 14;"&$") $4000
String(Num(1=1);"True;;False") True
String(Num(1=2);"True;;False") False
The format is specified in the same way as it would be for a number field on a form. See
the 4th Dimension Design Reference for more information about formatting numbers. You
can also pass the name of a custom style in format. The name of the custom style must be
preceded by the “|” character.
Time Expressions
If expression is a Time expression, the string is returned using the default HH:MM:SS
format. You can pass an optional numeric format from the following table:
Format Name Example
1 HH:MM:SS 01:02:03
2 HH:MM 01:02
3 hour min sec 1 hour 2 minutes 3 seconds
4 hour min 1 hour 2 minutes
5 H:MM AM/PM 1:02 AM
These examples assume that the current time is 5:30 PM and 45 seconds):
$vsResult:=String(Current time) ` $vsResult gets "17:30:45"
$vsResult:=String(Current time;Hour Min Sec) ` $vsResult gets "17 hours 30 minutes
45 seconds"
See Also
Date, Num, Time string.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Num returns the numeric form of the String or Boolean expression you
pass in expression.
String Expressions
If string consists only of one or more alphabetic characters, Num returns a zero. If string
includes alphabetic and numeric characters, Num ignores the alphabetic characters. Thus,
Num transforms the string "a1b2c3" into the number 123.
There are three reserved characters that Num treats specially: the decimal separator in the
US English version (i.e., the period “.”) , the hyphen “-”, and “e” or “E”. These characters
are interpreted as numeric format characters.
• The decimal separator is interpreted as a decimal place and must appear embedded in a
numeric string.
• The hyphen causes the number or exponent to be negative. The hyphen must appear
before any negative numeric characters or after the “e” for an exponent. If a hyphen is
embedded in a numeric string, the string is considered invalid and the Num function
returns a zero (0). For example, Num("123-456") returns 0, but Num("-9") returns -9.
• The e or E causes any numeric characters to its right to be interpreted as the power of an
exponent. The “e” must be embedded in a numeric string. Thus, Num("123e–2") returns
1.23.
Boolean Expressions
If you pass a Boolean expression, Num returns 1 if the expression is True; otherwise, it
returns 0 (zero).
2. Here, [Client]Debt is compared with $1000. The Num command applied to these
comparisons returns 1 or 0. Multiplying 1 or 0 with a string repeats the string once or
returns the empty string. As a result, [Client]Risk gets either “Good” or “Bad”:
` If client owes less than 1000, a good risk.
` If client owes more than 1000, a bad risk.
⇒ [Client]Risk:=("Good"*Num ([Client]Debt<1000))+("Bad"*Num([Client]Debt>=1000))
See Also
Logical Operators, String, String Operators.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Position returns the position of the first occurrence of find in string.
If Position locates an occurrence of find, it returns the position of the first character of the
occurrence in string.
If you ask for the position of an empty string within an empty string, Position returns
zero (0).
Warning: You cannot use the @ wildcard character with Position. For example, if you pass
"abc@" in find, the command will actually look for "abc@" and not for "abc" plus any
character.
Examples
1. This example illustrates the use of Position. The results, described in the comments, are
assigned to the variable vlResult.
⇒ vlResult := Position ("ll"; "Willow") ` vlResult gets 3
⇒ vlResult := Position (vtText1; vtText2) ` Returns first occurrence of vtText1 in vtText2
See Also
Comparison Operators, Substring.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Substring returns the portion of source defined by firstChar and numChars.
The firstChar parameter points to the first character in the string to return, and numChars
specifies how many characters to return.
If firstChar plus numChars is greater than the number of characters in the string, or if
numChars is not specified, Substring returns the last character(s) in the string, starting
with the character specified by firstChar. If firstChar is greater than the number of
characters in the string, Substring returns an empty string ("").
Examples
1. This example illustrates the use of Substring. The results, described in the comments, are
assigned to the variable vsResult.
⇒ vsResult := Substring ("08/04/62"; 4; 2) ` vsResult gets "04"
⇒ vsResult := Substring ("Emergency"; 1; 6) ` vsResult gets "Emerge"
⇒ vsResult := Substring (var; 2) ` vsResult gets all characters except ` the first
` EXTRACT PARAGRAPHS
` EXTRACT PARAGRAPHS ( text ; Pointer )
` EXTRACT PARAGRAPHS ( Text to parse ; -> Array of ¶s )
C_TEXT ($1)
C_POINTER ($2)
$vlElem:=Size of array($2->)
Repeat
$vlElem:=$vlElem+1
INSERT ELEMENT($2->;$vlElem)
$vlPos:=Position(Char(Carriage return);$1)
If ($vlPos>0)
⇒ $2->{$vlElem}:=Substring($1;1;$vlPos-1)
⇒ $1:=Substring($1;$vlPos+1)
Else
$2->{$vlElem}:=$1
End if
Until ($1="")
See Also
Position.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Length is used to find the length of string. Length returns the number of characters that
are in string.
Examples
This example illustrates the use of Length. The results, described in the comments, are
assigned to the variable vlResult.
⇒ vlResult := Length ("Topaz") ` vlResult gets 5
⇒ vlResult := Length ("Citizen") ` vlResult gets 7
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Ascii returns the ASCII code of character.
If there is more than one character in the string, Ascii returns the code of the first
character.
The Char function is the counterpart of Ascii. It returns the character that an ASCII code
represents.
Important: Within 4D, all the text values, fields, or variables that you have not yet
converted to another ASCII map are MacOS-encoded on both Macintosh and Windows.
For more information, see the section ASCII Codes.
Examples
1. Uppercase and lowercase characters are considered equal within a comparison. You can
use Ascii to differentiate between uppercase and lowercase characters. Thus, this line
returns True:
("A" = "a")
⇒ (Ascii("A")=Ascii("a"))
2. This example returns the ASCII value of the first character of the string "ABC":
When executed multiple times on large texts, this test will run faster when compiled if it
is written this way:
For($vlChar;1;Length(vtText))
⇒ $vlAscii:=Ascii(vtText[[$vlChar]])
Case of
: ($vlAscii=Carriage return)
` Do something
: ($vlAscii=Tab)
` Do something else
: (...)
` ...
End case
End for
The second piece of code runs faster for two reasons: it does only one character reference
by iteration and uses LongInt comparisons instead of string comparisons to test for
carriage returns and tabs. Use this technique when working with common ASCII codes
such as CR and TAB.
See Also
ASCII Codes, Char, Character Reference Symbols.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Char returns the character whose ASCII code is asciiCode.
Tip: In editing a method, the command Char is commonly used to specify characters that
cannot be entered from the keyboard or that would be interpreted as an editing
command in the Method editor.
Important: Within 4D, all the text values, fields, or variables that you have not yet
converted to another ASCII map are MacOS-encoded on both Macintosh and Windows.
For more information, see the section ASCII Codes.
Example
The following example uses Char to insert a carriage return within the text of an alert
message:
⇒ ALERT("Employees: "+String(Records in table([Employees]))+
Char(13)+"Press OK to continue.")
See Also
Ascii, ASCII Codes, Character Reference Symbols.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Introduction
The character reference symbols:
are used to refer to a single character within a string. This syntax allows you to
individually address the characters of a text variable, string variable, or field.
Note: On Macintosh, you obtain the first two symbols by typing Option+"<" and
Option+">".
If the character reference symbols appear on the left side of the assignment operator (:=),
a character is assigned to the referenced position in the string. For example, if vsName is
not an empty string, the following line sets the first character of vsName to uppercase:
If (vsName#"")
vsName[[1]]:=Uppercase(vsName[[1]])
End if
Otherwise, if the character reference symbols appear within an expression, they return
the character (to which they refer) as a 1-character string. For example:
` The following example tests if the last character of vtText is an At sign "@"
If (vtText # "")
If (Ascii(Substring(vtText;Length(vtText);1))=At Sign)
` ...
End if
End if
` Using the character reference syntax, you would write in a simpler manner:
If (vtText # "")
If (Ascii(vtText[[Length(vtText)]])=At Sign)
` ...
End if
End if
vsAnyText:=""
vsAnyText[[1]]:="A" ` Very bad and nasty thing to do, booh!
Example
The following project method capitalizes the first character of each word of the text
received as parameter and returns the resulting capitalized text:
` Capitalize text project method
` Capitalize text ( Text ) -> Text
` Capitalize text ( Source text ) -> Capitalized text
$0:=$1
$vlLen:=Length($0)
If ($vlLen>0)
$0[[1]]:=Uppercase($0[[1]])
For ($vlChar;1;$vlLen-1)
If (Position($0[[$vlChar]];" !&()-{}:;<>?/,.=+*")>0)
$0[[$vlChar+1]]:=Uppercase($0[[$vlChar+1]])
End if
End for
End if
See Also
Ascii, ASCII Codes, Char.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Uppercase takes string and returns the string with all alphabetic characters in uppercase.
Examples
See the example for Lowercase.
See Also
Lowercase.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Lowercase takes string and returns the string with all alphabetic characters in lowercase.
Example
The following project method capitalizes the string or text received as parameter. For
instance, Caps ("john") would return "John".
` Caps project method
` Caps ( String ) -> String
` Caps ( Any text or string ) -> Capitalized text
⇒ $0:=Lowercase($1)
If (Length($0)>0)
$0[[1]]:=Uppercase($0[[1]])
End if
See Also
Uppercase.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Change string changes a group of characters in source and returns the resulting string.
Change string overlays source, with the characters in newChars, at the character described
by where.
If newChars is an empty string (""), Change string returns source unchanged. Change string
always returns a string of the same length as source. If where is less than one or greater
than the length of source, Change string returns source.
Change string is different from Insert string in that it overwrites characters instead of
inserting them.
Example
The following example illustrates the use of Change string. The results are assigned to the
variable vtResult.
See Also
Delete string, Insert string, Replace string.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Insert string inserts a string into source and returns the resulting string. Insert string inserts
the string what before the character at position where.
If where is greater than the length of source, then what is appended to source. If where is
less than one (1), then what is inserted before source.
Insert string is different from Change string in that it inserts characters instead of
overwriting them.
Example
The following example illustrates the use of Insert string. The results are assigned to the
variable vtResult.
⇒ vtResult := Insert string ("The tree"; " green"; 4) ` vtResult gets "The green tree"
⇒ vtResult := Insert string ("Shut"; "o"; 3) ` vtResult gets "Shout"
⇒ vtResult := Insert string ("Indention"; "ta"; 6) ` vtResult gets "Indentation"
See Also
Change string, Delete string, Replace string.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Delete string deletes numChars from source, starting at where, and returns the resulting
string.
If where is less than one, the characters are deleted from the beginning of the string.
If where plus numChars is equal to or greater than the length of source, the characters are
deleted from where to the end of source.
Example
The following example illustrates the use of Delete string. The results are assigned to the
variable vtResult.
See Also
Change string, Insert string, Replace string.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Replace string replaces howMany occurrences of oldString in source with newString.
If newString is an empty string (""), Replace string deletes each occurrence of oldString in
source.
If howMany is specified, Replace string will replace only the number of occurrences of
oldString specified, starting at the first character of source. If howMany is not specified,
then all occurrences of oldString are replaced.
Examples
1. The following example illustrates the use of Replace string. The results, described in the
comments, are assigned to the variable vtResult.
See Also
Change string, Delete string, Insert string.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Mac to Win returns the text, expressed using the Windows ANSI map,
equivalent to the text you pass in Text, expressed using the MacOS ASCII map.
This command expects a text parameter expressed using the MacOS ASCII map.
Generally, when running on Windows, you do not need to use this command to convert
ASCII codes. When you copy or paste text between 4D and Windows or when you import
or export data, 4D automatically performs these conversions. However, when you use disk
read/write commands such as SEND PACKET or RECEIVE PACKET, you need to explicitly
invoke ASCII conversions. This is the main purpose of the Mac to Win command.
Within 4D, all the text values, fields, or variables that you have not yet converted to
another ASCII map are MacOS-encoded on both Macintosh and Windows. For more
information, see the section ASCII Codes.
Example
On Windows, when you write characters into a document using SEND PACKET, if you do
not use an output ASCII map for filtering characters from MacOS to Windows (see USE
ASCII MAP), you need to convert the text from MacOS to Windows yourself. You can do it
this way:
` ...
⇒ SEND PACKET ($vhDocRef;Mac to Win(vtSomeText))
` ...
See Also
ASCII Codes, SEND PACKET, USE ASCII MAP, Win to Mac.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Win to Mac returns text, expressed using the MacOS ASCII map, equivalent
to the text you pass in Text, expressed using the Windows ANSI map.
This command expects a text parameter expressed using the Windows ANSI map.
Generally, when running on Windows, you do not need to use this command to convert
ASCII codes. When you copy or paste text between 4D and Windows or when you import
or export data, 4D automatically performs these conversions. However, when you use disk
read/write commands such as SEND PACKET or RECEIVE PACKET, you need to explicitly
invoke ASCII conversions. This is the main purpose of the Win to Mac command.
Within 4D, all the text values, fields, or variables that you have not yet converted to
another ASCII map are MacOS-encoded on both Macintosh and Windows. For more
information, see the section ASCII Codes.
Example
When you read characters from a Windows document using RECEIVE PACKET, if you do
not use an input ASCII map for filtering characters from Windows to MacOS (see USE
ASCII MAP), you need to convert the text from Windows to MacOS yourself. You can do it
this way:
` ...
RECEIVE PACKET ($vhDocRef;vtSomeText;16*1024)
⇒ vtSomeText:=Win to Mac(vtSomeText)
` ...
See Also
ASCII Codes, Mac to Win, RECEIVE PACKET, USE ASCII MAP.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Function result String ← Text expressed using ISO Latin-1 character map
Description
The command Mac to ISO returns text, expressed using the ISO Latin-1 character map,
equivalent to the text you pass in text, expressed using the MacOS ASCII map.
This command expects a text parameter expressed using the MacOS ASCII map.
4D converts characters received from and sent to a Web Browser. As a result, the text
values you deal with, inside a Web Connection process, are always expressed using the
MacOS ASCII map.
Generally, when running on Windows, you do not need to convert ASCII codes. When
you copy or paste text between 4D and Windows or when you import or export data, 4D
automatically performs these conversions. However, when you use disk read/write
commands such as SEND PACKET or RECEIVE PACKET, you need to explicitly invoke ASCII
conversions.
Within 4D, all the text values, fields, or variables that you have not yet converted to
another ASCII map are MacOS-encoded on both Macintosh and Windows. For more
information, see the section ASCII Codes.
On Windows, it is necessary that, in this case, you do not filter the characters using an
output filter ASCII map.
Consequently, no matter what the platform, if you want to write ISO Latin-1 HTML
documents on disk, you just need to convert the text using Mac to ISO. This is the main
purpose of the Mac to ISO command.
⇒ vtSomeText:=Mac to ISO(vtSomeText)
2. While developing a 4D Web Server application, you build HTML documents that you
later send over Intranet or Internet, using the command SEND HTML FILE. Some of these
documents have references or links to other documents.
The following project method calculates an HTML-based pathname from the Windows or
Macintosh pathname received as parameter:
C_TEXT($0;$1)
C_LONGINT($vlChar;$vlAscii)
C_STRING(31;$vsChar)
$0:=""
If (On Windows )
$1:=Replace string($1;"\";"/")
Else
$1:=Replace string($1;":";"/")
End if
⇒ $1:=Mac to ISO($1)
For ($vlChar;1;Length($1))
$vlAscii:=Ascii($1[[$vlChar]])
Case of
: ($vlAscii>=127)
$vsChar:="%"+Substring(String($vlAscii;"&$");2)
: (Position(Char($vlAscii);":<>&%= "+Char(34))>0)
$vsChar:="%"+Substring(String($vlAscii;"&$");2)
Else
$vsChar:=Char($vlAscii)
End case
$0:=$0+$vsChar
End for
Note: The project method On Windows is listed in the section System Documents.
` ...
ARRAY STRING(31;$asDocuments;0)
DOCUMENT LIST(...;$asDocuments)
$vlNbDocuments:=Size of array($asDocuments)
jsHandler:=...
For ($vlDocument;1;$vlNbDocuments)
vtHTMLCode:=vtHTMLCode+"<P><A HREF="+Char(34)+<>vsFTPURL
+HTML Pathname
(Substring($1+$asDocuments{$vlDocument};Length(<>vsFTPDirectory)+1))
+Char(34)+jsHandler+">
"+$asDocuments{$vlDocument}+"</A></P>"+Char(13)
End for
` ...
See Also
ASCII Codes, ISO to Mac, SEND HTML FILE, SEND PACKET, USE ASCII MAP.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command ISO to Mac returns text, expressed using the MacOS ASCII map, equivalent
to the text you pass in text, expressed using the ISO Latin-1 character map.
This command expects a text parameter expressed using the ISO Latin-1 character map.
4D converts characters received from and sent to a Web Browser. As a result, the text
values you deal with, inside a Web Connection process, are always expressed using the
MacOS ASCII map.
Generally, when running on Windows, you do not need to convert ASCII codes. When
you copy or paste text between 4D and Windows or when you import or export data, 4D
automatically performs these conversions. However, when you use disk read/write
commands such as SEND PACKET or RECEIVE PACKET, 4D does not perform any ASCII
code conversion.
Within 4D, all the text values, fields, or variables that you have not yet converted to
another ASCII map are MacOS-encoded on both Macintosh and Windows. For more
information, see the section ASCII Codes.
On Windows, it is necessary that, in this case, you do not filter the characters using an
output filter ASCII map.
Consequently, no matter what the platform, if you want to use RECEIVE PACKET to read
ISO Latin-1 HTML documents from the disk, you just need to convert the text using ISO
to Mac. This is the main purpose of the ISO to Mac command.
See Also
ASCII Codes, Mac to ISO, RECEIVE PACKET, USE ASCII MAP.
Structure Access
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The commands in this theme return a description of the database structure. They return
the number of tables, the number of fields in each table, the names of the tables and
fields, and the type and properties of each field.
Determining the database structure is extremely useful when you are developing and
using groups of project methods and forms that can be copied into different databases.
The ability to read the database structure allows you to develop and use portable code.
See Also
Count fields, Count tables, Field, GET FIELD PROPERTIES, Pointers, SET INDEX, Table, Table
name.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Count tables returns the number of tables in the database. Tables are numbered in the
order in which they are created.
Example
The following example builds an array, named asTables, with the names of tables defined
in the database. This array can be used as a drop-down list (or tab control, scrollable area,
and so on) to display the list of the tables, within a form:
See Also
Arrays, Count fields, Table name.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count fields returns the number of fields in the table whose number or
pointer you pass in TableNum or TablePtr.
Example
The following project method builds the array asFields, consisting of the field names, for
the table whose pointer is received as first parameter:
$vlTable:=Table($1)
⇒ ARRAY STRING(31;asFields;Count fields($vlTable))
For ($vlField;1;Size of array(asFields))
asFields{$vlTable}:=Field name($vlTable;$vlField)
End for
See Also
Arrays, Count tables, Field name, GET FIELD PROPERTIES.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Table name returns the name of the table whose number of pointer you
pass in tableNum or tablePtr.
Example
The following is an example of a generic method that displays the records of a table. The
reference to the table is passed as a pointer to the table. The Table name command is used
to include the name of the table in the title bar for the window:
` SHOW CURRENT SELECTION Project method
` SHOW CURRENT SELECTION ( Pointer )
` SHOW CURRENT SELECTION (->[Table])
⇒ SET WINDOW TITLE("Records for "+Table name($1)) ` Sets the window title
DISPLAY SELECTION($1->) ` Displays the selection
See Also
Count tables, Field name, Table.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Field name returns the name of the field whose pointer you pass in fieldPtr
or whose table and field number you pass in tableNum and fieldNum.
Examples
1. This example sets the second element of the array FieldArray{1} to the name of the
second field in the first table. FieldArray is a two-dimensional array:
⇒ FieldArray{1}{2}:=Field name(1;2)
2. This example sets the second element of the array FieldArray{1} to the name of the field
[MyTable]MyField. FieldArray is a two-dimensional array:
⇒ FieldArray{1}{2}:=Field name(->[MyTable]MyField)
⇒ ALERT("The ID number for the field "+Field name($1)+" in the table "
+Table name(Table($1))+" has to be longer than five characters.")
See Also
Count fields, Field, Table name.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Table has three forms:
• If you pass a table number in tableNum, Table returns a pointer to the table.
• If you pass a table pointer in aPtr, Table returns the table number of the table.
• If you pass a field pointer in aPtr, Table returns the table number of the field.
Examples
1. This example sets the tablePtr variable to a pointer to the third table of the database:
⇒ TablePtr:=Table(3)
2. Passing tablePtr (a pointer to the third table) to Table returns the number 3. The
following line sets TableNum to 3:
⇒ TableNum:=Table(TablePtr)
3. This example sets the tableNum variable to the table number of [Table3]:
⇒ TableNum:=Table(->[Table3])
4. This example sets the tableNum variable to the table number of the table to which the
[Table3]Field1 field belongs:
⇒ TableNum:=Table (->[Table3]Field1)
See Also
Count tables, Field, Pointers, Table name.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET TABLE PROPERTIES returns the properties for the table passed in
tablePtr or tableNum. The table number or a pointer to the table can be passed as first
parameter.
See Also
GET FIELD ENTRY PROPERTIES, GET FIELD PROPERTIES, GET RELATION PROPERTIES.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Field has two forms:
• If you pass a table number in tableNum and a field number in fieldNum, Field returns a
pointer to the field.
• If you pass a field pointer in fieldPtr, Field returns the field number of the field.
Examples
1. The following example sets the fieldPtr variable to a pointer to the second field in the
third table:
⇒ FieldPtr:=Field(3; 2)
2. Passing fieldPtr (a pointer to the second field of a table) to Field returns the number 2.
The following line sets FieldNum to 2:
⇒ FieldNum:=Field(FieldPtr)
3. The following example sets the FieldNum variable to the field number of [Table3]Field2:
⇒ FieldNum:=Field(->[Table3]Field2)
See Also
Count fields, Field name, GET FIELD PROPERTIES, Table.
Description
The command GET FIELD PROPERTIES returns information about the field specified by
fieldPtr or by tableNum and fieldNum.
• The fieldLen parameter returns the length of the field, if the field is Alphanumeric (i.e.,
fieldType=Is Alpha Field). The value of fieldLen is meaningless for the other field types.
• The unique parameter returns True if the field is set to “Unique”, else False. The Unique
attribute can be set only to indexed fields.
• The invisible parameter returns True if the field is set to “Invisible”, else False. The
Invisible attribute can be used to hide a given field in 4D standard editor (label, charts...).
Examples
1. This example sets the variables vType, vLength, vIndex, vUnique and vInvisible to the
properties for the third field of the first table:
2. This example sets the variables vType, vLength, vIndex, vUnique and vInvisible to the
properties for the field named [Table3]Field2:
See Also
Field, Field name, SET INDEX.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET FIELD ENTRY PROPERTIES command returns the data entry properties for the field
specified by tableNum and fieldNum or by fieldPtr.
You can either pass:
• table and field numbers in tableNum and fieldNum, or
• a pointer to the field in fieldPtr.
Note: This command returns the properties defined at the structure window level. Similar
properties can be defined at the form level.
See Also
GET FIELD PROPERTIES, GET RELATION PROPERTIES, GET TABLE PROPERTIES.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET RELATION PROPERTIES returns the properties of the relation (if any)
which starts form the source field defined by tableNum and fieldNum or by fieldPtr.
See Also
GET FIELD ENTRY PROPERTIES, GET FIELD PROPERTIES, GET TABLE PROPERTIES.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET INDEX creates or removes the index for the field or subfield you pass in
field.
To index the field or subfield, pass TRUE in index. If the index already exists, the call has
no effect. To delete the index, pass FALSE. If the index does not exist, the call has no
effect.
SET INDEX will not index locked records; it will wait until the record becomes unlocked.
Starting from version 6.5, 4D allows you to now choose between two index modes: the
“traditional” mode, which is the mode used in previous versions of 4D, and the new
“fast” mode, which in most cases allows for a significant increase in speed. For more
information, refer to the 4D Design Reference manual.
You select the index mode to use by choosing whether to pass the optional mode
parameter. The mode parameter is only used if the command is able to actually create the
index (that is if the index parameter is True).
• If you don't pass the mode parameter, the indexing will be performed in traditional
mode. In this case, since indexing is done in a separate process, the database remains
available for use during this time. If an operation that uses the index is executed while the
index is being built, the index will not be used. To determine if a field has been indexed,
use the GET FIELD PROPERTIES command.
• If you pass the mode parameter, the command will use the fast mode. In this case, it
will not be possible to modify the data of the table during the indexing process.
You must pass an Integer value that represents a percentage to the mode parameter. This
value allows you to indicate the usage type for which you want the index to be most
efficient. It must be between the following limits:
- mode = 0: the index will be most efficient when adding or inserting records.
- mode = 100: the index will be most efficient when performing queries.
Examples
1. The following example indexes the field [Customers]ID with the classical mode:
UNLOAD RECORD([Customers])
⇒ SET INDEX ([Customers]ID; True)
2. You want to index the [Customers]Name field with the fast mode. This field is mainly
used for queries:
2. You want to index the [Contacts]Name field with the fast mode. This field is mainly
used for adding and inserting names, but also for queries:
See Also
GET FIELD PROPERTIES, ORDER BY, QUERY.
Description
The command Get database parameter allows you to read, for the current process, the
current value of the 4D database parameters .
The selector parameter designates the parameter to read. 4th Dimension offers you the
following predefined constants, which are in the “Database Parameters” theme:
Constant Type Value
Seq Order Ratio Longint 1
Seq Access Optimization Longint 2
Seq Distinct Values Ratio Longint 3
Index Compacting Longint 4
Seq Query Select Ratio Longint 5
Minimum Web Process Longint 6
Maximum Web Process Longint 7
Web conversion mode Longint 8
Database Cache Size Longint 9
4th Dimension Scheduler Longint 10
4D Server Scheduler Longint 11
4D Client Scheduler Longint 12
4D Server Timeout Longint 13
4D Client Timeout Longint 14
Port ID Longint 15
IP Address to listen Longint 16
Character set Longint 17
Max Concurrent Web Processes Longint 18
Client Minimum process Web Longint 19
Client Maximum process Web Longint 20
Client Maximum Web requests size Longint 21
Client Port ID Longint 22
Client IP Address to listen Longint 23
Client Character set Longint 24
Client Max Concurrent Web Proc Longint 25
Cache Writing Mode Longint 26
Maximum Web requests size Longint 27
The Database Cache Size (9) selector allows you to get the current database memory cache
size. The returned value is expressed in bytes.
The Maximum Cache size can be set on both Windows and Mac OS platforms and the
minimum cache size can be only set on the Mac OS platform. Those settings are accessed
through the Database properties dialog box. The actual size allocated to the databse cache
will however depend on both the settings and the current system resources. The
command Get database parameter allows you to get the actual size of the memory
allocated to the database cache by 4D.
Note: You cannot set the database cache memory size using the language. In other words,
the Database Cache Size selector cannot be set using the SET DATABASE PARAMETER
command.
Examples
(1) The following method allows you to get 4D scheduler current values:
C_LONGINT($ticksbtwcalls;$maxticks;$minticks;$lparams)
If (Application type=4th Dimension) ` 4D single user is used
⇒ $lparams:=Get database parameter(4th Dimension scheduler)
$ticksbtwcalls:=$lparams & 0x00ff
$maxticks:=($lparams>>8) & 0x00ff
$minticks:=($lparams>>16) & 0x00ff
End if
(2) The selector 16 (IP Address to listen) allows you to obtain the IP address on which the
4D Web server receives HTTP requests. The following example splits up the hexadecimal
value:
C_LONGINT($a;$b;$c;$d)
C_LONGINT($addr)
⇒ $addr:=Get database parameter(IP Address to listen)
$a:=($addr>>24)&0x000000ff
$b:=($addr>>16)&0x000000ff
$c:=($addr>>8)&0x000000ff
$d:=$addr&0x000000ff
See Also
DISTINCT VALUES, QUERY SELECTION, SET DATABASE PARAMETER.
Description
The SET DATABASE PARAMETER command allows you to modify, for the current process,
various internal parameters of the 4D database.
selector designates the code of the database parameter to modify. 4th Dimension offers
the following predefined constants, which are located in the “Database Parameters”
theme:
Constant Type Value
Seq Order Ratio Longint 1
Seq Access Optimization Longint 2
Seq Distinct Values Ratio Longint 3
Index Compacting Longint 4
Seq Query Select Ratio Longint 5
Minimum Web Process Longint 6
Maximum Web Process Longint 7
Web conversion mode Longint 8
4th Dimension Scheduler Longint 10
4D Server Scheduler Longint 11
4D Client Scheduler Longint 12
4D Server Timeout Longint 13
4D Client Timeout Longint 14
Port ID Longint 15
IP Address to listen Longint 16
Character set Longint 17
Max Concurrent Web Processes Longint 18
Client Minimum process Web Longint 19
Client Maximum process Web Longint 20
Client Max Web requests size Longint 21
Client Port ID Longint 22
Client IP Address to listen Longint 23
Client Character set Longint 24
Client Max Concurrent Web Proc Longint 25
Cache writing mode Longint 26
Maximum Web requests size Longint 27
Note: An additional selector can be used with the command Get database parameter:
Database Cache Size (9). This selector cannot be used with the command SET DATABASE
PARAMETER. For more information, please refer to the description of the command Get
database parameter.
See also example 3. For more information on how to designate the IP address, refer to the
section Web Services, Web Server Settings.
(3) The IP address 192.193.194.195 will be set with the following statement:
See Also
DISTINCT VALUES, Get database parameter, QUERY SELECTION.
Subrecords
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CREATE SUBRECORD creates a new subrecord for subtable and makes the new subrecord
the current subrecord. The new subrecord is saved only when the parent record is saved.
The parent record can be saved by a command such as SAVE RECORD or by the user
accepting the record. If there is no current record, CREATE SUBRECORD has no effect. To
add a new subrecord through a subrecord input form, use ADD SUBRECORD.
Example
The following example is an object method for a button. When it is executed (that is,
when the button is clicked), it creates new subrecords for children in the [People] table.
The Repeat loop lets the user add children until the Cancel button is clicked. The form
displays the children in an subform, but will not allow direct data entry into the subtable
because the Enterable option has been turned off:
Repeat
` Get the child’s name
vChild := Request("Name (cancel when done):")
` If the user clicked OK
If (OK = 1)
` Add a new subrecord for a child
⇒ CREATE SUBRECORD([People]Children)
` Assign child’s name to the subfield
[People]Children'Name:=vChild
End if
Until (OK=0)
See Also
ADD SUBRECORD, DELETE SUBRECORD, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DELETE SUBRECORD deletes the current subrecord of subtable. If there is no current
subrecord, DELETE SUBRECORD has no effect. After the subrecord is deleted, the current
subselection for subtable is empty. As a result, DELETE SUBRECORD can’t be used to scan
through a subselection and delete selected subrecords.
The deletion of subrecords is not permanent until the parent record is saved. Deleting a
parent record automatically deletes all its subrecords.
To delete a subselection, create the subselection you want to delete, delete the first
subrecord, create the subselection again, delete the first subrecord, and so on.
Examples
1. The following example deletes all the subrecords of a subtable:
ALL SUBRECORDS([People]Children)
While (Records in subselection([People]Children)>0)
⇒ DELETE SUBRECORD([People]Children)
ALL SUBRECORDS([People]Children)
End while
2. The following example deletes the subrecords in which the age of the child is greater
than or equal to 12, from the [People]Children subtable :
ALL RECORDS([People]) ` Select all the records
For ($vlRecord;1;Records in selection([People])) ` For all the records in the table
` Query all records that have subrecords with the criteria
QUERY SUBRECORDS([People]Children;[People]Children'Age>=12)
` Loop until no subrecords are left by the query
While (Records in subselection([People]Children)>0)
⇒ DELETE SUBRECORD([People]Children) ` Delete the subrecord
QUERY SUBRECORDS([People]Children;[People]Children'Age>=12) ` Query again
End while
SAVE RECORD([People]) ` Save the parent record
NEXT RECORD([People])
End for
See Also
ALL SUBRECORDS, QUERY SUBRECORDS, Records in subselection, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
ALL SUBRECORDS makes all the subrecords of subtable the current subselection. If a
current parent record does not exist, ALL SUBRECORDS has no effect. When a parent
record is first loaded, the subselection contains all subrecords. A subselection may not
contain all subrecords after ADD SUBRECORD, QUERY SUBRECORDS, or DELETE
SUBRECORD is executed.
Example
The following example selects all subrecords to ensure that they are all included in the
sum:
See Also
QUERY SUBRECORDS, Records in subselection.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Records in subselection returns the number of subrecords in the current subselection of
subtable. Records in subselection applies only to subrecords in the current record. It is the
subrecord equivalent of Records in selection. The result is undefined if no parent record
exists.
Example
The following example selects all the subrecords and displays the number of children for
the parent record:
` Select all children, then display how many
ALL SUBRECORDS ([People]Children)
⇒ ALERT ("Number of children: "+String(Records in subselection ([People]Children)))
See Also
ALL SUBRECORDS, QUERY SUBRECORDS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
APPLY TO SUBSELECTION applies statement to each subrecord in the current subselection
of subtable. The statement may be a statement or a method. If the statement modifies a
subrecord, the modified subrecord is written to disk only when the parent record is
written. If the subselection is empty, APPLY TO SUBSELECTION has no effect.
Example
The following example capitalizes the first names in [People]Children:
ALL SUBRECORDS ([People]Children)
⇒ APPLY TO SUBSELECTION([People]Children;[People]Children'Name:=
Uppercase(Substring([People]Children'Name;1;1))
+Lowercase(Substring([People]Children'Name;2)))
Note: The statement has been put on several lines for clarity in documentation only.
See Also
ALL SUBRECORDS, QUERY SUBRECORDS, SAVE RECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
FIRST SUBRECORD makes the first subrecord of the current subselection of subtable the
current subrecord. All query, selection, and order by commands also set the current
subrecord to the first subrecord. If the current subselection is empty, FIRST SUBRECORD
has no effect.
Example
The following example concatenates the first and last names in child records stored in a
subtable. It copies the names into the array atNames:
` Create an array to hold the names
ARRAY TEXT (atNames; Records in subselection ([People]Children))
⇒ FIRST SUBRECORD ([People]Children)
` Start at the first subrecord and loop once for each child
For ($vlSub; 1; Records in subselection ([People]Children))
atNames{$vlSub} := [People]Children'First Name+" "+ [People]Children'Last Name
NEXT SUBRECORD ([People]Children)
End for
See Also
LAST SUBRECORD, NEXT SUBRECORD, PREVIOUS SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
LAST SUBRECORD makes the last subrecord of the current subselection of subtable the
current subrecord. If the current subselection is empty, LAST SUBRECORD has no effect.
Example
The following example concatenates the first and last names in child records stored in a
subtable. It copies the names into an array, called atNames. It is the same as the example
for FIRST SUBRECORD except that it moves through the subrecords from last to first:
` Create an array to hold the names
ARRAY TEXT (atNames; Records in subselection ([People]Children))
` Start at the last subrecord and loop once for each child
⇒ LAST SUBRECORD ([People]Children)
For ($vlSub;1;Records in subselection ([People]Children))
atNames{$vlSub}:=[People]Children'First Name + " " + [People]Children'Last Name
PREVIOUS SUBRECORD ([People]Children)
End for
See Also
FIRST SUBRECORD, NEXT SUBRECORD, PREVIOUS SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
NEXT SUBRECORD moves the current subrecord pointer to the next subrecord in the
current subselection of subtable. If NEXT SUBRECORD moves the pointer past the last
subrecord, End subselection returns TRUE, and there is no current subrecord. If End
subselection returns TRUE, use FIRST SUBRECORD or LAST SUBRECORD to move the pointer
back into the current subselection. If the current subselection is empty, or Before
subselection returns TRUE, NEXT SUBRECORD has no effect.
Example
See the example for FIRST SUBRECORD.
See Also
FIRST SUBRECORD, LAST SUBRECORD, PREVIOUS SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
PREVIOUS SUBRECORD moves the current subrecord pointer to the previous subrecord in
the current subselection of subtable. If PREVIOUS SUBRECORD moves the pointer before
the first subrecord, Before subselection returns TRUE, and there is no current subrecord. If
Before subselection returns TRUE, use FIRST SUBRECORD or LAST SUBRECORD to move the
pointer back into the current subselection. If the current subselection is empty, or End
subselection returns TRUE, PREVIOUS SUBRECORD has no effect.
Example
See the example for LAST SUBRECORD.
See Also
FIRST SUBRECORD, LAST SUBRECORD, NEXT SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Before subselection returns True when the current subrecord pointer is before the first
subrecord of subtable. Before subselection is used to check whether or not PREVIOUS
SUBRECORD has moved the pointer before the first subrecord. If the current subselection
is empty, Before subselection returns True.
Example
The following example is an object method for a button. When the button is clicked, the
pointer moves to the previous subrecord. If the pointer is before the first subrecord, it
moves to the last subrecord:
PREVIOUS SUBRECORD ([People]Children) ` Move to the previous subrecord
⇒ If (Before subselection ([People]Children) ` If we have gone too far...
LAST SUBRECORD ([People]Children) ` move to the last subrecord
End if
See Also
PREVIOUS SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
End subselection returns True when the current subrecord pointer is after the end of the
current subselection of subtable. End subselection is used to check whether or not NEXT
SUBRECORD has moved the pointer after the last subrecord. If the current subselection is
empty, End subselection returns True.
Example
The following example is an object method for a button. When the button is clicked, the
pointer moves to the next subrecord. If the pointer is after the last subrecord, it moves to
the first subrecord:
NEXT SUBRECORD ([People]Children) ` Move to the next subrecord
⇒ If (End subselection ([People]Children)) ` If we have gone too far...
FIRST SUBRECORD ([People]Children) ` move to the first subrecord
End if
See Also
NEXT SUBRECORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
ORDER SUBRECORDS BY (subtable; subfield{; > or <}{; subfield2; > or <2; ...; subfieldN;
> or <N})
Description
ORDER SUBRECORDS BY sorts the current subselection of subtable. It sorts only the
subselection of the subtable contained in the current parent record.
You can specify more than one level of sort by including more subfields and sort symbols.
After the sort is completed, the first subrecord of the sorted subselection is the current
subrecord. Sorting subrecords is a dynamic process. Subrecords are never saved in their
sorted order. If neither a current record nor a higher-level subrecord exists, ORDER
SUBRECORDS BY has no effect.
If a form contains a subform that is to be printed in a fixed frame, this command needs
to be called just once before printing in the Before phase of the parent form method.
Example
The following example sorts the [Stats]Sales subtable into ascending order, based on the
SalesDollars subfield:
See Also
QUERY SUBRECORDS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
QUERY SUBRECORDS queries subtable and creates a new subselection. This is the only
command that queries subrecords and returns a selection of subrecords. The queryFormula
is applied to each subrecord in subtable. If the formula evaluates as TRUE, the subrecord is
added to the new subselection. When the query is complete, QUERY SUBRECORDS makes
the first subrecord the current subrecord of subtable.
Remember that QUERY SUBRECORDS queries only the subrecords of the subtable
contained in the currently selected parent record, and not all the subrecords associated
with the records of the parent table. QUERY SUBRECORDS does not change the current
parent record.
If neither a current record nor a higher-level subrecord exists, QUERY SUBRECORDS has no
effect.
Example
The following example queries for children older than 10 years:
See Also
ALL SUBRECORDS, ORDER SUBRECORDS BY, Records in subselection.
System Documents
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Introduction
All the documents and applications you use on your computer are stored as files on the
hard disk(s) connected to or mounted on your machine, or floppy disk(s) or other similar
permanent storage devices. Within 4th Dimension we use the terms file or document to
refer to these documents and applications. However, most commands in this theme use
the term "document" because most of the time you will use them to access documents
(rather than application or system files) on disk.
A hard disk can be formatted as one or several partitions, each of which is called a
volume. It does not matter if two volumes are physically present on the same hard disk;
at the 4D First level, you will usually treat these volumes as separate and equal entities.
Each volume has a volume name. On Windows, volumes are designated by a letter
followed by a colon. Usually A: and B: are used to designate the 5 1/4 or 3 1/2 floppy
drives. Usually C: designates the volume you use for booting your system (unless you
configure your PC otherwise). Then the letters D: through Z: are used for the additional
volumes connected or mounted to your PC (CD-ROM drives, additional drives, network
drives, and so on). On Macintosh, volumes have natural names whose maximal length is
31 characters; these are the names you see on the desktop at the Finder level.
Normally, you classify your documents into folders, which themselves can contain other
folders. It is not a good idea to accumulate hundreds or thousands of files at the same
level of a volume; it is messy and it slows down your system. On Windows, a folder is (or
was) called a directory; since the introduction of Windows 95, the term folder is used.
Folders have always been called so on the Macintosh.
To uniquely identify a document, you need to know the name of the volume and the
name(s) of the folder(s) where the document is located as well as the name of the
document itself. If you concatenate all these names, you get the pathname to the
document. Within this pathname, folder name are separated by a special character called
the directory (separator) symbol. On Windows, this character is the anti-slash (\); on
Macintosh it is the colon (:).
On Windows, if the whole thing is located on the C: drive (volume), the pathname of the
document is:
C:\Current Work\Documents\Memos\Important Memo.TXT
On Macintosh, if the whole thing is located on the disk (volume) Internal Drive, the
pathname of the document is:
Internal Drive:Current Work:Documents:Memos:Important Memo
On Windows, the name of the document is suffixed with .TXT; we will see why in the
next section.
Whatever the platform, the full pathname of a document can be expressed as follows:
VolName DirSep { DirName DirSep { DirName DirSep { ... } } } DocName
All the documents (files) located on volumes have several characteristics, usually called
attributes or properties: the name of the document itself (up to 31 characters on
Macintosh, up to 8 characters on Windows 3.1.1, up to 255 characters on Windows 95 or
NT 4.0), the type and the creator.
On Windows, the type of a document is determined by the suffix (called the file
extension) attached to the document name. For instance, .TXT is the Windows file
extension for text documents. On Macintosh, the type of a document is determined by
the file type property, which is a 4-character signature (not displayed at the Finder level).
For instance, the file type of a text document is "TEXT".
A document is open or closed. Using the built-in 4D commands, a document can be open
by only one process at a time. One process can open several documents, several processes
can open multiple documents, but you cannot open the same document twice at a time.
You open a document with the commands Open document, Create document and Append
document.
Once a document is open, you can read and write characters from and to the document
(see the command RECEIVE PACKET and SEND PACKET). When you are finished with the
document, you usually close it using the command CLOSE DOCUMENT.
All open documents are referred to using DocRef expression returned by the commands
Open document, Create document and Append document. A DocRef uniquely identifies an
open document. It is formally an expression of type Time. All commands working with
open documents expect DocRef as a parameter. If you pass an incorrect DocRef to one of
these commands, a file manager error occurs.
When you access (open, close, delete, rename, copy) documents, when you change the
properties of a document or when you read and write characters in a document, I/O errors
may occur. A document might not be found, it can be locked, it can be already open. You
can catch these errors with an error-handling method installed with ON ERR CALL. Most
the errors that can occur while using system documents are described in the section OS
File Manager Errors.
The three commands Open document, Create document and Append document enables
you to access a document using the standard Open or Save file dialog boxes. When you
access a document through a standard dialog, 4D returns the full pathname of the
document in the Document system variable. This system variable has to be distinguished
from the document parameter that appears in the parameter list of the commands.
Most of the routines of this section expecting a document name accept both a name or a
pathname to the document (except when signaled otherwise). If you pass a name, the
command looks for the document within the folder of the database. If you pass a
pathname, it must be valid.
Warning: The maximum length of the parameter document is 255 characters. If you pass
a longer name, it will be truncated and a File manager error will be generated.
The On Windows project method listed here tells if your database is running on Windows:
` On windows Project Method
` On windows -> Boolean
` On windows -> True if on Windows
C_BOOLEAN($0)
C_LONGINT($vlPlatform;$vlSystem;$vlMachine)
PLATFORM PROPERTIES($vlPlatform;$vlSystem;$vlMachine)
$0:=($vlPlatform=Windows)
C_INTEGER($0)
If (On Windows )
$0:=Ascii("\")
Else
$0:=Ascii(":")
End if
C_STRING(255;$1;$0)
C_INTEGER($viLen;$viPos;$viChar;$viDirSymbol)
$viDirSymbol:=Directory symbol
$viLen:=Length($1)
$viPos:=0
For ($viChar;$viLen;1;-1)
If (Ascii($1≤$viChar≥)=$viDirSymbol)
$viPos:=$viChar
$viChar:=0
End if
End for
If ($viPos>0)
$0:=Substring($1;$viPos+1)
Else
$0:=$1
End if
If (◊vbDebugOn) ` Set this variable to True or False in the On Startup database method
If ($0="")
TRACE
End if
End if
C_STRING(255;$1;$0)
C_STRING(1;$vsDirSymbol)
C_INTEGER($viLen;$viPos;$viChar;$viDirSymbol)
See Also
Append document, CLOSE DOCUMENT, COPY DOCUMENT, Create document, CREATE
FOLDER, DELETE DOCUMENT, Document creator, DOCUMENT LIST, Document type,
FOLDER LIST, Get document position, GET DOCUMENT PROPERTIES, Get document size,
MAP FILE TYPES, MOVE DOCUMENT, Open document, SET DOCUMENT CREATOR, SET
DOCUMENT POSITION, SET DOCUMENT PROPERTIES, SET DOCUMENT SIZE, SET
DOCUMENT TYPE, Test path name, VOLUME ATTRIBUTES, VOLUME LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Document type returns the type of the document whose name or
pathname you pass in document.
On Windows, Document type returns the file extension of the document (i.e. 'DOC' for a
Microsoft Word document, 'EXE' for an executable file, and so on) or the corresponding
MacOS-based 4 characters file type if this latter has been mapped with its equivalent
Windows file extension by 4th Dimension (i.e. 'TEXT' for the 'TXT' file extension) or by a
prior call to MAP FILE TYPES.
On Macintosh, Document type returns the 4-characters file type of the document (i.e.
'TEXT' for a Text document, 'APPL' for a double-clickable application and so on).
See Also
Document creator, GET DOCUMENT PROPERTIES, MAP FILE TYPES, SET DOCUMENT TYPE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET DOCUMENT TYPE command sets the type of the document whose name or
pathname you pass in document.
See the discussion of file types in System Documents and Document type.
On Windows, this command modifies the file extension and therefore the value of
document. For example, the instruction:
⇒ SET DOCUMENT TYPE("C:\Docs\Invoice.asc";"TEXT")
renames the file "Invoice.asc" to "Invoice.txt". In 4D, the Macintosh "TEXT" type
corresponds to the Windows "txt" type.
If the type has no equivalent provided by 4D, you will have to pass the extension. For
example, the following instruction renames the file "Invoice.asc" to "Invoice.zip":
⇒ SET DOCUMENT TYPE("C:\Docs\Invoice.asc";"zip")
See Also
Document type, MAP FILE TYPES, SET DOCUMENT CREATOR, SET DOCUMENT PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Document creator returns the creator of the document whose name or
pathname you pass in document.
See Also
Document type, SET DOCUMENT CREATOR.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET DOCUMENT CREATOR sets the creator of the document whose name
or pathname you pass in document.
See Also
Document creator, SET DOCUMENT PROPERTIES, SET DOCUMENT TYPE.
Description
The command Open document opens the document whose name or pathname you pass
in document.
If you pass an empty string in document, the Open File dialog box is presented, you then
select the document to be open. If you cancel the dialog, no document is open, Open
document returns a null DocRef and sets the OK variable to 0.
• If the document is correctly opened, Open document returns its document reference
number and sets the OK variable to 1.
• If the document is already open and the mode parameter is omitted, Open document
opens the document in Read mode and sets the OK variable to 1.
• If the document is already open and you try to open it in Write mode, an error is
generated.
• If the document does not exist an error is generated.
On Macintosh, if you use the Open File dialog box, all documents are by default
presented. To show another type of documents, specify the a document type in the
optional fileType parameter.
On Windows, if you use the Open File dialog box, all types of documents *.* are by
default presented. To show another type of documents, pass in fileType, a 1 to 3-character
Windows file extension or a Macintosh file type mapped using the command MAP FILE
TYPES.
⇒ vhDocRef:=Open document("C:\Letter";"WRI")
will try to open the document “C:\Letter.WRI” on your disk. If you pass more than three
characters in fileType, Open document takes into account only the first three characters. If
a document type is not specified, Open document tries to open the document with no file
extension. If it does not find it, it tries to open the document with the .TXT extension. If
it does not find it, it will return a “File not found” error.
If a document is open, Open document initially sets the file position at the beginning of
the document while Append document sets it at the end of the document.
Once you have open a document you can read and write in the document using the
command RECEIVE PACKET and SEND PACKET that you can combine with the commands
Get document position and SET DOCUMENT POSITION to directly access any part of the
document.
The optional parameter mode allows you to define how docName is to be opened. Four
different open file modes are possible. 4th Dimension offers the following predefined
constants, located in the theme "System Documents":
Constant Type Value
Read and Write (default value) Integer 0
Write Mode Integer 1
Read Mode Integer 2
Get Pathname Integer 3
Examples
1. The following example opens an existing document called Note, writes the string
“Good-bye” into it, and closes the document. If the document already contained the
string “Hello”, the string would be overwritten:
C_TIME(vhDocRef)
⇒ vhDocRef:=Open document ("Note") ` Open a document called Note
If (OK=1)
SEND PACKET (vhDocRef;"Good-bye") ` Write one word into the document
CLOSE DOCUMENT (vhDocRef) ` Close the document
End if
See Also
Append document, Create document.
Description
The Create document command creates a new document and returns its document
reference number.
Pass the name or full pathname of the new document in document. If document already
exists on the disk, it is overwritten. However, if document is locked or already open, an
error is generated.
If you pass an empty string in document, the Save As dialog box is displayed and you can
then enter the name of the document you want to create. If you cancel the dialog, no
document is created; Create document returns a null DocRef and sets the OK variable to 0.
If the document is correctly created and opened, Create document returns its document
reference number and sets the OK variable to 1. The system variable Document is updated
and returns the access path of the created document.
Whether or not you use the Save As dialog box, Create document creates a .TXT
(Windows) or TEXT (Macintosh) document by default. If you want to create another type
of document, pass the fileType parameter.
On Macintosh, you pass a file type. On Windows you pass a 1- to 3-character Windows file
extension or Macintosh file type mapped through the MAP FILE TYPES mechanism. If you
want to create a document without an extension, a document containing several
extensions, or a document containing an extension with more than three characters, do
not use the type parameters and pass the full name in document (see example2).
Once you have created and opened a document, you can write and read the document
using the SEND PACKET and RECEIVE PACKET commands that you can combine with the
Get file position and SET FILE POSITION commands in order to directly access any part of
the document.
Example
(1) The following example creates and opens a new document called Note, writes the
string “Hello” into it, and closes the document:
C_TIME(vhDocRef)
⇒ vhDocRef:=Create document ("Note") ` Create new document called Note
If (OK=1)
SEND PACKET(vhDocRef; "Hello") ` Write one word in the document
CLOSE DOCUMENT(vhDocRef) ` Close the document
End if
(2) The following example creates documents with non-standard extensions under
Windows:
See Also
Append document, Open document.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Append document does the same as thing as Open document: it allows you
to open a document on disk.
The only difference is that Append document sets the file position at the end of the
document while Open document sets its at the beginning of the document.
Refer to Open document for more details about using Append document.
Example
The following example opens an existing document called Note, appends the string “and
so long” and a carriage return onto the end of the document, and closes the document. If
the document already contained the string “Good-bye”, the document would now
contain the string “Good-bye and so long”, followed by a carriage return:
C_TIME(vhDocRef)
⇒ vhDocRef:=Append document ("Note") ` Open Note document
SEND PACKET (vhDocRef;" and so long"+Char(13)) ` Append a string
CLOSE DOCUMENT (vhDocRef) ` Close the document
See Also
Create document, Open document.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CLOSE DOCUMENT closes the document specified by docRef.
Closing a document is the only way to ensure that the data written to a file is saved. You
must close all the documents you open with the commands Open document, Create
document or Append document.
Example
The following example lets the user create a new document, writes the string “Hello” into
it, and closes the document:
C_TIME(vhDocRef)
vhDocRef:=Create document ("")
If (OK=1)
SEND PACKET(vhDocRef; "Hello") ` Write one word into the document
⇒ CLOSE DOCUMENT(vhDocRef) ` Close the document
End if
See Also
Append document, Create document, Open document.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command COPY DOCUMENT copies the document specified by sourceName to the
location specified by destinationName.
An error will occur if there is already a document named destinationName unless you
specify the optional * parameter instructing COPY DOCUMENT to delete and override the
destination document.
Examples
(1) The following example duplicates a document in its own folder:
⇒ COPY DOCUMENT("C:\FOLDER\DocName";"C:\FOLDER\DocName2")
(2) The following example copies a document to the database folder (provided C:\FOLDER
is not the database folder):
⇒ COPY DOCUMENT("C:\FOLDER\DocName";"DocName")
(3) The following example copies and from a document from one volume to another one:
⇒ COPY DOCUMENT("C:\FOLDER\DocName";"F:\Archives\DocName.OLD")
(4) The following example duplicates a document in its own folder overriding an already
existing copy:
⇒ COPY DOCUMENT("C:\FOLDER\DocName";"C:\FOLDER\DocName2";*)
See Also
MOVE DOCUMENT.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command MOVE DOCUMENT moves or renames a document.
You specify the full pathname to the document in srcPathName and the new name
and/or new location for the document in dstPathName.
Warning: Using MOVE DOCUMENT, you can move a document from and to any directory
on the same volume. If you want to move a document between two distinct volumes, use
COPY DOCUMENT to “move” the document then delete the original copy of the
document using DELETE DOCUMENT.
Examples
(1) The following example renames the document DocName:
⇒ MOVE DOCUMENT("C:\FOLDER\DocName";"C:\FOLDER\NewDocName")
(2) The following example moves and renames the document DocName:
⇒ MOVE DOCUMENT("C:\FOLDER1\DocName";"C:\FOLDER2\NewDocName")
⇒ MOVE DOCUMENT("C:\FOLDER1\DocName";"C:\FOLDER2\DocName")
Note: In the last two example, the destination folder "C:\FOLDER2" must exist. The
command MOVE DOCUMENT only moves a document, does not create folders.
See Also
COPY DOCUMENT.
Description
The command DELETE DOCUMENT deletes the document whose name you pass in
document.
If the document name or the entered path name is incorrect, an error is generated. This is
also the case if you try to delete an open document.
DELETE DOCUMENT doesn’t accept an empty string argument for document. If an empty
string is used, the Open File dialog box is not displayed and an error is generated.
WARNING: DELETE DOCUMENT can delete any file on a disk. This includes documents
created with other applications as well as the applications themselves. DELETE DOCUMENT
should be used with extreme caution. Deleting a document is a permanent operation and
cannot be undone.
Examples
(1) The following example deletes the document named Note:
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The function Test path name checks if a document or folder whose name or pathname
you pass in pathname is present on the disk.
If a document is found, Test path name returns 1. If a folder found, Test path name
returns 0.
If no document nor folder is found, Test path name returns a negative value (i.e. -43 for
File not found).
Example
The following tests if the document “Journal” is present in the folder of the database,
then creates it if it was not found:
See Also
Create document, CREATE FOLDER.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CREATE FOLDER creates a folder according to the pathname you pass in
folderPath.
If you pass a name, the folder is created in the folder of the database. If you pass a path
name, it must refer to a valid path up to the name of the folder you want to create;
starting at the root level of a volume or at the level of the database folder.
Examples
(1) The following example creates the folder “Archives” in the folder of the database:
⇒ CREATE FOLDER("Archives")
(2) The following example creates the folder Archives in the folder of the database, then
it creates the subfolder “January” and “February”:
⇒ CREATE FOLDER("Archives")
⇒ CREATE FOLDER("Archives\January")
⇒ CREATE FOLDER("Archives\February")
(3) The following example creates the folder “Archives” at the root level of the C volume:
⇒ CREATE FOLDER("C:\Archives")
(4) The following example will fail if there is no “NewStuff” folder at the root level of the
C volume:
⇒ CREATE FOLDER("C:\NewStuff\Pictures")
` WRONG, cannot create two folder levels in one call
See Also
FOLDER LIST, Test path name.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Select folder displays a dialog box that allows you to manually select a
folder and then retrieve the complete access path to that folder.
The Select folder command displays a standard dialog box to browse through the
workstation’s volumes and folders.
The optional parameter message allows you to display a message in the dialog box. In the
following examples, the message is "Select a destination folder":
Windows
The user selects a folder and then clicks the OK button (on Windows) or the Select
button (on Mac OS). The access path to the folder is then returned by the function.
• On Windows, the access path is returned in the following format:
“C:\Folder1\Folder2\SelectedFolder\”
• On MacOS, the access path is returned in the following format:
“Hard Disk:Folder1:Folder2:SelectedFolder:”
Note: On MacOS, depending on whether or not the name of the folder is selected in the
dialog box, the access path that is returned to you may be different.
4D Server: This function allows you to view the volumes connected to the client
workstations. It is not possible to call this function from a stored procedure.
If the user validates the dialog box, the OK system variable is set to 1. If the user clicks the
Cancel button, the OK system variable is set to 0 and the function returns an empty
string.
Note: On Windows, if the user selected some incorrect elements, such as “Workstation”,
“Trash can”, and so on, the OK system variable is set to 0, even if the user validates the
dialog box.
See Also
CREATE FOLDER, FOLDER LIST.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE FOLDER command deletes the folder whose name or full path has
been passed in folder.
You can detect these errors through a method installed by the ON ERR CALL command.
See Also
DELETE DOCUMENT.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command CREATE ALIAS creates an alias (named “shortcut” under Windows) for the
target file or folder passed in targetPath. The name and location are defined by the
targetPath parameter.
An alias can be made for any kind of document or folder. The alias icon will be the same
as the target item. The icon contains a small arrow at the bottom left side. Under MacOS,
the icon name is also displayed in italics characters.
This command does not assign a name by default, the name has to be passed in the
aliasPath parameter. If just a name is passed in this parameter, the alias is created in the
current working folder (usually the folder containing the structure file).
Note: Under Windows, the shortcuts are designated by a “.LNK” extension (invisible). If
this extension is not passed, it is automatically added by the command.
Example
Your database generates text files called “Report Number” sorted in the database folder.
The user would like to create shortcuts to these reports and to store them at a convenient
location:
`Method CREATE_REPORT
C_TEXT($vtRport)
C_STRING(250;$vtpath)
C_STRING(80;$vaname)
C_TIME(vDoc)
C_INTEGER($ReportNber)
See Also
RESOLVE ALIAS.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command RESOLVE ALIAS returns the full path to the target file or folder of the alias
(named shortcut under Windows).
See Also
CREATE ALIAS.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command VOLUME LIST populates the Text or String array volumes with the names of
the volumes currently defined (Windows) or mounted (Macintosh) on your machine.
On Macintosh, it returns the list of the volumes visible at the Finder level.
On the other hand, on Windows, it returns the list of the volumes currently defined
whether or not each volume is physically present (i.e. the volume A: will be returned
whether or not a disk is actually present in the floppy drive).
Example
Using a scrollable area named asVolumes you want to display the list of the volumes
defined or mounted on your machine, you write:
Case of
: (Form event=On Load)
ARRAY STRING(31;asVolumes;0)
⇒ VOLUME LIST(asVolumes)
` ...
End case
See Also
DOCUMENT LIST, FOLDER LIST, VOLUME ATTRIBUTES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command VOLUME ATTRIBUTES returns, expressed in bytes, the size, the used space
and the free space for the volume whose name you pass in volume.
Example
Your application includes some batch operations running the night or the week-end that
store huge temporary files on disk. To make this process as automatic and flexible as
possible, you write a routine that will automatically find the first volume whose free space
is sufficient for your temporary files. You might write the following project method:
` Find volume for space Project Method
` Find volume for space ( Real ) -> String
` Find volume for space ( Space needed in bytes ) -> Volume name or Empty string
C_STRING(31;$0)
C_STRING(255;$vsDocName)
C_LONGINT($vlNbVolumes;$vlVolume)
C_REAL($1;$vlSize;$vlUsed;$vlFree)
C_TIME($vhDocRef)
Once this project method is added to your application, you can for instance write:
$vsVolume:=Find volume for space (100*1024*1024)
If($vsVolume#"")
` Continue
Else
ALERT("A volume with at least 100 MB of free space is required!")
End if
See Also
VOLUME LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command FOLDER LIST populates the Text or String array directories with the names
of the folders located at the pathname you pass in pathname.
Note: The pathname parameter only accepts absolute pathnames.
If there are no folders at the specified location, the command returns an empty array. If
the pathname you pass in pathname is invalid, FOLDER LIST generate a file manager error
that you can intercept using an ON ERR CALL method.
Warning: The maximum length of the parameter pathname is 255 characters. If you pass a
longer pathname, it will be truncated and a File manager error will be generated.
See Also
DOCUMENT LIST, VOLUME LIST.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The DOCUMENT LIST command populates the Text or String array documents with the
names of the documents located at the pathname you pass in pathname.
Note: The pathname parameter only accepts absolute pathnames.
If there are no documents at the specified location, the command returns an empty array.
If the pathname you pass in pathname is invalid, DOCUMENT LIST generates a file
manager error that you can intercept using an ON ERR CALL method.
Warning: The maximum length of the parameter pathname is 255 characters. If you pass a
longer pathname, it is truncated and a File Manager error is generated.
See Also
FOLDER LIST, VOLUME LIST.
version 3.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
MAP FILE TYPES lets you associate a Windows file extension with a Macintosh file type.
You need to call this routine only once to establish a mapping for an entire worksession
with a database. Once the call has been made, the commands Append document, Create
document, Create resource file, Open resource file and Open resource file while running on
Windows will automatically substitute the Windows file extension for the Macintosh file
type you actually pass as a parameter to the routine.
In the macOS parameter you pass a 4-character Macintosh file type. If you do not pass a 4-
character string, the command does nothing and generates an error.
In the windows parameter you pass a 1 to 3-character Windows file extension. If you do
not pass a 1 to 3-character string, the command does nothing and generates an error.
In the context parameter you pass the string that will be displayed in the List Files of Type
drop-down list of the Windows Open File dialog box. The context string is limited to 32
characters; additional characters are ignored.
IMPORTANT: Once you have mapped a Windows file extension to a Macintosh file type,
you cannot change or delete this mapping within a single work session. If you need to
change a mapping while developing and debugging a 4D application, reopen the database
and remap the file extension.
Once the call above has been made, the following code will display only Word documents
in the Open file dialog on Windows and Macintosh:
$DocRef:=Open document("";"WDBN")
If (OK=1)
` ...
End if
See Also
Append document, Create document, Create resource file, Open resource file, Open resource
file.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
GET DOCUMENT PROPERTIES (document; locked; invisible; created on; created at;
modified on; modified at)
Description
The GET DOCUMENT PROPERTIES command returns information about the document
whose name or pathname you pass in document.
Example
You have created a documentation database and you would like to export all the records
you created in the database to documents on disk. Because the database is regularly
updated you want to write an export algorithm that create or recreate each document on
disk if the document does not exist or if the corresponding record has been modified after
the document was saved for the last time. Consequently, you need to compare the date
and time of modification of a document (if it exists) with its corresponding record.
Rather than saving both a date and time values into each record, you can save a “time
stamp” value which expresses the number of seconds elapsed between an arbitrary
anterior date and time (in this example we use Jan, 1st 1995 at 00:00:00) and the date
and time when the record was saved.
In our example, the field [Documents]Creation Stamp holds the time stamp when the
record was first created and the field [Documents]Modification Stamp holds the time stamp
when the record was last modified.
The Time stamp project method listed below calculates the time stamp for a specific date
and time or for the current date and time if no parameters are passed:
` Time stamp Project Method
` Time stamp { ( date ; Time ) } -> Long
` Time stamp { ( date ; Time ) } -> Number of seconds since Jan, 1st 1995
C_DATE($1;$vdDate)
C_TIME($2;$vhTime)
C_LONGINT($0)
If (Count parameters=0)
$vdDate:=Current date
$vhTime:=Current time
Else
$vdDate:=$1
$vhTime:=$2
End if
$0:=(($vdDate-!01/01/95!)*86400)+$vhTime
Note: Using this method, you can encode dates and times from the 01/01/95 at 00:00:00
to the 01/19/2063 at 03:14:07 which cover the long integer range 0 to 2^31 minus one.
C_DATE($0)
C_LONGINT($1)
$0:=!01/01/95!+($1\86400)
C_TIME($0)
C_LONGINT($1)
$0:=Time(Time string(†00:00:00†+($1%86400)))
For insuring that the records have their time stamps correctly updated no matter the way
they are created or modified, we just need to enforce that rule using the trigger of the
table [Documents]:
Case of
: (Database event=Save New Record Event)
[Documents]Creation Stamp:=Time stamp
[Documents]Modification Stamp:=Time stamp
: (Database event=Save Existing Record Event)
[Documents]Modification Stamp:=Time stamp
End case
C_STRING(255;$vsPath;$vsDocPathName;$vsDocName)
C_LONGINT($vlDoc)
C_BOOLEAN($vbOnWindows;$vbDoIt;$vbLocked;$vbInvisible)
C_TIME($vhDocRef;$vhCreatedAt;$vhModifiedAt)
C_DATE($vdCreatedOn;$vdModifiedOn)
See Also
Document creator, Document type, SET DOCUMENT PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
SET DOCUMENT PROPERTIES (document; locked; invisible; created on; created at;
modified on; modified at)
Description
The SET DOCUMENT PROPERTIES command changes the information about the
document whose name or pathname you pass in document.
The dates and times of creation and last modification are managed by the file manager of
your system each time you create or access a document. Using this command, you can
change those properties for special purpose. See example for the command GET
DOCUMENT PROPERTIES.
See Also
GET DOCUMENT PROPERTIES, SET DOCUMENT CREATOR, SET DOCUMENT TYPE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET DOCUMENT ICON returns in the 4D picture variable or field icon, the
icon of the file whose name is passed in filePath. The file can be of any type (executable,
document, shortcut or alias...). However, the command does not return folder icons.
filePath should contain the full pathname of the file. You can also pass the file name only,
in this case the file must be placed in the database current working directory (usually, the
folder containing the database structure file).
If you pass an empty string in filePath, the standard Open File dialog box is presented. The
user can then select the file to read. Once the dialog box is validated, the Document system
variable contains the full pathname to the selected file.
Pass in icon a 4D picture field or variable. After the command is executed, this parameter
contains the icon of the file (PICT format).
The optional size parameter allows you to set the dimensions in pixels of the returned
icon. This value actually represents the side length of the square including the icon. Icons
are usually defined in 32x32 pixels (“large icons”) or 16x16 pixels (“small icons”). If you
pass 0 or omit this parameter, the largest available icon is returned.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get document size returns the size, expressed in bytes, of a document.
If the document is open, you pass its document reference number in document.
If the document is not open, you pass its name or pathname in document.
On Macintosh, if you do not pass the optional * parameter, the size of the data fork is
returned. If you do pass the * parameter, the size of the resource fork is returned.
See Also
Get document position, SET DOCUMENT POSITION, SET DOCUMENT SIZE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET DOCUMENT SIZE command sets the size of a document to the number of bytes
you pass in size.
If the document is open, you pass its document reference number in document.
See Also
Get document position, Get document size, SET DOCUMENT POSITION.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command operates only on a document currently open whose document reference
number you pass in docRef.
Get document position returns the position, starting from the beginning of the
document, where the next read (RECEIVE PACKET) or write (SEND PACKET) will occur.
See Also
RECEIVE PACKET, SEND PACKET, SET DOCUMENT POSITION.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command operates only on a document currently open whose document reference
number you pass in docRef.
SET DOCUMENT POSITION sets the position you pass in offset where the next read
(RECEIVE PACKET) or write (SEND PACKET) will occur.
If you omit the optional anchor parameter, the position is relative to the beginning of the
document. If you do specify the anchor parameter, you pass one of the values listed
above.
Depending on the anchor you can pass positive or negative values in offset.
See Also
Get document position, RECEIVE PACKET, SEND PACKET.
System Environment
version 3.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
On Windows, Screen height returns the height of 4D application window (MDI window).
If you specify the optional * parameter, Screen height returns the height of the screen.
On Macintosh, Screen height returns the height of the main screen, the screen where the
menu bar is located.
See Also
SCREEN COORDINATES, Screen width.
version 3.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
On Windows, Screen width returns the width of 4D application window (MDI window). If
you specify the optional * parameter, Screen width returns the width of the screen.
On Macintosh, Screen width returns the width of the main screen, the screen where the
menu bar is located.
See Also
SCREEN COORDINATES, Screen height.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Count screens returns the number of screen monitors connected to your
machine.
See Also
Menu bar screen, SCREEN COORDINATES, SCREEN DEPTH, Screen height, Screen width.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SCREEN COORDINATES returns in left, top, right, and bottom the global
coordinates of the screen specified by screen.
On Windows
Usually, you will not pass the screen parameter.
On Macintosh
If you omit the screen parameter, the command returns the coordinates of the main
screen, the screen where the menu bar is displayed.
See Also
Count screens, Menu bar screen, SCREEN DEPTH.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Screen depth returns in depth and color information about the monitor.
If the monitor is set to display in color, 1 is returned in color. If the monitor is set to
display in gray scale, 0 is returned in color. Note that this value is significant on the
Macintosh platform.
Example
Your application displays many color graphics. Somewhere in your database, you could
write:
⇒ SCREEN DEPTH ($vlDepth;$vlColor)
If ($vlDepth<8)
ALERT("The forms will look better if the monitor"+" was set to display 256 colors or
more.")
End if
See Also
Count screens, SET SCREEN DEPTH.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command does nothing on Windows.
On Macintosh, SET SCREEN DEPTH changes the depth and color/gray scale settings of the
screen whose number you pass in screen. If you omit this parameter, the command is
applied to the main screen.
For details about the values you pass in color and depth, see the description of the
command SCREEN DEPTH.
See Also
SCREEN DEPTH.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Menu bar screen returns the number of the screen where the menu bar is located.
See Also
Count screens, Menu bar height.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Menu bar height returns the height of the menu bar, expressed in pixels.
See Also
HIDE MENU BAR, Menu bar screen, SHOW MENU BAR.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command FONT LIST populates the string or text array fonts with the names of the
fonts available on your system.
Example
In a form, you want a drop-down list that displays a list of the fonts available on your
system. The method of the drop-down list is as follows:
Case of
: (Form event=On Load)
ARRAY STRING(63;asFont;0)
⇒ FONT LIST(asFont)
` ...
End case
See Also
Font name, Font number.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Font name returns the name of the font whose number is fontNumber. If
there is no available font with that number, the command returns an empty string.
Examples
1. To display a form object with the default system font, you write:
2. To display a form object with the default application font, you write:
See Also
FONT LIST, Font number.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Font number returns the number of the font whose name is fontName. If
there is no font with this name, the command returns 0.
Example
Some forms in your database use the font whose name is “Kind of Special.” Somewhere in
your database, you could write:
See Also
FONT LIST, Font name.
Description
The PLATFORM PROPERTIES command returns information about the type of platform
you are running, the version of the operating system, and the processor installed on your
machine.
The information returned in system and machine depends on the version of 4th
Dimension you are running.
Macintosh version
If you are running a MacOS version of 4th Dimension, the system parameter returns a 32-
bit (Long Integer) value, for which the high level word is unused and the low level word
is structured like this:
- The high byte contains the major version number,
- The low byte is composed of two nibbles (4 bits each). The high nibble is the major
update version number and the low nibble is the minor update version. Example: System
9.0.4 is coded as $0904, so you receive the decimal value 2308.
Note: In 4D, you can extract these values using the % (modulo) and \ (integer division)
numeric operators or the Bitwise operators.
⇒ PLATFORM PROPERTIES($vlPlatform;$vlSystem)
$vlResult:=$vlSystem\256
`If $vlResult = 8 → you are under MacOS 8.x
`If $vlResult = 9 → you are under MacOS 9.x
`If $vlResult = 16 → you are under MacOS 10.x
Windows version
If you are running the Windows version of 4 th Dimension, the system parameter returns
a 32-bit (Long Integer) value, the bits and bytes of which are structured as follows:
If the high level bit is set to 0, it means you are running Windows NT4 or Windows 2000.
If the bit is set to 1, it means you are running Windows 95 or Windows 98.
Note: The high level bit fixes the sign of the long integer value. Therefore, in 4D, you
just need to test the sign of the value; if it is positive you are running Windows NT,
Windows 2000 or Windows XP. You can also use the Bitwise operators.
The low byte gives the major Windows version number. If it returns 4, you are running
Windows 95, 98 or Windows NT 4. If it returns 5, you are running Windows 2000 or
Windows XP. In both cases, the sign of the value tells whether or not you are running
NT/2000.
The next low byte gives the minor Windows version number. If you are running
Windows 95, this value is 0.
Note: In 4D, you can extract these values using the % (modulo) and \ (integer division)
numeric operators or the Bitwise operators.
• The machine parameter returns a value that you can compare to one of the following
predefined constants:
Constant Type Value
INTEL 386 Long Integer 386
INTEL 486 Long Integer 486
Pentium Long Integer 586
PowerPC 601 Long Integer 601
PowerPC 603 Long Integer 603
PowerPC 604 Long Integer 604
PowerPC G3 Long Integer 510
Other G3 and above Long Integer 406
Note: An update list of Macintosh number is published by Apple Computer, Inc. in its
Developer and Technical documentation. New values may be added when Apple or other
manufacturers release new models of the Macintosh.
⇒ PLATFORM PROPERTIES($vlPlatform;$vlSystem;$vlMachine)
If (($vlPlatform<1) | (3<$vlPlatform))
$vsPlatformOS:=""
Else
If ($vlPlatform=3)
$vsPlatformOS:=""
If ($vlSystem<0)
$winMajVers:=((2^31)+$vlSystem)%256
$winMinVers:=(((2^31)+$vlSystem)\256)%256
Case of
: ($winMajVers=4)
$vsPlatformOS:="Windows™ NT"
: ($winMajVers=5)
If ($winMinVers=0)
$vsPlatformOS:="Windows™ 2000"
Else
$vsPlatformOS:="Windows™ XP"
End if
End case
End if
$vsPlatformOS:=$vsPlatformOS+" version
"+String($winMajVers)+"."+String($winMinVers)
Else
$vsPlatformOS:="MacOS™ version "
If (($vlSystem\256) = 16)
$vsPlatformOS:=$vsPlatformOS+"10"
Else
$vsPlatformOS:=$vsPlatformOS+String($vlSystem\256)
End if
$vsPlatformOS:=$vsPlatformOS+"."+String(($vlSystem\16)%16)+
(("."+String($vlSystem%16))*Num(($vlSystem%16) # 0))
End if
End if
ALERT($vsPlatformOS)
See Also
Bitwise Operators.
Description
The command System folder returns the pathname to a system folder within the active
Windows or Macintosh System folder, or to the active Windows or Macintosh System
folder itself.
You pass in the optional type parameter a value indicating the type of system folder. 4D
provides you with the following predefined constants, placed in the “System Folder”
theme:
Constant Type Value
System Long Integer 0
Fonts Long Integer 1
Preferences or Profiles_All Long Integer 2
Preferences or Profiles_User Long Integer 3
Startup Items_All Long Integer 4
Startup Items_User Long Integer 5
Mac Shutdown Items_All Long Integer 6
Mac Shutdown Items_User Long Integer 7
Apple or Start Menu_All Long Integer 8
Apple or Start Menu_User Long Integer 9
Mac Extensions Long Integer 10
Mac Control Panels Long Integer 11
System Win Long Integer 12
System32 Win Long Integer 13
Favorites Win Long Integer 14
Desktop Win Long Integer 15
Program Files Win Long Integer 16
The pathnames to some system folders can specific to the current user. Constants 2 to 9
allows you to choose whether you want to obtain the pathname to a folder which is
shared by all users, or customized for the current user.
Note: The constants Mac Shutdown Items, Mac Extensions and Mac Control Panels can be
used on Mac OS only. When they are used on Windows, System folder will return an
empty string. Conversely, the constants System Win, System32 Win, Favorites Win, Desktop
Win and Program Files Win can be used on Windows only. When they are used on Mac OS,
System folder will return an empty string.
See Also
Get 4D folder, Temporary folder.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Temporary folder returns the pathname to the current temporary folder set
by your system.
Example
See example for the command APPEND TO CLIPBOARD.
See Also
System folder.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Current machine returns the network name of your machine, as set in the
Network Control Panel.
Example
Even if you are not running with the Client/Server version of the 4D environment, your
application can include some network services that require your machine to be correctly
configured. In the On Startup database method of your application, you write:
See Also
Current machine owner.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Current machine owner returns the owner name of your machine, as set in
the Network Control Panel.
Example
See example for the command Current machine.
See Also
Current machine.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Gestalt command returns in value a numeric value that denotes the characteristics of
your system hardware and software, depending on the selector you pass in selector.
Important: The Gestalt Manager is part of MacOS. On Windows, some of the selectors are
also implemented, but the usefulness of this command is limited.
For more information about the selectors that you can pass to Gestalt, refer to the Apple
Developer documentation related to the Gestalt Manager, available on-line at the
following address:
http://developer.apple.com/techpubs/macosx/Carbon/oss/GestaltManager/
gestaltmanager.html
Example
On Macintosh, using version 9.2 of MacOS, the following code displays the alert “You're
running system version 0x0920”:
⇒ $vlErrCode:=Gestalt("sysv";$vlInfo)
If ($vlErrCode=0)
ALERT("You're running system version "+String($vlInfo;"&x"))
End if
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command LOG EVENT allows you to add custom messages that will appear in the
Windows NT Log events. This service maintains a log file that receives and stores messages
coming from running applications. It therefore allows you to monitor the course of a
worksession. For more information, please refer to the 4D Design Mode manual.
Note: For this feature to be available, Windows NT Log events service must be running.
You can attribute a level of importance to message, which helps you to read and
understand the log events. There are three levels of importance: Information, Warning,
and Error. The importance parameter allows you to set the level of importance of the
message.
4th Dimension provides you with the following predefined constants, placed in the
“Windows NT Log Events” category:
Constant Type Value
Information Message Integer 0
Warning Message Integer 1
Error Message Integer 2
If you don’t pass anything in importance or pass an incorrect value, the default value (0)
is used.
Example
If you want to have keep track of when your database is opened, you could write the
following line of code in the On Startup Database Method:
Each time the database is opened, this information will be written in Windows NT’s log
events and its level of importance will be 0.
Table
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
DEFAULT TABLE sets table as the default table for the current process.
There is no default table for a process until the DEFAULT TABLE command is executed.
After a default table has been set, any command that omits the table parameter will
operate on the default table. For example, consider this command:
INPUT FORM ([Table]; "form")
If the default table is first set to [Table], the same command could be written this way:
INPUT FORM ("form")
One reason for setting the default table is to create code that is not table specific. Doing
this allows the same code to operate on different tables. You can also use pointers to tables
to write code that is not table specific. For more information about this technique, see the
description of the Table name command.
DEFAULT TABLE does not allow the omission of table names when referring to fields. For
example:
[My Table]My Field:="A string" ` Good
because a default table had been set. However, you can omit the table name when
referring to fields in the table method, form, and objects that belong to the table.
Tip: Although using DEFAULT TABLE and omitting the table name may make the code
easier to read, many programmers find that using this command actually causes more
problems and confusion than it is worth.
Example
The following example first shows code without the DEFAULT TABLE command. It then
shows the same code, with DEFAULT TABLE. The code is a loop commonly used to add new
records to a database. The INPUT FORM and ADD RECORD commands both require a table
as the first parameter:
INPUT FORM ([Customers];"Add Recs")
Repeat
ADD RECORD ([Customers])
Until (OK = 0)
See Also
Current default table.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Current default table returns a pointer to the table that has been passed to the last call to
DEFAULT TABLE for the current process.
Example
Provided a default table has been set, the following line of code sets the window title to
the name of the current default table:
See Also
DEFAULT TABLE, Table, Table name.
Description
The command INPUT FORM sets the current input form for table to form. The form must
belong to table.
The scope of this command is the current process. Each table has its own input form in
each process.
INPUT FORM does not display the form; it just designates which form is used for data
entry, import, or operation by another command. For information about creating forms,
see the 4th Dimension Design Reference..
The default input form is defined in the Design environment Explorer window for each
table. This default input form is used if the INPUT FORM command is not used to specify
an input form, or if you specify a form that does not exist.
Input forms are displayed by a number of commands, which are generally used to allow
the user to enter new data or modify old data. The following commands display an input
form for data entry or query purposes:
• ADD RECORD
• DISPLAY RECORD
• MODIFY RECORD
• QUERY BY EXAMPLE
The DISPLAY SELECTION and MODIFY SELECTION commands display a list of records
using the output form. The user can double-click on a record in the list, which displays
the input form.
The import commands IMPORT TEXT, IMPORT SYLK and IMPORT DIF use the current
input form for importing records.
Note: Whether or not you pass the optional * parameter, INPUT FORM changes the input
form for the table.
Example
The following example shows a typical use of INPUT FORM:
⇒ INPUT FORM ([Companies]; "New Comp") ` Form for adding new companies
ADD RECORD ([Companies]) ` Add a new company
See Also
ADD RECORD, DISPLAY RECORD, DISPLAY SELECTION, IMPORT DIF, IMPORT SYLK, IMPORT
TEXT, MODIFY RECORD, MODIFY SELECTION, Open window, OUTPUT FORM, QUERY BY
EXAMPLE.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command OUTPUT FORM sets the current output form for table to form. The form
must belong to table.
The scope of this command is the current process. Each table has its own output form in
each process.
OUTPUT FORM does not display the form; it just designates which form is printed,
displayed, or used by another command. For information about creating forms, see the
4th Dimension Design Reference.
The default output form is defined in the Design environment Explorer window for each
table. This default output form is used if the OUTPUT FORM command is not used to
specify an output form, or if you specify a form that does not exist.
Output forms are used by three groups of commands. One group displays a list of records
on screen, another group generates reports, and the third group exports data. The
DISPLAY SELECTION and MODIFY SELECTION commands display a list of records using an
output form. You use the output form when creating reports with the PRINT LABEL and
PRINT SELECTION commands. Each of the export commands (EXPORT DIF, EXPORT SYLK
and EXPORT TEXT) also uses the output form.
Example
The following example shows a typical use of OUTPUT FORM. Note that although the
OUTPUT FORM command appears immediately before the output form is used, this is not
required. In fact, the command may be executed in a completely different method, as
long as it is executed prior to this method:
INPUT FORM ([Parts]; "Parts In") ` Select the input form
⇒ OUTPUT FORM ([Parts]; "Parts List") ` Select the output form
MODIFY SELECTION ([Parts]) ` This command uses both forms
See Also
DISPLAY SELECTION, EXPORT DIF, EXPORT SYLK, EXPORT TEXT, INPUT FORM, MODIFY
SELECTION, PRINT LABEL, PRINT SELECTION.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Current form table command returns the pointer to the table of the form being
displayed or printed in the current process.
If there is no form being displayed or printed in the current process, the command
returns Nil.
If there are several windows open for the current process (which means that the window
opened last is the current active window), the command returns the pointer to the table
of the form displayed in the active window.
If the currently displayed form is the Detail form for a subform area, you are in data entry
and you double-clicked on a record or a subrecord of a double-clickable subform area. In
this case, the command returns:
• The pointer to the table shown in the subform area, if the subform displays a table.
• A non-significant pointer, if the subform area displays a subtable.
Example
Throughout your application, you use the following convention when displaying a
record:
If the variable vsCurrentRecord is present in a form, it displays “New Record” if you are
working with a new record. If you are working with the 56th record of a selection
composed of 5200 records, it displays “56 of 5200”.
See Also
DIALOG, INPUT FORM, OUTPUT FORM, PRINT SELECTION.
Tool Bar
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command HIDE TOOL BAR makes the toolbar invisible.
If the toolbar was already hidden, HIDE TOOL BAR does nothing.
See Also
HIDE MENU BAR, SHOW MENU BAR, SHOW TOOL BAR.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SHOW TOOL BAR makes the toolbar visible.
If the toolbar was already visible, SHOW TOOL BAR does nothing.
See Also
HIDE MENU BAR, HIDE TOOL BAR, SHOW MENU BAR.
Transactions
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Transactions are a series of related data modifications made to a database within a process.
A transaction is not saved to a database permanently until the transaction is validated. If a
transaction is not completed, either because it is canceled or because of some outside
event, the modifications are not saved.
During a transaction, all changes made to the database data within a process are stored
locally in a temporary buffer. If the transaction is accepted with VALIDATE TRANSACTION,
the changes are saved permanently. If the transaction is canceled with CANCEL
TRANSACTION, the changes are not saved.
Since transactions deal with temporary record addresses, after a transaction is validated or
canceled, the selection for each table of the current process becomes empty. For this
reason, you should be cautious when using named selections inside a transaction. After a
transaction is validated or canceled, a named selection created before or during the
transaction may contain incorrect record addresses. For example, a named selection may
contain the address of a deleted record or the temporary address of a record added during
the transaction. This warning also applies to sets, because they are based on bit tables with
record addresses.
The following commands use record numbers—do not use them in a transaction:
• GOTO RECORD
• RELATE ONE SELECTION
• RELATE MANY SELECTION
Transaction Examples
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In this example, the database is a simple invoicing system. The invoice lines are stored in
a table called [Invoice Lines], which is related to the table [Invoices] by means of a relation
between the fields [Invoices]Invoice ID and [Invoice Lines]Invoice ID. When an invoice is
added, a unique ID is calculated, using the Sequence number command. The relation
between [Invoices] and [Invoice Lines] is an automatic Relate Many relation. The Auto
Assign Related Value check box is checked.
This example is a typical situation in which you need to use a transaction. You must be
sure that you can save all these records during the operation or that you will be able to
cancel the transaction if a record cannot be added or updated. In other words, you must
save related data.
If you do not use a transaction, you cannot guarantee the logical data integrity of your
database. For example, if one record of the [Parts] records is locked, you will not be able to
update the quantity stored in the field [Parts]In Warehouse. Therefore, this field will
become logically incorrect. The sum of the parts sold and the parts remaining in the
warehouse will not be equal to the original quantity entered in the record. You can avoid
such a situation by using transactions.
3. To reduce record locking while performing the data entry, you can also choose to
manage transactions from within the form method and access the tables in READ WRITE
only when it becomes necessary.
You perform the data entry using the input form for [Invoices], which contains the
related table [Invoice Lines] in a subform. The form has two buttons: bCancel and bOK,
both of which are no action buttons.
Note that the [Parts] table is now in read-only access mode during data entry. Read/write
access will be available only if the data entry is validated.
The transaction is started in the [Invoices] input form method listed here:
Case of
: (Form Event=On Load)
START TRANSACTION
[Invoices]Invoice ID:=Sequence number([Invoices]Invoice ID)
Else
[Invoices]Total Invoice:=Sum([Invoice Lines]Total line)
End case
If you click the bValidate button, the data entry must be accepted and the transaction
must be validated. Here is the object method of the bOK button:
Case of
: (Form Event=On Clicked)
$NbLines:=Records in selection([Invoice Lines])
READ WRITE([Parts]) ` Switch to Read/Write access for the [Parts] table
FIRST RECORD([Invoice Lines]) ` Start at the first line
$ValidTrans:=True ` Assume everything will be OK
For ($Line;1;$NbLines) ` For each line
RELATE ONE([Invoice Lines]Part No)
OK:=1 ` Assume you want to continue
` Try getting the record in Read/Write access
While (Locked([Parts]) & (OK=1))
CONFIRM("The Part "+[Invoice Lines]Part No+" is in use. Wait?")
If (OK=1)
DELAY PROCESS(Current process;60)
LOAD RECORD([Parts])
End if
End while
If (OK=1)
` Update quantity in the warehouse
[Parts]In Warehouse:=[Parts]In Warehouse-[Invoice Lines]Quantity
SAVE RECORD([Parts]) ` Save the record
Else
$Line:=$NbLines+1 ` Leave the loop
$ValidTrans:=False
End if
NEXT RECORD([Invoice Lines]) ` Go next line
End for
READ ONLY([Parts]) ` Set the table state to read only
If ($ValidTrans)
SAVE RECORD([Invoices]) ` Save the Invoices record
VALIDATE TRANSACTION ` Validate all database modifications
Else
CANCEL TRANSACTION ` Cancel everything
End if
CANCEL ` Leave the form
End case
Depending on your needs, you can let 4D handle transactions during data entry or you
can customize your database, as shown in these examples. In the last example, the
handling of locked records in the [Parts] table could be developed further.
See Also
CANCEL TRANSACTION, In transaction, START TRANSACTION, VALIDATE TRANSACTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
START TRANSACTION
Description
START TRANSACTION starts a transaction in the current process. All changes to the
database are stored temporarily until the transaction is accepted (validated) or canceled.
If you have several global processes, you can have several transactions. You cannot,
however, nest transactions. If you start a transaction inside another transaction,
4th Dimension ignores the second transaction.
See Also
CANCEL TRANSACTION, In transaction, Using Transactions, VALIDATE TRANSACTION.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
VALIDATE TRANSACTION
Description
VALIDATE TRANSACTION accepts the transaction in the current process that was started
with START TRANSACTION. VALIDATE TRANSACTION saves the changes to the database
that occurred during the transaction.
See Also
CANCEL TRANSACTION, In transaction, START TRANSACTION, Using Transactions.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
CANCEL TRANSACTION
Description
CANCEL TRANSACTION cancels the transaction in the current process that was started
with START TRANSACTION. CANCEL TRANSACTION leaves the database unchanged by
canceling the operations executed during the transaction.
See Also
In transaction, START TRANSACTION, Using Transactions, VALIDATE TRANSACTION.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
In transaction → Boolean
Description
The command In transaction returns TRUE if the current process is in a transaction,
otherwise it returns FALSE.
Example
If you perform a multi-record operation (adding, modifying, or deleting records), you
may encounter locked records. In this case, if you have to maintain data integrity, you
must be in transaction so you can “roll-back” the whole operation and leave the database
untouched.
If you perform the operation from within a trigger or from a subroutine (that can be
called while in transaction or not), you can use In transaction to check whether or not
the current process method or the caller method started a transaction. If a transaction was
not started, you do not even start the operation, because you already know that you will
not be able to roll it back if it fails.
See Also
CANCEL TRANSACTION, START TRANSACTION, Triggers, VALIDATE TRANSACTION.
Triggers
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Triggers can prevent “illegal” operations on the records of your database. They are a very
powerful tool for restricting operations on a table, as well as preventing accidental data
loss or tampering. For example, in an invoicing system, you can prevent anyone from
adding an invoice without specifying the customer to whom the invoice is billed.
By default, when you create a table in the Design Environment, it has no trigger.
Activating a trigger that is not yet written or writing a trigger without activating it will
not affect the operations performed on a table.
1. Activating a Trigger
To activate a trigger for a table, you must select one of the Triggers options (database
events) for the table in the Table Properties window:
On deleting a record
If this option is selected, the trigger will be invoked each time a record of the table is
deleted.
This happens when:
• Deleting a record (User environment or calling DELETE RECORD or DELETE SELECTION).
• Performing any operation that provokes deletion of related records through the
deletion control options of a relation.
• Using a Plug-in that calls the DELETE RECORD command.
On loading a record
If this option is selected, the trigger will be invoked each time a record of the table is
loaded. This includes all situations in which a current record is loaded from the data file.
You will use this option less often than the three previous ones.
In order to optimize the operation of 4D, the On loading a record option never triggers a
call to the trigger when using a command that can take advantage of the index.
In fact, when the index is used, records are not loaded and conversely, if the index is not
used (i.e., if the field being processed is not indexed), records are loaded. That would mean
that a trigger for which the On loading a record option was selected could either be or not
be executed depending on the Indexed attribute for the processed field. Rather than
keeping a behaviour that is difficult to anticipate, the decision was made to never execute
the trigger with the On loading a record option selected when using a command that
could take advantage of the index.
Note: If the On loading a record option is selected, the trigger will be executed when a
current record is loaded from the data file, except for the following functions:
• Queries: User queries that were prepared in the standard query editor or by using the
QUERY or QUERY SELECTION commands.
• Order by: Sorts that were prepared in the standard Order by Editor or by using the
ORDER BY command.
• On a series: Sum, Average, Min, Max, Std deviation, Variance, Sum square.
• Commands: RELATE ONE SELECTION, RELATE MANY SELECTION.
Database Events
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
A trigger can be invoked for one of the four database events described above. Within the
trigger, you detect which event is occurring by calling the function Database event. This
function returns a numeric value that denotes the database event.
Typically, you write a trigger with a Case of structure on the result returned by Database
event:
` Trigger for [anyTable]
C_LONGINT($0)
$0:=0 ` Assume the database request will be granted
Case of
⇒ : (Database event=Save New Record Event)
` Perform appropriates action for the saving of a newly created record
⇒ : (Database event=Save Existing Record Event)
` Perform appropriates actions for the saving of an already existing record
⇒ : (Database event=Delete Record Event)
` Perform appropriates actions for the deletion of a record
⇒ : (Database event=Load Record Event)
` Perform appropriates actions for the loading into memory of a record
End case
1. Performing Actions
Each time a record is saved (added or modified) to a [Documents] table , you want to
“mark” the record with a time stamp for creation and another one for the most recent
modification. You can write the following trigger:
` Trigger for table [Documents]
Case of
: (Database event=Save New Record Event)
[Documents]Creation Stamp:=Time stamp
[Documents]Modification Stamp:=Time stamp
Note: The function Time stamp used in this example is a small project method that
returns the number of seconds elapsed since a fixed date was chosen arbitrarily.
After this trigger has been written and activated, no matter what way you add or modify
a record to the [Documents] table (data entry, import, project method, 4D plug-in), the
fields [Documents]Creation Stamp and [Documents]Modification Stamp will automatically be
assigned by the trigger before the record is eventually written to the disk.
Note: See the example for the command GET DOCUMENT PROPERTIES for a complete
study of this example.
Example
Let’s take the case of an [Employees] table. During data entry, you enforce a rule on the
field [Employees]Social Security Number. When you click the validation button, you check
the field using the object method of the button:
` bAccept button object method
If (Good SS number ([Employees]SS number))
ACCEPT
Else
BEEP
ALERT ("Enter a Social Number then click OK again.")
End if
If the field value is valid, you accept the data entry; if the field value is not valid, you
display an alert and you stay in data entry.
If you also create [Employees] records programmatically, the following piece of code would
be programmatically valid, but would violate the rule expressed in the previous object
method:
` Extract from a projec method
` ...
CREATE RECORD ([Employees])
[Employees]Name :="DOE"
SAVE RECORD([Employees]) `←DB rule violation! The SS number has not been assigned!
` ...
Once this trigger is written and activated, the line SAVE RECORD ([Employees]) will
generate a database engine error -15050, and the record will NOT be saved.
Similarily, a 4D Plug-in would attempt to save an [Employees] record with an invalid social
security number. The trigger would generate the same error and the record would not be
saved.
The trigger guarantees that nobody (user, database designer, Plug-in, 4D Open client with
4D Server) can violate the social security number rule, either deliberately or accidentally.
Note that even if you do not have a trigger for a table, you can get database engine errors
while attempting to save or delete a record. For example, if you attempt to save a record
with a duplicated value in a unique indexed field, you the error -9998 is returned.
Therefore, triggers returning errors add new database engine errors to your application:
• 4D manages the “regular” errors: unique index, relational data control, and so on.
• Using triggers, you manage the custom errors unique to your application.
Important: You can return an error code value of your choice. However, do NOT use error
codes already taken by the 4D database engine. We strongly recommend that you use
error codes between -32000 and -15000. We reserve error codes above -15000 for the
database engine.
At the process level, you handle trigger errors the same way you handle database engine
errors:
• You can let 4D display the standard error dialog box, then the method is halted.
• You can use an error-handling method installed using ON ERR CALL and recover the
error the appropriate way.
Note: During data entry, if a trigger error is returned while attempting to validate or
delete a record, the error is handled like a unique indexed error. The error dialog is
displayed, and you stay in the data entry. Even though you only use a database in the
User environment (not in Custom menus), you have the benefit of using triggers.
Triggers execute at the database engine level. This is summarized in the following
diagram:
Triggers are executed on the machine where the database engine is actually located. This
is obvious with a 4D single-user version. On 4D Server, triggers are executed within the
acting process on the server machine, not on the client machine.
When a trigger is invoked, it executes within the context of the process that attempts the
database operation. This process, which invokes the trigger execution, is called the
invoking process.
In particular, the trigger works with the current selections, current records, table
read/write states, and record locking operations of the invoking process.
Warning: A trigger cannot and must not change the current record of the table to which
it is attached. Within a trigger, if you need to check a unique value on multiple fields, use
the command SET QUERY DESTINATION, which allows you to query a table without
changing the current selection or current record of the table.
• Interprocess variables: A trigger has access to the interprocess variables of the machine
where it executes. With 4D Server, it can access a machine different than that of the
invoking process.
• Process variables: An independent process variables table is shared by all the triggers. A
trigger has no access to the process variables of the invoking process.
• Local variables: You can use local variables in a trigger. Their scope is the trigger
execution; they are created/deleted at each execution.
• Semaphores: A trigger can test or set global semaphores as well as local semaphores (on
the machine where it executes). However, a trigger must execute quickly, so you must be
very careful when testing or setting semaphores from within triggers.
• Sets and Named selections: If you use a set or a named selection from within a trigger,
you work on the machine where the triggers executes.
• User Interface: Do NOT use user interface elements in a trigger (no alerts, no messages,
no dialog boxes). Accordingly, you should limit any tracing of triggers in the Debugger
window. Remember that in Client/Server, triggers execute on the 4D Server machine. An
alert message on the server machine does not help a user on a client. Let the invoking
process handle the user interface.
You must handle transactions at the invoking process level. Do not manage transactions
at the trigger level. During one trigger execution, if you have to add, modify or delete
multiple records (see the following case study), you must first use the In transaction
command from within the trigger to test if the invoking process is currently in
transaction. If this is not the case, the trigger may potentially encounter a locked record.
Therefore, if the invoking process is not in transaction, do not even start the operations
on the records. Just return an error in $0 in order to signal the invoking process that the
database operation it tries to perform must be executed in transaction. Otherwise, if
locked records are met, the invoking process will have no means to roll back the actions
of the trigger.
Note: In order to optimize the combined operation of triggers and transactions, 4D does
not call triggers after the execution of VALIDATE TRANSACTION. This prevents the triggers
from being executed twice.
Note: The tables have been collapsed; they have more fields than shown here.
Let’s say that the database “authorizes” the deletion of an invoice. We can examine how
such an operation would be handled at the trigger level (because you could also perform
deletions at the process level).
In order to maintain the relational integrity of the data, deleting an invoice requires the
following actions to be performed in the trigger for [Invoices]:
• In the [Customer] record, decrement the Gross Sales field by the amount of the invoice.
• Delete all the [Line Items] records related to the invoice.
• This also implies that the [Line Items] trigger decrements the Quantity Sold field of the
[Products] record related to the line item to be deleted.
• Delete all the [Payments] records related to the deleted invoice.
First, the trigger for [Invoices] must perform these actions only if the invoking process is
in transaction, so a roll-back is possible if a locked record is met.
Second, the trigger for [Line Items] is cascading with the trigger for [Invoices]. The [Line
Items] trigger executes “within” the execution of the [Invoices] trigger, because the
deletion of the list items are consequent to a call to DELETE SELECTION from within the
[Invoices] trigger.
Consider that all tables in this example have triggers activated for all database events. The
cascade of triggers will be:
• [Invoices] trigger is invoked because the invoking process delete an invoice
• [Customers] trigger is invoked because the [Invoices] trigger updates the Gross
Sales field
• [Line Items] trigger is invoked because the [Invoices] trigger deletes a line item
(repeated)
• [Products] trigger is invoked because the [Line Items] trigger updates the
Quantity Sold field
• [Payments] trigger is invoked because the [Invoices] trigger deletes a payment
(repeated)
From within the triggers, you can use the command Trigger level to detect at the level at
which a trigger is executed. In addition, you get can command TRIGGER PROPERTIES to
get information about the other levels.
For example, if a [Products] record is being deleted at a process level, the [Products] trigger
would be executed at level 1, not at level 3.
Using Trigger level and TRIGGER PROPERTIES, you can detect the cause of an action. In our
example, an invoice is deleted at a process level. If we delete a [Customers] record at a
process level, then the [Customers] trigger should attempt to delete all the invoices related
to that customer. This means that the [Invoices] trigger will be invoked as above, but for
another reason. From within the [Invoices] trigger, you can detect if it executed at level 1
or 2. If it did execute at level 2, you can then check whether or not it is because the
[Customers] record is deleted. If this the case, you do not even need to bother updating
the Gross Sales field.
While handling an On saving new record database event, you can call the Sequence
number command to maintain a unique ID number for the records of a table.
Example
` Trigger for table [Invoices]
Case of
: (Database event=On Saving new record)
` ...
[Invoices]Invoice ID Number:=Sequence number ([Invoices])
` ...
End case
See Also
Database event, Methods, Record number, Trigger level, TRIGGER PROPERTIES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Called from within a trigger, the command Database event returns a numeric value that
denotes the type of the database event, in other words, the reason why the trigger has
been invoked.
Within a trigger, if you perform database operations on multiple records, you may
encounter conditions (usually locked records) that will make the trigger unable to
perform correctly. An example of this situation is updating multiple records in a
[Products] table when a record is being added to an [Invoices] table. At this point, you
must stop attempting database operations, and return a database error so the invoking
process will know that its database request cannot be performed. Then the invoking
process must be able to cancel, during the transaction, the incomplete database operations
performed by the trigger. When this type of situation occurs, you need to know from
within the trigger if you are in transaction even before attempting anything. To do so,
use the command In transaction.
When cascading trigger calls, 4th Dimension has no limit other than the available
memory. To optimize trigger execution, you may want to write the code of your triggers
depending not only on the database event, but also on the level of the call when triggers
are cascaded. For example, during a deletion database event for the [Invoices] table, you
may want to skip the update of the [Customers] Gross Sales field if the deletion of the
[Invoices] record is part of the deletion of all the invoices related to a [Customers] record
being deleted. To do so, use the commands Trigger level and TRIGGER PROPERTIES.
See Also
In transaction, Trigger level, TRIGGER PROPERTIES, Triggers.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Trigger level returns the execution level of the trigger.
For more information on execution levels, see the topic Cascading Triggers in the section
Triggers.
See Also
Database event, TRIGGER PROPERTIES, Triggers.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command TRIGGER PROPERTIES returns information about the trigger execution level
you pass in triggerLevel. You use TRIGGER PROPERTIES in conjunction with Trigger level to
perform different actions depending on the cascading of trigger execution levels. For
more information, see the topic Cascading Triggers in the section Triggers.
If you pass a non-existing trigger execution level, the command returns 0 (zero) in all
parameters.
The nature of the database event for the trigger execution level is returned in dbEvent.
The following predefined constants are provided:
Constant Type Value
Save New Record Event Long Integer 1
Save Existing Record Event Long Integer 2
Delete Record Event Long Integer 3
Load Record Event Long Integer 4
The table number and record number for the record involved by the database event for
the trigger execution level are returned in tableNum and recordNum.
Note: Remember that while in transaction, newly created records have temporary record
numbers.
See Also
About Record Numbers, Database event, Trigger level, Triggers.
User Interface
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
BEEP
Description
The command BEEP causes the PC or Macintosh to generate a beep. Your computer (on
Windows or Macintosh) can emit a sound other than a beep, depending on the sound
chosen in the Sound control panel.
Warning: Do not call BEEP from within a Web connection process, because the beep will
be produced on the 4th Dimension Web server machine and not on the client Web
browser machine.
Example
In the following example, if no records are found by the query, a beep is emitted and an
alert is displayed:
QUERY([Customers];[Customers]Name=$vsNameToLookFor)
If (Records in selection([Customers])=0)
⇒ BEEP
ALERT("There is no Customer with such a name.")
End if
See Also
PLAY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description on Windows
On Windows, the command PLAY plays sound (.WAV files), MIDI (.MID files), or Video
(.AVI files) Windows files. You pass the full pathname of the file you want to play in
objectName.
Note: You cannot play multimedia files or objects in asynchronous mode. To do so, use
OLE Services.
On Macintosh or on Windows (with some restrictions, see Important Note below), the
command PLAY plays the sound resource named by objectName on Macintosh.
The channel parameter specifies the Macintosh synthesizer channel. If channel is not
specified, the channel is for simple digitized sounds and is synchronous. Synchronous
means that all processing stops until the sound has finished. If channel is 0, the channel is
for simple digitized sounds and is asynchronous. Asynchronous means that processing
does not stop and the sound plays in the background.
⇒ PLAY ("";0)
If you work with a database on Macintosh and Windows concurrently, you can also play
Macintosh sounds on the Windows platform. To do so:
• On the Macintosh, using a resource editor such as ResEdit or Resorcerer, copy the
required 'snd ' resources into the resource fork of the structure file.
• Transport the database from Macintosh to Windows, using 4D Transporter.
You can check the internal data of a ‘snd’ resource using Resorcerer.
Examples
1. The following example shows how to play a video file on Windows:
$DocRef := Open document ( ""; "AVI")
If (OK=1)
CLOSE DOCUMENT($DocRef)
⇒ PLAY (Document)
End if
2. The following example code appears in a startup method. It welcomes the user with a
sound called Welcome Sound on Macintosh:
See Also
BEEP.
Description
The command Get platform interface returns a numeric value that denotes the current
platform interface used for displaying forms.
You can change the platform interface using the command SET PLATFORM INTERFACE or
within the Design environment Database Properties dialog box.
See Also
GET PLATFORM INTERFACE.
Description
The command SET PLATFORM INTERFACE sets the platform interface used for displaying
the forms.
Note: The constant Mac Theme allows you to use the user interface defined with the
Appearance Manager. This manager only exists on Mac OS. When a database defined with
“Mac Theme” interface is displayed on Windows, the interface “Windows 9x” is applied.
The command does nothing if the value you pass does not change the current platform
interface.
Note: The platform interface can also be changed in the Design environment Database
Properties dialog box.
See Also
Get platform interface.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET TABLE TITLES enables you to mask, rename, and reorder the tables of your database
when they appear in standard 4th Dimension dialog boxes such as the Query editor,
within the User or Custom Menus environments.
Using this command, you can also rename on the fly the table labels in your forms, if
you used dynamic names. For more information about inserting dynamic field and table
names in the forms, refer to the 4th Dimension Design Reference.
The arrays tableTitles and tableNumbers must be synchronized. In the array tableTitles, you
pass the names of the tables as you would like them to appear. If you do not want to
show a particular table, do not include its name or new title in the array. The tables will
appear in the order you specify in this array. In each element of the array tableNumbers,
you pass the actual table number corresponding to the table name or new title passed in
the same element number in the array tableTitles.
For example, you have a database composed of the tables A, B, and C, created in that
order. You want these tables to appear as X, Y, and Z. In addition you do not want to
show table B. Finally, you want to show Z and X, in that order. To do so, you pass Z and X
in a two-element tableTitles array, and you pass 3 and 1 in a two-element tableNumbers
array.
SET TABLE TITLES does NOT change the actual structure of your database. It only affects
posterior uses of the standard 4th Dimension dialog boxes and forms using dynamic
names within the User or Custom menus environments. The scope of the command SET
TABLE TITLES is the worksession. One benefit in Client/Server, is that several 4D Client
stations can simultaneously “see” your database in different ways. You can call SET TABLE
TITLES as many times as you want.
Example
• You are building a 4D application that you plan to sell internationally. Therefore, you
must carefully consider localization issues. Regarding the standard 4th Dimension dialog
boxes that can appear in the User and Custom Menus environments and your forms that
use dynamic names you can address localization needs by using a [Translations] table and
a few project methods to create and use fields localized for any number of countries.
• In your database, add the following table:
• Then, create the TRANSLATE TABLES AND FIELDS project method listed below. This
method browses the actual structure of your database and creates all the necessary
[Translations] records for the localization corresponding to the language passed as
parameter.
` TRANSLATE TABLES AND FIELDS project method
` TRANSLATE TABLES AND FIELDS ( String )
` TRANSLATE TABLES AND FIELDS ( Language )
C_STRING(31;$1)
C_LONGINT($vlTable;$vlField)
• At this point, if you execute the following line, you create as many records as needed for
a Spanish localization of the tables and fields titles.
TRANSLATE TABLES AND FIELDS ("Spanish")
• After this call has been executed, you can then enter the [Translations]Translated Name
for each of the newly created records.
• Finally, each time you want to show your database’s standard 4D dialog boxes or forms
with dynamic titles using the Spanish localization, you execute the following line:
LOCALIZED TABLES AND FIELDS ("Spanish")
C_STRING(63;$1)
C_LONGINT($vlTable;$vlNbTable;$vlField;$vlNbField)
• Note that new localizations can be added to the database without modifying or
recompiling the code.
See Also
Count tables, SET FIELD TITLES, Table name.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
SET FIELD TITLES enables you to mask, rename, and reorder the fields of the table or
subtable passed in table or subtable when they appear in standard 4th Dimension dialog
boxes, such as the Query editor, within the User or Custom Menus environments.
Using this command, you can also rename on the fly the labels of the fields in your
forms, if you used dynamic names. For more information about inserting dynamic field
and table names in the forms, refer to the 4th Dimension Design Reference.
The arrays fieldTitles and fieldNumbers must be synchronized. In the array fieldTitles, you
pass the name of the fields as you would like them to appear. If you do not want to show
a particular field, do not include its name or new title into the array. The fields will appear
in the order you specify in this array. In each element of the array fieldNumbers, you pass
the actual field number corresponding to the field name or new title passed in the same
element number in the array fieldTitles.
For example, you have a table or subtable composed of the fields F, G, and H, created in
that order. You want these fields to appear as M, N, and O. In addition you do not want
to show field N. Finally, you want to show O and M in that order. To do so, pass O and M
in a two-element fieldTitles array and pass 3 and 1 in a two-element fieldNumbers array.
SET FIELD TITLES does NOT change the actual structure of your table. It only affects
posterior uses of the standard 4th Dimension dialog boxes and forms using dynamic
names within the User or Custom menus environments. The scope of the command SET
FIELD TITLES is the worksession. One benefit in Client/Server, is that several 4D Client
stations can simultaneously “see” your table in different manners. You can call SET FIELD
TITLES as many times as you want.
Example
See example for the command SET TABLE TITLES.
See Also
Count fields, Field name, SET TABLE TITLES.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Shift down returns TRUE if the Shift key is pressed.
Example
The following object method for the button bAnyButton performs different actions,
depending on which modifier keys are pressed when the button is clicked:
` bAnyButton Object Method
Case of
` Other multiple key combinations could be tested here
` ...
: (Shift down & Windows Ctrl down)
` Shift and Windows Ctrl (or Macintosh Command) keys are pressed
DO ACTION1
` ...
: (Shift down)
` Only Shift key is pressed
DO ACTION2
` ...
: (Windows Ctrl down)
` Only Windows Ctrl (or Macintosh Command) key is pressed
DO ACTION3
` ...
` Other individual keys could be tested here
` ...
End case
See Also
Caps lock down, Macintosh command down, Macintosh control down, Macintosh option
down, Windows Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Caps lock down returns TRUE if the Caps Lock key is pressed.
Example
See example for the command Shift down.
See Also
Macintosh command down, Macintosh control down, Macintosh option down, Shift down,
Windows Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Windows Ctrl down returns TRUE if the Windows Ctrl key is pressed.
Note: When called on a Macintosh platform, Windows Ctrl down returns TRUE if the
Macintosh Command key is pressed.
Example
See example for the command Shift down.
See Also
Caps lock down, Macintosh command down, Macintosh option down, Shift down, Windows
Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Windows Alt down returns TRUE if the Windows Alt key is pressed.
Note: When called on a Macintosh platform, Windows Alt down returns TRUE if the
Macintosh Option key is pressed.
Example
See example for the command Shift down.
See Also
Caps lock down, Macintosh command down, Macintosh control down, Macintosh option
down, Shift down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Macintosh command down returns TRUE if the Macintosh command key is pressed.
Note: When called on a Windows platform, Macintosh command down returns TRUE if
the Windows Ctrl key is pressed.
Example
See example for the command Shift down.
See Also
Caps lock down, Macintosh control down, Macintosh option down, Shift down, Windows Alt
down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Macintosh option down returns TRUE if the Macintosh Option key is pressed.
Note: When called on a Windows platform, Macintosh option down returns TRUE if the
Windows Alt key is pressed.
Example
See example for the command Shift down.
See Also
Caps lock down, Macintosh command down, Macintosh control down, Shift down, Windows
Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Macintosh control down returns TRUE if the Macintosh Control key is pressed.
Note: When called on a Windows platform, Macintosh control down always return FALSE.
This Macintosh key has no equivalent on Windows.
Example
See example for the command Shift down.
See Also
Caps lock down, Macintosh command down, Macintosh option down, Shift down, Windows
Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET MOUSE returns the current state of the mouse.
The horizonal and vertical coordinates are returned in mouseX and mouseY. If you pass
the * parameter, the coordinates are expressed relative to the screen. If you omit the *
parameter, they are expressed relative to the frontmost window of the current process.
The parameter mouseButton returns the state of the buttons, as listed previously.
Example
See the example for the command Pop up menu.
See Also
Caps lock down, Macintosh command down, Macintosh control down, Macintosh option
down, ON EVENT CALL, Shift down, Windows Alt down, Windows Ctrl down.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Pop up menu displays a pop-up menu at the current location of the mouse.
In order to follow user interface rules, you usually call this command in response to a
mouse click and if the mouse button is still down.
You define the items of the pop-up menu with the parameter contents as follows:
• Separate each item from the next one with a semi-colon (;). For example,
"ItemText1;ItemText2;ItemText3".
• To disable an item, place an opening parenthesis (() in the item text.
• To specify a separation line, pass "(-" as item text.
• To specify a font style for a line, place in the item text a less than sign (<) followed by
one of these characters:
<B Bold
<I Italic
<U Underline
<O Outline (Macintosh only)
<S Shadow (Macintosh only)
• To add a check mark to an item, place in the item text an exclamation mark (!) followed
by the character you want as a check mark. On Macintosh, the character is displayed; on
Windows, a check mark is displayed, no matter what character you passed.
• To add an icon to an item, place in the item text a circumflex accent (^) followed by a
character whose ASCII code plus 208 is the resource ID of a MacOS-based icon resource.
• To add a shortcut to an item, place in the item text a slash (/) followed by the shortcut
character for the item. Note that this last option is purely informative; no shortcut will
activate the pop-up menu. However, you may want to include a shortcut if the pop-up
menu item has an equivalent in the main menu bar of your application.
The optional default parameter allows you to specify the default menu item selected when
the pop-up menu is displayed. Pass a value between 1 and the number of menu items. If
you omit this parameter, the command selects the first menu item as the default.
Note: Use pop-up menus that have a reasonable number of items. If you want to display
more than 50 items, you might think about a using scrollable area in a form instead of a
pop-up menu.
Example
The project method MY SPEED MENU pulls down a navigation speed menu:
` MY SPEED MENU project method
GET MOUSE($vlMouseX;$vlMouseY;$vlButton)
If (Macintosh control down | ($vlButton=2))
$vtItems:="About this database...<I;(-;!-Other Options;(-"
For ($vlTable;1;Count tables)
$vtItems:=$vtItems+";"+Table name($vlTable)
End for
⇒ $vlUserChoice:=Pop up menu($vtItems)
Case of
: ($vlUserChoice=1)
` Display Information
: ($vlUserChoice=2)
` Display options
Else
If ($vlUserChoice>0)
` Go to table whose number is $vlUserChoice-4
End if
End case
End if
In the last two cases, the click does not need to occur in any form object. This is one of
the advantages of the Pop up menu command. Generally, you use form objects to display
pop-up menus. Using Pop up menu, you can display the menu anywhere.
The pop-up menu is displayed on Windows by pressing the right mouse button; it is
displayed on Macintosh by pressing Control-Click. Note, however, that the method does
not actually check whether or not there was a mouse click; the caller method tests that.
See Also
GET MOUSE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The POST KEY command simulates a keystroke. Its effect is as if the user actually entered a
character on the keyboard.
If you pass the modifiers parameter, you pass one or a combination of the Events
(modifiers) constants. For example, to simulate the Shift key, pass Shift key mask. If you do
not pass modifiers, no modifiers are simulated.
If you specify the process parameter, the keystroke is sent to the process whose process
number you pass in process. If you pass 0 (zero) or if you omit the parameter, the
keystroke is sent at the application level, and the 4D scheduler will dispatch it to the
appropriate process.
Example
See example for the command Process number.
See Also
POST CLICK, POST EVENT.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command POST CLICK simulates a mouse click. Its effect as if the user actually clicked
the mouse button.
You pass the horizontal and vertical coordinates of the click in mouseX and mouseY. If
you pass the * parameter, you express these coordinates relative to the screen. If you omit
the * parameter, you express these coordinates relative to the frontmost window of the
process whose process number you pass in process.
If you specify the process parameter, the click is sent to the process whose process number
you pass in process. If you pass 0 (zero) or if you omit the parameter, the click is sent at
the application level, and the 4D scheduler will dispatch it to the appropriate process.
See Also
POST EVENT, POST KEY.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command POST EVENT simulates a keyboard or mouse event. Its effect is as if the user
actually acted on the keyboard or the mouse.
If the event is a mouse-related event, you pass 0 (zero) in message. If the event is a
keyboard-related event, you pass the ASCII code of the simulated character in message.
If the event is a mouse-related event, you pass the horizontal and vertical coordinates of
the click in mouseX and mouseY.
In the parameter modifiers, you pass one or a combination of the Events (modifiers)
constants. For example, to simulate the Shift key, pass Shift key bit.
If you specify the process parameter, the event is sent to the process whose process
number you pass in process. If you pass 0 (zero) or if you omit the parameter, the event is
sent at the application level, and the 4D scheduler will dispatch it to the appropriate
process.
See Also
POST CLICK, POST KEY.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET HIGHLIGHT is used to determine what text is currently highlighted.
Warning: Although you pass a field or variable enterable area name to GET HIGHLIGHT,
this command returns the significant selection position only when it is applied to the
area currently being edited.
Note: This command cannot be used with fields in the List form of a subform.
The parameter startSel returns the position of the first highlighted character.
The parameter endSel returns the position of the last highlighted character plus one.
If startSel and endSel are returned equal, the insertion point is positioned before the
character specified by startSel. The user has not selected any text, and no characters are
highlighted.
Examples
1. The following example gets the highlighted selection from the field called
[Products]Comments:
See Also
FILTER KEYSTROKE, HIGHLIGHT TEXT, Keystroke.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command HIGHLIGHT TEXT highlights a section of the text in area.
If area is not the object currently being edited, the focus is then set to this area.
Note: This command cannot be used with fields in the List form of a subform.
startSel is the first character position to be highlighted, and lastSel is the last character plus
one to be highlighted. If startSel and lastSel are equal, the insertion point is positioned
before the character specified by startSel, and no characters are highlighted.
If lastSel is greater than the number of characters in area, then all characters between
startSel and the end of the text are highlighted.
Example
1. The following example selects all the characters of the enterable field
[Products]Comments:
⇒ HIGHLIGHT TEXT([Products]Comments;1;Length([Products]Comments)+1)
2. The following example moves the insertion point to the beginning of the enterable
field [Products]Comments:
⇒ HIGHLIGHT TEXT([Products]Comments;1;1)
3. The following example moves the insertion point to the end of the enterable field
[Products]Comments:
$vLen:=Length([Products]Comments)+1
⇒ HIGHLIGHT TEXT([Products]Comments;$vLen;$vLen)
See Also
GET HIGHLIGHT.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET CURSOR changes the mouse cursor to the cursor stored in the MacOS-
based ‘CURS’ resource whose ID number you pass in cursor.
If you omit the parameter, the mouse cursor is set to the standard arrow.
Use the command RESOURCE LIST to get the list of available cursors.
See Also
RESOURCE LIST.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Last object returns a pointer to the last or current enterable area, in other words, the
object that the cursor is in or has just left. You can use Last object to perform an action on
a form area without having to know which object is currently selected. Be sure to test that
the object is the correct data type, using Type, before performing an action on it. This
command cannot be used with fields in subforms.
Note: This command is to be used only in data entry context, otherwise it will return
errors.
Example
The following example is an object method for a button. The object method changes the
data in the current object to uppercase. The object must be a text or string data type (type
0 or 24):
⇒ $vp := Last object ` Save the pointer to the last area
If ((Type ($vp->) = Is Alpha field) | (Type($vp->) = Is String var))
` If it is a string or text area
$vp-> := Uppercase ($vp->) ` Change the area to uppercase
End if
REDRAW (object)
Description
When you use a method to change the value of a field or subfield displayed in a subform,
you must execute REDRAW to ensure that the form is updated.
Web Server: When executed after the On Timer form event, the REDRAW command can
be called to periodically update a 4D form sent to a Web browser. For more information,
please refer to the description of the SET TIMER command.
See Also
SET TIMER.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
INVERT BACKGROUND is used to invert textVar or textField in the form.
You can use INVERT BACKGROUND when displaying on screen or printing to a dot matrix
printer. A postscript printer will not print an inverted background.
You cannot invert a variable in an output form. Avoid using INVERT BACKGROUND on an
enterable variable. Entering characters will only partially erase the inverted display.
Example
This example is an object method for a variable in an input form. It tests the value of a
field. If the field is positive, the object method does nothing. If the field is negative, the
object method inverts the display of the variable in the form:
vAmount:=[Accounts]Amount ` Put the value of field in the variable
If (vAmount < 0) ` If it is a negative amount…
⇒ INVERT BACKGROUND (vAmount) ` Invert the background
End if
Note: This command, originally created for black and white user interfaces, is now rarely
used. You now generally use colors to highlight a field or a variable.
See Also
SET COLOR, SET RGB COLORS.
version 5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
EDIT ACCESS
Description
EDIT ACCESS allows the user to edit the password system. The Passwords window in the
Design environment is used to edit the access.
Groups can be edited by the Designer, the Administrator and group owners. The Designer
and the Administrator can edit any group. Group owners can edit only the groups they
own. Users can be added to and removed from groups. The command has no effect if no
groups are defined.
The Designer and the Administrator can add new users, as well as assign them to groups.
In Client/Server compiled databases, the Designer and the Administrator can also use this
command to save the path to the 4D Server database (see the section Creating a Path
Document in the 4D Server Reference guide).
Example
The following example displays the Passwords window to the user:
⇒ EDIT ACCESS
See Also
CHANGE ACCESS, CHANGE PASSWORD.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
CHANGE ACCESS
Description
CHANGE ACCESS allows the user to change to a different access level without leaving the
database. The same password dialog box that is displayed when the user launches the
database is presented, and the user can gain access as a different user.
The dialog box displayed will depend on the Preferences set in the Database Properties
dialog box in the Design Environment.
Example
The following example displays the password dialog box to the user:
⇒ CHANGE ACCESS
See Also
CHANGE PASSWORD.
version 6.0.2
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Validate password returns True if the string passed in password is the password for the user
account whose ID number is passed in userID.
Example
This example checks whether the password of the user “Hardy” is “Laurel”:
GET USER LIST(atUserName;alUserID)
$vlElem:=Find in array(atUserName;"Hardy")
If ($vlElem>0)
⇒ If (Validate password(alUserID{$vlElem};"Laurel")>0)
ALERT("Yep!")
Else
ALERT("Too bad!")
End if
Else
ALERT("Unknown user name")
End if
See Also
GET USER PROPERTIES, SET USER PROPERTIES.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CHANGE PASSWORD changes the password of the current user. This command replaces
the current password with the new password you pass in password.
Example
The following example allows the user to change his or her password.
CHANGE ACCESS ` Present user with password dialog
If (OK=1)
$pw1:=Request("Enter new password for "+Current user)
` The password should be at leat five characters long
If (((OK=1) & ($pw1#"")) & (Length($pw1)>5))
` Make sure the password has been entered correctly
$pw2:=Request("Enter password again")
If ((OK=1) & ($pw1=$pw2))
CHANGE PASSWORD($pw2) ` Change the password
End if
End if
End if
See Also
CHANGE ACCESS.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Current user returns the user name of the current user.
Example
See example for the command User in group.
See Also
CHANGE ACCESS, CHANGE PASSWORD, User in group.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
User in group returns TRUE if user is in group.
Example
The following example searches for specific invoices. If the current user is in the
Executive group, he or she is allowed access to forms that display confidential
information. If the user is not in the Executive group, a different form is displayed:
QUERY([Invoices];[Invoices]Retail>100)
⇒ If (User in group(Current user;"Executive"))
OUTPUT FORM([Invoices];"Executive Output")
INPUT FORM([Invoices];"Executive Input")
Else
OUTPUT FORM([Invoices];"Standard Output")
INPUT FORM([Invoices];"Standard Input")
End if
MODIFY SELECTION([Invoices];*)
See Also
Current user.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command DELETE USER deletes the user whose unique user ID number you pass in
userID. You must pass a valid user ID number returned by the command GET USER LIST.
If the user account does not exist or has already been deleted, the error -9979 is generated.
You can catch this error with an error-handling method installed using ON ERR CALL.
Deleted user names no longer appear in the Password window displayed when the
database is open or when you call CHANGE ACCESS. However, in order to maintain unique
user ID numbers, the user account is kept in the password system. Deleted user names are
displayed in green in the Design environment Passwords window.
See Also
GET USER LIST, GET USER PROPERTIES, Is user deleted, SET USER PROPERTIES.
Error Handling
If you do not have the proper access privileges for calling DELETE USER or if the Password
system is already accessed by another process, an access privilege error is generated. You
can catch this error with an error-handling method installed using ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Is user deleted tests the user account whose unique user ID number you
pass in userID.
If the user account does not exist or has been deleted, Is user deleted returns TRUE.
Otherwise, it returns FALSE.
See Also
DELETE USER, GET USER PROPERTIES, SET USER PROPERTIES.
Error Handling
If you do not have the proper access privileges for calling Is user deleted or if the Password
system is already accessed by another process, an access privilege error is generated. You
can catch this error with an error-handling method installed using ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GET USER LIST populates the arrays userNames and userNumbers with the names and
unique ID numbers of the users as they appear in the Passwords window.
The array userNames is filled with the user names displayed in the Passwords window,
including users whose accounts are disabled (user names displayed in green in the
Passwords window).
The array userNumbers, synchronized with userNames, is filled with the corresponding
unique user ID numbers. These numbers can have the following values or ranges:
User ID number User description
1 Designer user
2 Administrator user
3 to 15000 User created by the Designer of the database
(user #3 is the first user created by the Designer,
user #4 the second, and so on).
-11 to -15000 User created by the Administrator of the database
(user #-11 is the first user created by the Designer,
user #-12 is the second, and so on).
See Also
GET GROUP LIST, GET USER PROPERTIES, SET USER PROPERTIES.
Error Handling
If you do not have the proper access privileges for calling GET USER LIST or if the Password
system is already accessed by another process, an access privilege error is generated. You
can catch this error with an error-handling method installed using ON ERR CALL.
version 6.0.2
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
GET USER PROPERTIES (userID; name; startup; password; nbLogin; lastLogin{; memberships})
Description
GET USER PROPERTIES returns the information about the user whose unique user ID
number you pass in userID. You must pass a valid user ID number returned by the
command GET USER LIST.
If the user account does not exist or has been deleted, the error -9979 is generated. You
can catch this error with an error-handling method installed using ON ERR CALL.
Otherwise, you can call Is user deleted to test the user account before calling GET USER
PROPERTIES.
See Also
GET GROUP LIST, GET USER LIST, SET USER PROPERTIES, Validate password.
Error Handling
If you do not have the proper access privileges for calling GET USER PROPERTIES or if the
Password system is already accessed by another process, an access privilege error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
Set user properties (userID; name; startup; password; nbLogin; lastLogin{; memberships}) →
Number
Description
Set user properties enables you to change and update the properties of an existing user
account whose unique user ID number you pass in userID, or to add a new user affiliated
with the Designer or the Administrator.
If you are changing the properties of an existing user account, you must pass a valid user
ID number returned by the command GET USER LIST.
If the user account does not exist or has been deleted, the error -9979 is generated. You
can catch this error with an error-handling method installed using ON ERR CALL.
Otherwise, you can call Is user deleted to test the user account before calling Set user
properties.
If you do not pass -1, -2 or a valid user ID number, Set user properties does nothing.
Before the call, you pass the new name, startup method, password, number of logins and
date of last login for the user, in the parameters name, startup, password, nbLogin and
lastLogin. You pass an unencrypted password in the password parameter. 4D will encrypt it
for you before saving it in the user account.
If the new user name passed in name is not unique (there is already a user with the same
name), the command does nothing and the error -9979 is returned. You can catch ths
error with an error-handling method installed using ON ERROR CALL.
If you do not want to change all the properties of the user (aside from the memberships,
see below), first call GET USER PROPERTIES and pass the returned values for the properties
you want to leave unchanged.
If you do not want to change the password for an account, pass the * symbol as a value
for the password parameter. This allows you to change the other properties of the user
account without changing the password for the account.
If you do not pass the optional memberships parameter, the current memberships of the
user are left unchanged. If you do not pass memberships when adding a user, the user will
not belong to any group. If you pass the optional memberships parameter, you change all
the memberships for the user. Before the call, you must populate the array memberships
with the unique ID numbers of the groups to which the user will belong. Group ID
numbers can have the following ranges:
Group ID number Group description
15001 to 32767 Group created by the Designer or affiliated Group Owner
(group #15001 is the first group created by the Designer,
group #15002 the second, and so on).
-15001 to -32768 Group created by the Administrator or affiliated Group Owner
(group #-15001 is the first group created by the Administrator,
group #-15002 the second, and so on).
See Also
DELETE USER, GET GROUP LIST, GET USER LIST, GET USER PROPERTIES, Is user deleted,
Validate password.
Error Handling
If you do not have the proper access privileges for calling Set user properties or if the
Password system is already accessed by another process, an access privilege error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GET GROUP LIST populates the arrays groupNames and groupNumbers with the names and
unique ID numbers of the groups as they appear in the Password editor window.
The array groupNumbers, synchronized with groupNames, is filled with the corresponding
unique group ID numbers. These numbers can have the following ranges:
Group ID number Group description
15001 to 32767 Group created by the Designer or affiliated Group Owner
(group #15001 is the first group created by the Designer,
group #15002 the second, and so on).
-15001 to -32768 Group created by the Administrator or affiliated Group Owner
(group #-15001 is the first group created by the Administrator,
group #-15002 the second, and so on).
See Also
GET GROUP PROPERTIES, GET USER LIST, SET GROUP PROPERTIES.
Error Handling
If you do not have the proper access privileges for calling GET GROUP LIST or if the
Password system is already accessed by another process, an access privilege error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
GET GROUP PROPERTIES returns the properties of the group whose unique group ID
number you pass in groupID. You must pass a valid group ID number returned by the
command GET GROUP LIST. Group ID numbers can have the following values or ranges:
Group ID number Group description
15001 to 32767 Group created by the Designer or affiliated Group Owner
(group #15001 is the first group created by the Designer,
group #15002 the second, and so on).
-15001 to -32768 Group created by the Administrator or affiliated Group Owner
(group #-15001 is the first group created by the Administrator,
group #-15002 the second, and so on).
If you do not pass a valid group ID number, GET GROUP PROPERTIES returns empty
parameters.
After the call, you retrieve the name and owner of the group, in the parameters name and
owner.
See Also
GET GROUP LIST, GET USER LIST, SET GROUP PROPERTIES.
Error Handling
If you do not have the proper access privileges for calling GET GROUP PROPERTIES or if
the Password system is already accessed by another process, an access privilege error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Set group properties enables you to change and update the properties of an existing group
whose unique group ID number you pass in groupID, or to add a new group affiliated with
the Designer or the Administrator.
If you are changing the properties of an existing group, you must pass a valid group ID
number returned by the command GET GROUP LIST. Group ID numbers can have the
following values or ranges:
Group ID number Group description
15001 to 32767 Group created by the Designer or affiliated Group Owner
(group #15001 is the first group created by the Designer,
group #15002 the second, and so on).
-15001 to -32768 Group created by the Administrator or affiliated Group Owner
(group #-15001 is the first group created by the Administrator,
group #-15002 the second, and so on).
To add a new group affiliated with the Designer, pass -1 in groupID. To add a new group
affiliated with the Administrator, pass -2 in groupID. After the call, if the group is
successfully added, its unique ID number is returned in groupID.
If you do not pass -1, -2 or a valid group ID number, Set group properties does nothing.
Before the call, you pass the new name and owner of the group in the parameters name
and owner. If you do not want to change all the properties of the group (besides the
members, see below), first call GET GROUP PROPERTIES and pass the returned values for
the properties you want to leave unchanged.
If you pass the optional members parameter, you change the whole member list for the
group. Before the call, you must populate the array members with the unique ID numbers
of the users and groups the group will get as members. Member ID numbers can have the
following ranges:
Member ID number Member Description
1 Designer user
2 Administrator user
3 to 15000 User created by the Designer of the database
(user #3 is the first user created by the Designer,
user #4 the second, and so on).
-11 to -15000 User created by the Administrator of the database
(user #-11 is the first user created by the Designer,
user #-12 is the second, and so on).
15001 to 32767 Group created by the Designer or affiliated Group Owner
(group #15001 is the first group created by the Designer,
group #15002 the second, and so on).
-15001 to -32768 Group created by the Administrator or affiliated Group Owner
(group #-15001 is the first group created by the Administrator,
group #-15002 the second, and so on).
To remove all the members from a group, pass an empty members array.
See Also
GET GROUP LIST, GET GROUP PROPERTIES, GET USER LIST.
Error Handling
If you do not have the proper access privileges for calling Set group properties or if the
Password system is already accessed by another process, an access privilege error is
generated. You can catch this error with an error-handling method installed using ON
ERR CALL.
CHANGE LICENSES
Description
The command CHANGE LICENSES displays the 4D License dialog box, which enables the
user to add 4D's Expansion (4D Server only) or Serial licenses.
Here is the 4D License dialog box:
Note: For more information about this dialog box, please refer to the 4D Product Line
Installation Guide.
In the Design environment, you display this dialog box by clicking the Licenses button
in the Database Properties dialog box. Using the CHANGE LICENSES command, you can
display the 4D License dialog box from the User and Custom menus environments.
Example
In a "configuration" or "preferences" dialog box, you include a button whose method is:
` bLicense button object method
⇒ CHANGE LICENSES
Variables
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SAVE VARIABLES saves one or several variables in the document whose
name you pass in document.
The variables do not need to be of the same type, but have to be of type String, Text,
Real, Integer, Long Integer, Date, Time, Boolean, or Picture.
If you supply an empty string for document, the standard Save File dialog box appears; the
user can then choose the document to create. In this case, the 4D system variable
Document is set to the name of the document if one is created.
If the variables are properly saved, the OK variable is set to 1. If not, OK is set to 0.
Note: When you write variables to documents with SAVE VARIABLES, 4th Dimension uses
an internal data format. You can retrieve the variables only with the LOAD VARIABLES
command. Do not use RECEIVE VARIABLE or RECEIVE PACKET to read a document created
by SAVE VARIABLES.
WARNING: This command does not support array variables. Use the new BLOB commands
instead.
Example
The following example saves three variables to a document named UserPrefs:
See Also
BLOB TO DOCUMENT, BLOB TO VARIABLE, DOCUMENT TO BLOB, LOAD VARIABLES,
VARIABLE TO BLOB.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command LOAD VARIABLES loads one or several variables from the document
specified by document. The document must have been created using the command SAVE
VARIABLES.
The variables variable, variable2...variableN are created; if they already exist, they are
overwritten.
If you supply an empty string for document, the standard Open File dialog box appears, so
the user can choose the document to open. If a document is chosen, the 4D system
variable Document is set to the name of the document.
In compiled databases, each variable must be of the same type as those loaded from disk.
WARNING: This command does not support array variables. Use the new BLOB commands
instead.
Example
The following example loads three variables from a document named UserPrefs:
See Also
BLOB TO DOCUMENT, BLOB TO VARIABLE, DOCUMENT TO BLOB, RECEIVE VARIABLE,
VARIABLE TO BLOB.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
This command acts differently in interpreted mode and in compiled mode.
In interpreted mode
CLEAR VARIABLE erases variable from memory. Consequently, the variable becomes
undefined; trying to read its value will generate a syntax error. Note that if you again
assign a value to the variable, 4D recreates the variable on the fly. After a variable is
cleared, Undefined returns True when applied to that variable.
In compiled mode
CLEAR VARIABLE only resets variable to its default type value (i.e., empty string for String
and Text variables, 0 for numeric variables, no elements for arrays, etc.). The variable still
exists—variables can never be undefined in compiled code.
Note: You do not need to clear process variables when a process ends; 4D clears them
automatically.
Local variables, which are variables preceded by a dollar sign ($), cannot be cleared with
CLEAR VARIABLE. They are cleared automatically when the method in which are located
completes execution.
See Also
Undefined.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
Undefined returns True if variable has not been defined, and False if variable has been
defined. A variable is defined if a value is assigned to it. A variable is undefined if it does
not have a value assigned to it, or if it has been cleared with CLEAR VARIABLE.
If the database has been compiled, the Undefined function returns False for all variables.
Examples
1. Up to version 6, a good way to test if you were running in interpreted mode or in
compiled mode was to write:
anyVar:="Hello"
CLEAR VARIABLE(anyVar)
⇒ If (Undefined(anyVar))
` You are in interpreted mode
Else
` You are in compiled mode
End if
Starting with version 6, it is more convenient to use the built-in command Compiled
application.
When developing the database, you add new modules. Instead modifying the On Startup
database method (to add the initialization of the corresponding ◊PID_...) and then
reopening the database to reinitialize everything each time you add a module, you use the
Undefined command to manage the addition of the new module, on the fly:
` M_ADD_CUSTOMERS global procedure
If (◊PID_ADD_CUSTOMERS=0)
◊PID_ADD_CUSTOMERS:=New process("P_ADD_CUSTOMERS";64*1024;
"P_ADD_CUSTOMERS")
Else
SHOW PROCESS(◊PID_ADD_CUSTOMERS)
BRING TO FRONT(◊PID_ADD_CUSTOMERS)
End if
` Note: P_ADD_CUSTOMERS, the process master method, sets
` ◊PID_ADD_CUSTOMERS to zero when it ends.
See Also
CLEAR VARIABLE.
Web Server
4th Dimension, 4D Server and 4D Client include a Web Server engine that enables you to
publish 4D databases or any type of HTML page on the Web. The principal characteristics
of the 4D Web Server engine are:
• Easy publication
You can start or stop publication of the database on the Web at any time. To do so, you
just need to choose a menu command or execute a language command.
• Load balancing with 4D Client: since any 4D Client machine can be used as a Web
server, you can set up a dynamic Web server system with a load balancer. This offers
extensive development possibilities, including, more particularly:
- the setting-up of a load-balancing system in order to optimize the performance of the
4D Web server: using a mirror of the Web site that is installed on each 4D Client Web
server, a load balancer (hardware or software) will send requests to the client machines on
the basis of their current load.
- the setting-up of a fault tolerance Web server: the 4D Web site is mirrored on two or
more 4D Client machines. If one 4D Client Web server fails, another one takes over.
- the creation of different views of the same data, for instance depending on the origin of
the requests. Within a company network, a protected 4D Client Web server can serve
Intranet requests and another 4D Client Web server, located beyond the firewall, will
serve Internet requests.
- the distribution of tasks between different 4D Client Web servers: one 4D Client Web
server can be in charge of SOAP requests, another can handle standard requests, and so
on.
See Also
Connection Security, SEND HTML FILE, SET HOME PAGE, SET HTML ROOT, SET HTML ROOT,
SET WEB DISPLAY LIMITS, SET WEB TIMEOUT, STOP WEB SERVER, Using CGIs, Using SSL
Protocol, Using the Contextual Mode, Web Server Settings.
4th Dimension, 4D Server and 4D Client include a Web server that enable you to publish
the data of your databases on the Web, transparently and dynamically.
This section describes the steps necessary for publication of 4D databases and for
connection of browsers, as well as the process of connection management.
To do this, display the password window using 4D Client (you must have suitable access
authorization to modify these parameters). When the password window is in the
foreground, choose the Edit Plug-in Access... command in the Passwords menu.
Above: only users belonging to the "Web" group are authorized to publish their 4D Client
machine as a Web server.
Under MacOS X, using TCP/IP ports reserved for Web publishing requires specific access
privileges: only the “root” user of the machine can launch an application using these
ports.
These ports are numbers 0 to 1023. Remember that, by default, a 4D database is published
on TCP port 80 in standard mode and on port 443 in SSL mode.
Once you publish a 4D database on the default TCP port without being connected as the
“root” user, an alert dialog box will be displayed:
The default port number for standard HTTP publication can be modified. However,
publishing with SSL must be done using port 443.
However, it is important to realize that this only applies to 4D Web servers published in
standard HTTP, in other words, servers that are not using the SSL protocol. SSL
publication from a 4D Server is required to take place using port 443. To be able to publish
a 4D Web server in a secure environment, you must connect as the “root” user.
Once the “root” user has been created, you must close the session (Apple menu) and then
log in using the “root” user name. You can then launch the Web server on port number
80, or a 4D Web server with a secure connection.
In the Web Server Publishing section, select the Publish Database at Startup check box,
then click OK. Once this is done, the database will be automatically published on the Web
each time you open it with 4th Dimension, 4D Server or 4D Client.
Tip: You do not need to quit 4D and reopen your database to start or stop publishing a
database on the Web. You can interrupt and restart the Web server as many times as you
want, using the Web Server menu or calling the commands START WEB SERVER and STOP
WEB SERVER.
After you have started publishing a 4D database on the Web, you can connect to it using
a Web browser. To do so:
• If your Web site has a registered name (i.e., “ www.flowersforever.com”), indicate that
name in the Open, Address, or Location area of your browser. Then press Enter to
connect.
• If your Web Site does not have a registered name, indicate the IP address of your
machine
(i.e., 123.4.567.89) in the Open, Address, or Location area of your browser. Then press
Enter.
At this time, your browser should display the home page of your Web site. If you have
published a database in keeping with standard configurations, you should obtain the
default home page of the 4th Dimension Web server. This page lets you test the
connection and the server operation.
2. You connect, but you get an HTTP 404 "File not found" error. This means that the site
home page has not be served. In this case, check that the home page actually exists at the
location defined in the database Preferences (see Web Server Settings section) or using the
SET HOME PAGE command.
4. You connect, but you do NOT obtain the Web page you were expecting! This can occur
when you have several Web servers running simultaneously on the same machine.
Examples:
• You are running only one 4D Web database on a Windows system that is already
running its own Web server.
• You are running several 4D Web databases on the same machine.
In this kind of situation, you need to change the TCP port number on which your 4D
Web database is published. To do so, refer to Web Server Settings section.
Note: If your database is protected by a password system, you may have to enter a valid
user name and password (for more information, refer to section Connection Security).
You can start the Web Server process in the following ways:
• Choose Start Web Server in the Web Server menu of 4D Server or 4th Dimension/4D
Client (in the User environment).
• Call the 4D command START WEB SERVER.
• Open a database whose Publish Database at Startup Preference is checked.
You can stop running the Web Server process in the following ways:
• Choose Stop Web Server from the User environment Web Server menu of 4D Server or
4th Dimension/4D Client (in the User environment).
• Call the 4D command STOP WEB SERVER.
• Quit the database being currently published.
The purpose of the Web Server process is only to handle Web connection attempts.
Starting the Web Server process does not mean that you open an actual Web connection,
it just means that you allow Web users to initiate Web connections. Stopping the Web
Server process does not mean that you close currently running Web connection processes
(if any), it just means that you no longer allow Web users to initiate new Web
connections.
If there are open Web connection processes when you stop the Web Server process, each
of these processes continues executing normally.
Consequently, a delay time can be necessary to complete the termination of the Web
Server process.
Each time a Web browser attempts to connect to the database, the request is handled by
the Web Server process, which performs the following steps:
• First, it creates one or several temporary local 4D processes called Web Processes to
evaluate and manage the connection with the Web browser.
Note: These temporary processes manage every HTTP request. They execute quickly and
then aborted or delayed. For the Web server to be reactive in non-contextual mode, 4D
freezes this “pool” of Web processes for 5 seconds and reuses them to execute any possible
future HTTP queries. You can customize this behavior using the command SET DATABASE
PARAMETER.
• If the request does not require that a context be created, the Web process handles the
processing of the request and sends a response (if necessary) to the browser. The
temporary process is then aborted or delayed (see above).
Note that the sixth process, which was started then aborted, handled the initialization of
the Web connection.
Note: For more information about the context management, see the paragraph Using the
Contextual Mode section.
• If during the session, the connection switches from contextual mode to non-contextual
mode, the Web connection process (with an ID) is aborted.
Conversely, if during the session, the connection switches from non-contextual mode to
contextual mode, a numbered Web connection process is created.
See Also
SEND HTML FILE, SET HTML ROOT, SET WEB DISPLAY LIMITS, SET WEB TIMEOUT, STOP
WEB SERVER, Using SSL Protocol.
The structure of this database (given at the end of this section) is simple: the database is
made of one table, an input form, an output form and a menu bar. The Home page is
customized. The database is published as a Web server.
At this point, you can browse the records at your convenience. After you click the Done
button, you go back to the Web site Home page.
You can add as many as records as you wish. When you are done, click the Cancel button
(the one with the red cross) to return to the Web site Home page.
If we eliminate the HTML home page, building a Web Server supporting database
Client/Server transactions consists of building a 4D database on Windows or Macintosh,
for one or multiple users. The following steps explain the process of creating the example
database in this way.
• Input and Output forms are added to enable you to work with records.
• Menu bar #1 is added to enable you to work with Custom menus and to support Web
connections.
• The Web server starts up in contextual mode and a default home page is defined in the
database Preferences:
Once these links have been defined, when the Web browser sends back the URL, 4D
executes the project method specified after the /4DMETHOD/ keyword. Then, after the
project method has been completed, you go back to the HTML page that triggered its
execution. Note that the project method can itself display 4D forms, other HTML pages,
and so on.
Your 4D-based Web Site can be a completely 4D-based system or a combination of 4D
forms and HTML pages. The interesting point in using HTML pages from within your 4D
database is that you benefit from both the 4D and HTML development environments.
Remember, you do not have to use HTML pages if you do not want to
The HTML home page in this example includes a button used to submit a record. There
are three types of HTML buttons: normal, submit, and reset.
• Normal - Normal buttons can be attributed an URL that refers to a 4D method using the
/4DMETHOD/ keyword. Normal buttons are used for navigation purposes.
• Submit - Submit buttons submit the form with the values entered by the user (if any) to
the Web server. They are useful for handling data entry that you prefer to perform via an
HTML page rather than a plain 4D form
• Reset - Reset buttons are not very useful within a 4D development: they clear the form
of the values entered by the user (if any) and does not send any request to the server.
To submit the HTML form on the 4D side, you need to specify the POST action 4D
method that will be executed by 4D after the form is submitted.
To do this, it must contain the line FORM ACTION="/4DMETHOD/GO_MAIN_MENU_BAR"
METHOD="POST"
• The GO_MAIN_MENU_BAR project method is the following:
SET HOME PAGE("")
In this example, this method has only one purpose: getting out of the current default
home page displayed on the Web browser and then sending the current menu bar. 4D
switches to the menu bar #1 of the database.
That is it!
In less than five minutes, you have created a 4D database that is both a locally operable
database and a Web Server that you can publish on your Intranet network or on the
Internet.
See Also
SEND HTML FILE, SET WEB DISPLAY LIMITS, SET WEB TIMEOUT, START WEB SERVER, STOP
WEB SERVER.
You can now define, in the Preferences dialog box, the access control system you want to
apply to your Web server. To do this, in the Preferences dialog box, choose the Publishing
page of the Web theme:
Notes:
- With the 4D Client Web server, keep in mind that all the sites published by the 4D
Client machines will share the same table of users. Validation of users/passwords is carried
out by the 4D Server application.
- Passwords entered by users are not encrypted in the HTTP requests (Basic mode).
The “Use Passwords” option is selected and the “Include 4D Passwords” option is not selected.
• If the On Web Authentication Database Method exists, it is executed and all its parameters
are given. You can therefore filter more precisely the connections according to the user
name, password, and/or the browser’s or Web server’s IP address.
• If the On Web Authentication Database Method doesn’t exist, the connection is
automatically refused and a message indicating that the Authentication method doesn’t
exist is sent to the browser.
Note: If the user name sent by the browser is an empty string and if the On Web
Authentication Database Method doesn’t exist, a password dialog box is sent to the
browser.
For example:
User-Agent: *
Disallow: /4D
Disallow: /%23%23
Disallow: /GIFS/
“User-Agent: *” means that all robots are affected.
“Disallow: /4D” means that robots are not allowed to access URLs beginning with /4D.
“Disallow: /%23%23” means that robots are not allowed to access URLs beginning with
/%23%23.
“Disallow: /GIFS/’ means that robots are not allowed to access the /GIFS/ folder or its
subfolders.
Another example:
User-Agent: *
Disallow: /
In this case, robots are not allowed to access the entire site.
You can designate a user, previously defined in the 4D password table, as a “Generic Web
User.” In this case, each browser that connects to the database can use the access
authorizations and restrictions associated to this generic user. You can therefore simply
control the browser’s access to the different parts of the database.
Note: Do not confuse this option, which allows you to restrict the browser’s access to
different parts of the database (tables, menus, etc.), with the Web server’s connection
control system, managed by the password system and the On Web Authentication
Database Method.
All the Web browsers that are authorized to connect to the database will benefit from the
access authorizations and restrictions associated to this generic Web user (except if the
“Include 4D Passwords” option has been selected and the user that connects does not
exist in the 4D password table, see below).
However, when the "Include 4D passwords" option is selected, two possible results can
occur:
• The user’s name and password don’t exist in 4D’s password table. In this case, if the
connection has been accepted by the On Web Authentication Database Method, the
generic Web user’s access rights will be applied to the browser.
• If the user’s name and password exist in 4D’s password table, the “Generic Web User”
parameter is ignored. The user connects with his own access rights.
This option in Preferences allows you to define the folder in which 4D will search for the
static and semi-dynamic HTML pages, pictures, etc., to send to the browsers.
Moreover, the HTML root folder defines, on the Web server hard drive, the hierarchical
level above which the files will not be accessible. This access restriction applies to URLs
sent to Web browsers as well as to 4D’s Web server commands, such as SEND HTML FILE. If
a URL is sent to the database by a browser or if a 4D command tries to access a file located
above the HTML root folder, an error is returned indicating that the file has not been
found.
By default, 4D defines a HTML Root folder named WebFolder. If it does not already exist,
the HTML root folder is physically created on disk at the moment the Web server is
launched for the first time.
If you keep the default location, the root folder is created:
• with 4th Dimension and 4D Server, at the same level as that of the database structure
file.
• with 4D Client, at the same level as that of the 4D Client .exe file (under Windows) or
the software package (under MacOS).
You can modify the default HTML root folder name and location in the Preferences
dialog box (Web theme, Publishing page):
In the “Default HTML Root” entry area, enter the new access path of the folder that you
wish to define.
The access path entered in this dialog box is relative: it is established from the folder
containing the structure of the database (4th Dimension or 4D Server) or the folder
containing the 4D Client application or software package (4D Client).
For multi-platform compatibility of your databases, the 4D Web server uses particular
writing conventions to describe access paths. The syntax rules are as follows:
• folders are separated by a slash (“/”)
• the access path must not end with a slash (“/”)
• to “go up” one level in the folder hierarchy, enter “..” (two periods) before the folder
name
• the access path must not start with a slash (“/”) (except if you want the HTML root
folder to be the database or 4D Client folder, see below).
For example, if you want the HTML root folder to be the “Web” subfolder in the
“4DDatabase” folder, enter 4DDatabase/Web
The special 4DACTION (non-contextual mode) and 4DMETHOD (contextual mode) URLs
allow you to trigger the execution of any project method of a4D database published on
the Web. For example, the request http://www.server.com/4DACTION/Erase_All causes the
execution of the Erase_All project method, if it exists.
This mechanism therefore presents a security risk for the database, in particular if an
Internet user intentionally (or unintentionally) triggers a method not intended for
execution via the Web. You can avoid this risk in three ways:
• restrict access to project methods using the 4D password system. Drawbacks: this system
requires the use of 4D passwords and forbids any type of method execution (including
using HTML tags).
• filter the methods called via theURLS using the On Web Authentication Database
Method. Drawbacks: if the database includes a great number of methods, this system may
by difficult to manage.
This option is used to individually designate each project method that can be called using
the special URLs, 4DACTION and 4DMETHOD. When it is not checked, the project
method concerned cannot be executed using an HTTP request containing a special URL.
Conversely, it can be executed using other types of calls (4D tags, other methods, etc.).
This option is unchecked by default for databases created with 4th Dimension 2003.
Methods that can be executed using the 4DACTION or 4DMETHOD Web URLs must be
specifically indicated.
Conversely, for reasons of compatibility, this option is checked for existing databases
(created with a version of 4D earlier than 2003): by default, all the project methods are
accessible via the special 4D URLs.
See Also
On Web Authentication Database Method, On Web Connection Database Method, Using SSL
Protocol.
The On Web Authentication Database Method is in charge of managing Web server engine
access. It is called by 4th Dimension, 4D Server or 4D Client when a Web browser request
requires the execution of a 4D method on the server (method called using a 4DACTION or
4DCGI URL, a 4DSCRIPT tag, etc.).
This method receives six Text parameters: $1, $2, $3, $4, $5, and $6, and returns one
Boolean parameter, $0. The description of these parameters is as follows:
Parameters Type Description
$1 Text URL
$2 Text HTTP header + HTTP body (up to 32 kb limit)
$3 Text IP address of the Web client (browser)
$4 Text IP address of the server
$5 Text User name
$6 Text Password
C_TEXT($1;$2;$3;$4;$5;$6)
C_BOOLEAN($0)
Note: All the On Web Authentication database method’s parameters will not eventually
be filled in. The information received by the database method depends on the options
that you have previously selected in the Preferences dialog box (please refer to the section
Connection Security).
• URL
The first parameter ($1) is the URL entered by the user in the location area of his or her
Web browser, from which the host address has been removed.
• Server IP address
The $4 parameter receives the IP address used to call the Web server. 4D since version 6.5
allows for multi-homing, which allows you to exploit machines with more than one IP
address. For more information, please refer to the section Web Server Settings.
The On Web Connection Database Method is only executed if the connection has been
accepted by On Web Authentication.
Notes
• Do not call any interface elements in the On Web Authentication Database Method
(ALERT, DIALOG, etc.), otherwise it will be interrupted and the connection will be refused.
The same is true if an error occurs while the database method is being executed.
• It is possible to forbid execution by 4DACTION or 4DMETHOD for each project method
using the “Available through 4DACTION” option in the Method properties dialog. For
more information about this point, refer to the Connection Security section.
The On Web Authentication Database Method is therefore called in the following cases:
• when 4D receives a URL beginning with 4DACTION/
• when 4D receives a URL beginning with 4DMETHOD/
• when 4D receives a URL beginning with 4DCGI/
• when 4D receives a URL requesting a static page that does not exist
• when 4D processes a 4DSCRIPT tag in a semi-dynamic page
• when 4D processes a 4DLOOP tag based on a method in a semi-dynamic page.
Note that the On Web Connection Database Method is NOT called when the server receives
a URL requesting a valid static page.
$0:=False
$user:=$5
$password:=$6
$BrowserIP:=$3
$ServerIP:=$4
If (Not($4Duser))
`It is not a user defined 4D, look in the table of Web users
QUERY([WebUsers];[WebUsers]User=$user;*)
QUERY([WebUsers]; & [WebUsers]Password=$password)
$0:=(Records in selection([WebUsers]) = 1)
Else
$0:=True
End if
End if
`Is this an intranet connection?
If (Substring($BrowserIP;1;7) # "192.100.")
$0:=False
End if
C_INTEGER($i)
C_BOOLEAN($0)
C_TEXT($1)
$0:=False
For($i;1;Length($1))
If (Ascii(Substring($1;$i;1)) = Ascii("@"))
$0:=True
End if
End for
See Also
Connection Security, Database Methods, On Web Connection Database Method, URLs and
Form Actions.
The On Web Connection database method can be called in three different cases:
• the Web server receives a request beginning with the 4DCGI URL.
• the Web server receives an invalid request.
• it is also called by 4th Dimension or 4D Server each time a Web browser initiates a
connection to the database in contextual mode, or each time the Web server receives a
request requiring the creation of a context (this case is not handled by 4D Client, which
does not support the contextual mode).
For more information, refer to the paragraph “On Web Connection Database Method
calls”.
The request should have been previously accepted by the On Web Authentication Database
Method (if it exists) and the database should be published as a Web server.
The On Web Connection database method receives six text parameters that are passed by
4D. The contents of these parameters are as follows:
Parameters Type Description
$1 Text URL
$2 Text HTTP header + HTTP body (up to 32 kb limit)
$3 Text IP address of the Web client (browser)
$4 Text IP address of the server
$5 Text User name
$6 Text Password
C_TEXT($1;$2;$3;$4;$5;$6)
Note that you are free to use this parameter at your convenience. 4D simply ignores the
value passed beyond the host part of the URL.
For example, you can establish a convention where the value "/Customers/Add" means “go
directly to add a new record in the [Customers] table.” By supplying the Web users of your
database with a list of possible values and/or default bookmarks, you can provide shortcuts
to the different parts of your application. This way, Web users can quickly access resources
of your Web site without going through the whole navigation path each time they make
a new connection to your database.
Particular case: In non-contextual mode, the $1 value does NOT start with the "/"
character in cases where the requested URL corresponds neither to an existing page nor to
a 4D special URL (such as "/4DCGI"). For example, if the requested URL is
"http://123.4.567.89/Clients/Add" and if the "Add" page does not exist in the "Clients"
folder, the On Web Authentication Database Method and then the On Web Connection
Database Method are called with the "Clients/Add" value in $1.
With Microsoft Internet Explorer 6 running on Windows, you may receive a header
similar to this:
GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Host: 123.45.67.89
Accept: image/gif, image/x-xbitmap, image/pjpeg, */*
Accept-Language: us
If your application deals with this information, it is up to you to parse the header and the
body.
The On Web Connection Database Method can be used as the entry point for the 4D Web
server, either using the special 4DCGI URL, or using customized command URLs. It also
plays a role as the entry point in contextual mode (with 4th Dimension and 4D Server).
The On Web connection database method is therefore called in the following cases:
• when connecting a browser to a 4D Web server operating in contextual mode. The
database method is called with the /<action>... URL.
• when 4D receives the /4DMETHOD URL. The Web server switches to contextual mode
and the database method is called with the /4DMETHOD/MethodName URL in $1.
• when 4D receives the /4DCGI URL. The database method is called with the
/4DCGI/<action> URL in $1.
• when a Web page is called with a URL of type <path>/<file> is not found. The database
method is called with the URL (*).
• when a Web page is called with a URL of type <file>/ and no home page has been
defined by default. The database method is called with the URL (*).
(*) In this particular cases, the URL received in $1 does NOT start with the "/" character.
To know whether the On Web Connection Database Method was called from a contextual
or from a non-contextual connection, you can use the Web Context function, that
returns True if it is called from contextual mode, and False otherwise.
Consequently, we suggest that you structure the On Web Connection database method in
the following manner:
`On Web connection database method
C_TEXT($1;$2;$3;$4;$5;$6)
If (Web Context) `If in contextual mode
WithContext ($1;$2;$3;$4;$5;$6)
`The WithContext contains everything that was in the
`On Web connection database method in 4D 6.0.x
Else
NoContext ($1;$2;$3;$4;$5;$6)
`The NoContext method executes the non-contextual
`processing of requests (generally short)
End if
The database has two tables: [Customers] and [Tables]. The On Startup database method
shown here initializes interprocess arrays used later by the On Web Connection database
method.
` On Startup Database Method
` Table List
ARRAY STRING(31;◊asTables;Count tables)
For ($vlTable;1;Size of array(◊asTables))
◊asTables{$vlTable}:=Table name($vlTable)
End for
The main job of the On Web Connection database method is to decipher the extra data
passed in the URL after the host part of the address and to act accordingly. The method is
as follows:
` On Web Connection Database Method
C_TEXT($1;$2;$3;$4;$5;$6)
C_TEXT($vtURL)
In other words, the HTML page ACME_IS.HTM is the Client Local Home Page for the 4D-
based information system of the organization. If a user clicks on the Add New Products
link, the Web browser will connect to the host having the URL
http://123.4.567.89/Products/Add. Provided that the IP address of the database computer
is 123.4.567.89, the On Web Connection Database Method receives the extra URL data
"/Products/Add" in $1, and therefore proceeds to add records in the [Products] table.
Finally, users can drag and drop links from that page onto the desktop to create Internet
Shortcut icons, such as the Add New Customers icon shown here. Simply double-clicking
these icons will bring them directly into any part of your 4D Web database.
See Also
Database Methods, On Web Authentication Database Method, URLs and Form Actions, Using
the Contextual Mode.
This section describes the means made available by the 4D Web server for exchanging
information via the Web, i.e. for dynamically sending and receiving values. The
following points will be dealt with:
• Sending dynamic values stored in 4D variables
• Receiving dynamic values via Web forms
• Using the COMPILER_WEB project method
• Managing server-side image mapping
• Embedding JavaScript
Note: the sending and receiving of dynamic values can be carried out automatically in
contextual mode via converted 4D forms. For more information on this point, refer to
the section Using the contextual mode.
References to 4D variables can be inserted in your HTML pages. You can bind these
references with any type of HTML object. When the Web pages are sent to the browser,
4D will replace these references with the current values of the variables. The pages
received are therefore a combination of static elements and values coming from 4D. This
type of page is called semi-dynamic.
Notes:
• You work with process variables.
• As HTML is a word processing oriented language, you will usually work with Text
variables. However, you can also use BLOBs variables (which avoid the 32 000 characters
limitation of text type variables). You just need to generate the BLOB in Text without
length mode.
First, an HTML object can have its value initialized using the value of a 4D variable.
Second, after a Web form is submitted back, the value of an HTML object can be returned
into a 4D variable. To do so, within the HTML source of the form, you create an HTML
object whose name is the same as the name of the 4D process variable you want to bind.
That point is studied further in the paragraph “Receiving dynamic values” in this
document.
Note: In non-contextual mode, it is not possible to make a reference to 4D picture
variables.
The <!--4DVAR --> tag also allows the insertion of 4D expressions in the pages sent (fields,
array elements, etc.). The operation of this tag with this type of data is identical to that
with variables. For more information, refer to the section 4D HTML Tags.
In fact, the syntax <!--4DVAR VarName--> allows you to insert 4D data anywhere in the
HTML page. For example, if you write:
<P>Welcome to <!--4DVAR vtSiteName-->!</P>
The value of the 4D variable vtSiteName will be inserted in the HTML page.
Here is an example:
` The following piece of 4D code assigns "4D4D" to the process variable vs4D
vs4D:="4D4D"
` Then it send the HTML page "AnyPage.HTM"
SEND HTML FILE("AnyPage.HTM")
In the HTML source code shown, note the hidden input object named vs4D. The value of
this object is set to the text value "<!--4DVAR vs4D-->". Since the project method sending
the HTML file has previously defined the 4D process variable vs4D, 4D replaces the value
of the HTML object and sets it to "4D4D", the value of the 4D variable.
The embedded JavaScript function Is4DWebServer tests the value of the vs4D HTML
object. Here is the trick: if the HTML page is served by 4D, the object’s value is changed to
"4D4D". However, if the HTML page is served by another application (i.e., 4D WebSTAR
on Macintosh), the object stays with its value as defined in the page, "[vs4D]". Bingo! By
using JavaScript to test the value of that object, from within the page on the Web
Browser side, you can detect whether or not the page is being served by 4D.
This first example shows how you can build “intelligent” HTML pages that provide
additional features when being served by 4D, while staying compatible with other Web
servers.
The binding in the direction 4D toward Web Browser works with any encapsulation
method (SEND HTML FILE, SEND HTML BLOB, as well as, in contextual mode, static text or
text or BLOB variable in a 4D form).
When you send an HTML page using SEND HTML FILE or SEND HTML BLOB, you can also
bind 4D variables with HTML objects in the “Web Browser toward 4D” direction. The
binding works both ways: once the HTML form is submitted, 4D can copy back the values
of the HTML objects into the 4D process variables. With a view to database compilation,
these variables must be declared in the COMPILER_WEB method (see paragraph below).
It is also possible to retrieve values from the Web forms sent to 4D without prior
knowledge of the fields that they contain, using the GET WEB FORM VARIABLES
command. For more information, refer to the description of this command.
Let’s examine the 4D method WWW Welcome that sends this HTML page using the SEND
HTML FILE command. This method is called by the On Web Connection Database Method.
` WWW Welcome Project Method
` WWW Welcome -> Boolean
` WWW Welcome -> Yes = Can start a session
C_BOOLEAN($0)
$0:=False
Repeat
` Do not forget to reset the values of the submit buttons!
vsbLogOn:=""
vsbRegister:=""
vsbInformation:=""
` Send the Web page
SEND HTML FILE("Welcome.HTM")
` Test the values of the submit buttons in order to detect which one was clicked
Case of
This the way to distinguish which Submit button was clicked when several Submit
buttons exist on the Web page. Note that 4D buttons in a 4D form are numeric variables.
However, with HTML, all objects are text objects.
If you bind a 4D variable with a SELECT object, you also bind a text variable. In 4D, to
test which element of a drop-down list was chosen, you test the numeric value of the 4D
array. With HTML, this is the value of the selected item that is returned in the 4D variable
bound to the HTML object.
No matter which object you bind with a 4D variable, the returned value is of type Text, so
you bind String or Text 4D process variables.
An interesting point of this example is that after you have obtained information about
the Browser, you can store these values in a 4D table, again combining Web and database
capabilities. This is what the (unlisted) WWW POST EVENT project method does. It does
not “post an event”; it saves the web session information into the tables shown here:
Using the binding features shown in this example, combined with all the information
you can give to or gather from users via HTML dialogs or 4D forms, you can add some
very interesting administrative capabilities to your database Web site.
When the 4D Web server receives a posted form, it automatically calls the project method
called COMPILER_WEB (if it exists). This method must contain all the typing and/or
variable initialization directives, which are the variables whose names are the same as the
field names in the form. It will be used by the compiler when compiling the database.
The COMPILER_WEB method is common to all the Web forms. By default, the
COMPILER_WEB method does not exist. You must explicitly create it.
Note: You can also use the GET WEB FORM VARIABLES command, which gets the value for
all the variables included in a submitted HTML page.
Web Services: The COMPILER_WEB project method is called, if it exists, for each SOAP
request accepted. You must use this method to declare all the 4D variables associated with
incoming SOAP arguments, for all methods published as Web Services. In fact, the use of
process variables in Web Services methods requires that they be declared before the
method is called. For more information on this point, refer to the description of the SOAP
DECLARATION command.
As seen in the section Using the Contextual Mode, when a 4D form is used as a Web page,
4D provides Server-side Image Mapping by means of invisible-like buttons that overlap a
static picture.
If you send an HTML document using SEND HTML FILE or SEND HTML BLOB, you can
bind 4D variables with Image Map HTML objects (INPUT TYPE="IMAGE") to retrieve
information. For example, you can create an Image Map HTML object named bImageMap
(you can actually use any name). Each time you click on the image on the browser side, a
submit with the click position is sent back to the 4D Web Server. To retrieve the
coordinates of the click (expressed relative to the top left corner of the image), you just
need to read the value the 4D process variables bImageMap_X and bImageMap_Y (of type
Longint) which contain the horizontal and vertical coordinates of the click. These
variables should be declared in the COMPILER_WEB project method (see previous
paragraph).
• Then, in the POST action 4D method or in the current method, after the POST action
method issued a SEND HMTL FILE("") call, you retrieve the coordinates of the click in the
bImageMap_X and bImageMap_Y variables :
If (($bImageMap_X#-1)&($bImageMap_Y#-1))
` Do something accordingly to the coordinates
End if
JavaScript Encapsulation
4D supports JavaScript source code embedded into HTML documents, and also JavaScript
.js files embedded in HTML documents (for example <SCRIPT SRC="...").
In contextual mode, if you encapsulate HTML in a 4D form, you do not have control over
the HEAD section or the FORM declaration. The scope of the scripts is therefore different.
For example, you cannot access the HTML form by its name. However, compare the
Is4DWebServer JavaScript function of the previous example with this one:
Both functions do the same thing, but the second example uses the forms property of the
HTML document object to access the object through the element forms[0]. As a result, it
operates even if you do not know the name that 4D may or may have not given to the
translated HTML page (form).
Note: 4D supports Java applets transport.
See Also
4D HTML Tags, SEND HTML BLOB, SEND HTML FILE, URLs and Form Actions.
The 4D Web Server offers different URLs and HTML form actions that allow you to
implement various actions in your database, in both contextual and non-contextual
modes.
Note: In addition, the 4D Web Server accepts four particular URLs: /4DSTATS,
/4DHTMLSTATS, /4DCACHECLEAR and /4DWEBTEST, to allow you to obtain information
about the functioning of your 4D Web site. These URLs are described in the section
Information about the Web Site.
URL 4DACTION/
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Syntax: 4DACTION/MyMethod{/Param}
Mode: Non-contextual. When called from contextual mode, aborts the context process
and switches to non-contextual mode.
Usage: URL or Form action.
This URL allows you to link an HTML object (text, button...) to a 4D project method in
contextual mode. The link will be /4DMETHOD/Method_Name/Param where
Method_Name is the name of the 4D project method to be executed when the user clicks
on the link and Param an optional Text parameter to pass to the method in $1 (see
paragraph “The Text Parameters Passed to 4D Methods Called via URLs” below).
When 4D receives a /4DACTION/MyMethod/Param request, the On Web Authentication
Database Method (if it exists) is called. If it returns True, the MyMethod method is
executed.
4DACTION/ can be associated with a URL in a static Web page. The syntax of the URL
must be in the following form: <A HREF="/4DACTION/MyMeth/Param">Do Something</A>
The MyMeth project method should generally return a "response" (sending of an HTML
page using SEND HTML FILE or SENT HTML BLOB, etc.). Be sure to make the processing as
short as possible in order not to block the browser.
Note: A method called by 4DACTION must not call interface elements (DIALOG, ALERT...).
Warning: For a 4D method to be able to be executed using the 4DACTION/ URL, it must
have the “Available through 4DACTION” attribute (unchecked by default), defined in the
Method properties. For more information on this point, refer to the Connection Security
section.
In this case, when the Web server receives a posted form, it calls the COMPILER_WEB
project method (if it exists, see below), then the On Web Authentication Database Method
(if it exists). If it returns True, the MethodName method is executed. 4D analyzes the
HTML fields present in the form, retrieves their values and automatically fills the 4D
variables with their contents. The field in the form and the 4D variable must have the
same name.
Note: For more information, refer to the section Binding 4D objects with HTML objects.
For each field in the form, 4D sets the value of the field to the value of the variable with
the same name. For the form options (for example, check boxes), 4D sets the associated
variable to 1 if it is selected, otherwise 0.
Example
In a 4D Web database started and used in “non-contextual” mode, we hope that the
browsers can search records by using a static HTML page. This page is called “search.htm”.
The database contains other static pages that allow you to, for example, display the search
result (“results.htm”). The POST type has been associated to the page, as well as the
/4DACTION/SEARCH action.
Here is the page as it appears in an HTML editor, in our case Adobe® PageMill™:
During data entry, type “ABCD” in the data entry area, check the option and validate it
by clicking the Search button.
In the example, VNAME contains the string “ABCD”, vEXACT is equal to 1 and OK is
equal to 1 (because the button’s name is OK).
4D calls the On Web Authentication Database Method (if it exists), then the PROCESSFORM
project method is called, which is as follows:
If (OK=1)
If (vEXACT=0) `If the option has not been selected
vNAME:=VNAME+"@"
End if
QUERY([Jockeys];[Jockeys]Name=vNAME)
vLIST:=Char(1) `Return the list in HTML
FIRST RECORD([Jockeys])
While (Not(End selection([Jockeys])))
vLIST:=vLIST+[Jockeys]Name+” “+[Jockeys]Tel+”<BR>”
NEXT RECORD([Jockeys])
End while
SEND HTML FILE(“results.htm”) `Send the list to the results.htm form
`which contains a reference to the variable vLIST (that is <!--4DVAR vLIST––>)
...
End if
URL 4DMETHOD/
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Syntax: 4DMETHOD/MyMethod{/Param}
Mode: Contextual. When called from non-contextual mode, switches to contextual
mode.
Usage: URL or Form action.
This URL allows you to link an HTML object (text, button...) to a 4D project method in
contextual mode. The link will be /4DMETHOD/Method_Name/Param where
Method_Name is the name of the 4D project method to be executed when the HTML
object is clicked and Param an optional Text parameter to pass to the method in $1 (see
paragraph “The Text Parameters Passed to 4D Methods Called via URLs” below). The
linked item triggers the execution of the 4D project method through their URLs. The
project method can itself display 4D forms, other HTML pages, and so on.
When 4D receives a /4DMETHOD request, the On Web Authentication Database Method (if
it exists) is called. If it returns True, the On Web Connection Database Method (if it exists)
is called, then the Method_Name method is executed with the /Param string as parameter
(in $1).
URL 4DCGI/<action>
_______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Syntax: 4DCGI/<action>
Mode: Both.
Usage: URL.
When the 4D Web server receives the /4DCGI/<action> URL, the On Web Authentication
Database Method (if it exists) is called. If it returns True, the Web server calls the On Web
Connection Database Method by sending the URL “as is ” to $1.
The 4DCGI/ URL does not correspond to any file. Its role is to call 4D using the On Web
Connection Database Method. The “<action>” parameter can contain any type of
information.
This URL allows you to perform any type of action. You just need to test the value of $1
in the On Web Connection Database Method or in one of its submethods and have 4D
perform the appropriate action. For example, you can build completely custom static
HTML pages to add, search, or sort records or to generate GIF images on-the-fly. Examples
of how to use this URL are in the descriptions of the PICTURE TO GIF and SEND HTTP
REDIRECT commands.
When issuing an action, a “response” must be returned, by using commands that send
data (SEND HTML FILE, SEND HTML BLOB, etc.).
Warning: Please be sure to execute the shortest possible actions so as not to hold up the
browser.
4th Dimension sends text parameters to any 4D method called via special URLs
(4DMETHOD/, 4DACTION/ and 4DCGI/), in both contextual and non-contextual modes.
Regarding these text parameters:
• Although you do not use these parameters, you must explicitly declare them with the
command C_TEXT, otherwise runtime errors will occur while using the Web to access a
database that runs in compiled mode.
• The $1 parameter returns the extra data placed at the end of the URL, and can be used
as a placeholder for passing values from the HTML environment to the 4D environment.
This runtime error is related to the missing declaration of the text $1 parameter in the 4D
method that is called when you click on the HTML link referring to that method. As the
context of the execution is the current HTML page, the error refers to the “line 0” of the
method that has actually sent the page to the Web browser.
After these changes have been made, the compiled runtime errors no longer occur.
See Also
Binding 4D objects with HTML objects, GET WEB FORM VARIABLES, Using the Contextual
Mode, Your First Time with the Web Server.
The 4D Web server provides you with different HTML tags specific to 4D, which allow
you to insert references to 4D variables or expressions, or different types of processing, in
static HTML pages sent by the Web server, for example using the SENT HTML FILE and
SEND HTML BLOB commands. These pages are called semi-dynamic pages.
These tags are inserted as HTML comments (<!--LaBalise LeContenu--> in HTML code). Most
HTML editors offer editing facilities to insert comments.
Compatibility Note: In version 6.0.x of 4D, the notation to use for inserting 4D variables
in static pages was square brackets [VarName]. In a converted database, to be able to use
the standard HTML syntax (<!--4DVAR VarName-->), make sure that the option “Use
4DVAR Comments instead of Brackets” in the Preferences dialog box is checked (see
section Web Server Settings).
Parsing of the contents of semi-dynamic pages sent by 4D takes place when SEND HTML
FILE (.htm, .html, .shtm, .shtml) or SEND HTML BLOB (text/html type BLOB) commands
are called, as well as when sending pages called using URLs.
However, in non-contextual mode, for reasons of optimization, pages that are suffixed
with “.htm” and “.html” are NOT parsed. In order to "force" the parsing of HTML pages
in this case, you must add the suffix “.shtm” or “.shtml” (for example,
http://www.server.com/dir/page.shtm).
An example of the use of this type of page is given in the description of the WEB CACHE
STATISTICS command.
In order to be processed by 4D, an HTML comment should have the following format <!--
4D...-->. Please note that some HTML editors add automatically other information within
the comment, this can lead to some misinterpretation.
However, other HTML comments such as <!--Beginning of list--> are possible.
If a comment <!--4D... does not end by -->, the following message “<!--4D... : --> expected”
will be inserted and the analysis will stop at this level (the page will be sent to indicate the
error).
4DVAR
Syntax: <!--4DVAR VarName-->
The tag <!--4DVAR VarName--> allows you to insert a reference to the 4D variable or
expression VarName anywhere in a HTML page. For example, if you write:
<P>Welcome to <!--4DVAR vtSiteName-->!</P>
The value of the 4D variable vtSiteName will be inserted in the HTML page.
You can insert a 4D text variable in HTML code, provided its first character is ASCII code 1
(i.e., vtHTML:=Char(1)+"...HTML code..."). You can also use the tag 4DHTMLVAR.
You can also insert 4D expressions (not only variables) in 4D HTML comments with the
4DVAR tag. You can insert directly a field content (for example <!--4DVAR
[tableName]fieldName-->) or an item array content (for example <!--4DVAR arr{1}-->).
The expression conversion follows the same rules as the variable ones. Moreover, the
expression must comply with 4D syntax rules.
Although an expression can contain direct calls to 4D functions, this is not recommended
for localization issues. For example, <!--4DVAR Current date-->, although correctly
interpreted with a 4D in English will not be understood by an French version. The same
applies to real numbers (the decimal separator can be different according to the
language). In both cases, we strongly advise you to assign a variable through
programming.
4DHTMLVAR
Syntax: <!--4DHTMLVAR VarName-->
For example, here are the insertion results of the 4D text variable myvar with the available
tags:
myvar Value Tags Web Page Insertion
myvar:="<B>" <!--4DVAR myvar--> <B>
myvar:=Char(1)+"<B>" <!--4DVAR myvar--> <B>
myvar:="<B>" <!--4DHTMLVAR myvar--> <B>
The 4DSCRIPT tag allows you to execute 4D methods when sending static HTML pages.
The presence of the <!--4DSCRIPT/MyMethod/MyParam--> tag in a static page as an HTML
comment forces the execution of the MyMethod method with the MyParam parameter as
a string in $1. When loading the home page, 4D calls the On Web Authentication Database
Method (if it exists). If it returns True, 4D executes the method.
The method returns text in $0. If the string starts with the ASCII code character 1, it is
considered as HTML (the same principle is true for the variables).
Note: The execution of a method with 4DSCRIPT is not dependent on the value of the
“Available through 4DACTION” attribute defined in the Method properties.
The analysis of the contents of the page is done when either SEND HTML FILE (.htm,
.html, .shtm, .shtml) or SEND HTML BLOB (blob of type text/html) is called.
Remember that in non-contextual mode, the analysis is also done when a URL points to a
file that has either the “.shtm” or “.shtml” extension (for example
http://www.server.com/dir/page.shtm).
Note: In contextual mode, the method is executed in the context.
For example, let’s say that you insert the following comment “Today is <!--
4DSCRIPT/MYMETH/MYPARAM-->” into a static page. When loading the page, 4D calls the
On Web Authentication Database Method (if it exists), calls the MYMETH method and
passes the string “/MYPARAM” as the parameter $1.
The method returns text in $0 (for example “12/31/03”), the expression “Today is
<!––4DSCRIPT/MYMETH/MYPARAM––>” therefore becomes “Today is 12/31/03”.
The MYMETH method is as follows:
C_TEXT($0) `This parameter must always be declared
C_TEXT($1) `This parameter must always be declared
$0:=String(Current date)
Warning: You must always declare the $0 and $1 parameters in the called method.
Note: A method called by 4DSCRIPT must not call interface elements (DIALOG, ALERT...).
4DINCLUDE
Syntax: <!--4DINCLUDE Path-->
This comment allows inclusion in an HTML page, the body of another HTML page
(indicated by the path parameter). An HTML page body is included within the <BODY>
and </BODY> tags (the tags themselves are not included).
The <!--4DINCLUDE --> comment is very useful for tests (<!--4DIF-->) or loops (<!--4DLOOP-
->). It is very convenient to include tags according to a criteria or randomly.
When including, regardless of the mode and file name extension, 4D analyses the called
page and then inserts the content (modified or not) in the page originating the
4DINCLUDE call.
An included page with the <!--4DINCLUDE --> comment is loaded in the Web server cache
the same way as pages called via an URL or sent with the command SEND HTML FILE.
Put in path the path leading to the document to include. The path is relative to the
document being analyzed. Use the slash character (/) as a folder separator and the two
dots (..) to go up one level (HTML syntax).
The number of <!--4DINCLUDE path--> within a page is unlimited. However, the <!--
4DINCLUDE path--> calls can be made only at one level. This means that, for example, you
cannot insert <!--4DINCLUDE mydoc3.html--> in the mydoc2.html body page, which is
called by <!--4DINCLUDE mydoc2--> inserted in mydoc1.html.
Furthermore, 4D verifies that inclusions are not recursive.
In case of error, the inserted text is "<!--4DINCLUDE path--> :The document cannot be
opened".
Note: In contextual mode, if a page is inserted in a form via a tag {mypage.html} inserted
in a static text area, the 4DINCLUDE comments (if any) will be ignored.
Used with the <!--4DELSE--> (optional) and <!--4DENDIF--> comments, the <!--4DIF
expression--> comment offers the possibility to execute HTML code conditionally.
The expression parameter can contain any valid 4D expression returning a boolean value.
It must be indicated within parenthesis and comply to the 4D syntax rules.
The <!--4DIF expression--> ... <!--4DENDIF--> blocks can be nested in several levels. Like in
4D, to each <!--4DIF expression--> should match a <!--4DENDIF-->.
In case of interpretation error, the text “<!--4DIF expression-->: A boolean expression was
expected” is inserted instead of the content located between <!--4DIF --> and <!--4DENDIF--
>.
Likewise, if there is not as much <!--4DENDIF--> as <!--4DIF -->, the text “<!--4DIF
expression-->: 4DENDIF expected” is inserted instead of the content located between <!--
4DIF --> and <!--4DENDIF-->.
Example
This example of code inserted in a static HTML page displays a different label according
the vname#"" expression result:
<BODY>
...
<!--4DIF (vname#"")-->
Names starting with <!--4DVAR vname-->.
<!--4DELSE-->
No name has been found.
<!--4DENDIF-->
...
</BODY>
This comment allows repetition of a portion of HTML code as long as the condition is
fulfilled. The portion is delimited by <!--4DLOOP--> and <!--4DENDLOOP-->.
The <!--4DLOOP condition--> ... <!--4DENDLOOP--> blocks can be nested. Like in 4D, to
each <!--4DLOOP condition--> should match a <!--4DENDLOOP-->.
• <!--4DLOOP array-->
This syntax makes a loop for each item array. The array current item is increased when
each HTML code portion is repeated.
Note: This syntax cannot be used with two dimension arrays. In this case, it is better to
combine a method with nested loops.
• <!--4DLOOP method-->
This syntax makes a loop as long as the method returns True. The method takes a Long
Integer parameter type. First it is called with the value 0 to allow an initialization stage (if
necessary), it is then called with the values 1,then 2, then 3 and so on, as long as it
returns True.
Note: The execution of a method with 4DLOOP is not dependent on the value of the
“Available through 4DACTION” attribute defined in the Method properties.
Warning: C_BOOLEAN($0) and C_LONGINT($1) MUST be declared within the method for
compilation purposes.
Example
The following HTML code example:
<!--4DLOOP my_method-->
<!--4DVAR var--> <BR>
<!--4DENDLOOP-->
See Also
Binding 4D objects with HTML objects, URLs and Form Actions, Using the Contextual Mode.
You can configure the operation of the 4D Web server using the parameters defined in
the Web theme of the database Preferences. This section describes the parameters of the
Publishing, Configuration and 4D WebSTAR pages of this theme.
Publishing Page
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
By default, 4D publishes a Web database on the regular Web TCP Port, which is port 80. If
that port is already used by another Web service, you need to change the TCP Port used
by 4D for this database. Modifying the TCP port allows you to start the 4D Web server
under MacOS X without being the root user of the machine (see Web server configuration
and connection management section).
Note: If you specify 0, 4D will use the default TCP port number 80.
From a Web browser, you need to include that non-default TCP port number into the
address you enter for connecting to the Web database. The address must have a suffix
consisting of a colon followed by the port number. For example, if you are using the TCP
port number 8080, you will specify “123.4.567.89:8080”.
WARNING: If you use TCP port numbers other than the default 80, be careful not to use
port numbers that are defaults for other services that you might want to use
simultaneously. For example, if you also plan to use the FTP protocol on your Web server
machine, do not use the TCP port 20 and 21, which are the default ports for that protocol
(unless you know what you are doing). Port 443 is the TCP port used for SSL connections.
For more information about default TCP port numbers and protocols, buy any book about
the TCP/IP protocol and look for a table of RFC 1700 standard assigned numbers. Ports
numbers below 256 are reserved for well known services and ports numbers from 256 to
1024 are reserved for specific services originated on the UNIX platforms. For maximum
security, specify a port number beyond these intervals, for example in the 2000's or
3000's.
You can define the IP address on which the Web server must receive HTTP requests.
This feature is for 4D Web Servers located on machines with multiple TCP/IP addresses. It
is, for example, frequently the case of most Internet host providers.
Implementing such a MultiHoming system requires specific configurations on the Web
server machine :
• On MacOS
To configure a MultiHoming system on MacOS:
1. You must use Open Transport version 1.3 or later. This new feature is only available in
this version of Open Transport.
2. Open the TCP/IP Control Panel.
Please check the Apple Open Transport documentation for more information.
• On Windows
To configure a MultiHoming system on Windows NT or Windows 2000:
1. Select the following sequences of commands:
• Windows NT: Start menu > Settings > Control Panel > Network Control panel >
Protocols tab > TCP/IP Protocol > Properties button > Advanced.
• Windows 2000: Start menu > Settings > Network and Dial-up Connections > Local
Area Connection > Properties button > Internet Protocol (TCP/IP) > Properties button >
Advanced.
The "Advanced TCP/IP Settings" dialog box appears.
• Windows XP: Start menu > Control Panel > Network and Internet Connections >
Network connections > Local Area Connection (Properties) > Internet Protocol (TCP/IP) >
Properties button > Advanced... button.
The "Advanced TCP/IP Settings" dialog is displayed.
2. Click the Add.... button in the "IP Addresses" area, and add additional IP addresses.
You can define up to 5 different IP addresses. You may need to consult your systems
administrator to do so. For more information, please refer to Windows documentation.
“Passwords” area
Configuration of Web site access protection using passwords. This option is described in
the Connection Security section,
Starting Mode
Allows you to define the mode in which the Web server will be started. This option is
described in the Using the Contextual Mode section.
You can designate a default home page for all the browsers that connect to the database,
no matter which mode (contextual or non-contextual) has been defined for the Web
sessions. This page can be static or semi-dynamic.
By default, when the Web server is launched for the first time, 4D creates a home page
named “index.html” and puts it in the HTML root folder. If you do not modify this
configuration, any browser connecting to the Web server will obtain the following page:
The 4D Web Server has a cache that allows you to load static pages, GIF images, JPEG
images (<128 kb) and style sheets (.css files) in memory, as they are requested.
Using the cache allows you to significantly increase the Web server’s performance when
sending static pages.
The cache is shared between all the Web processes. You can set the size of the cache in
the Preferences. By default, the cache of the static pages is not enabled (its size is equal to
0). To activate it, simply enter a value (expressed in Kb) in the Pages Cache Size area.
The value you set depends on the number and size of your Web site’s static pages, as well
as the resources that the host machines has at its disposal.
Note: While using your Web database, you can check the performance of the cache by
using the routine WEB CACHE STATISTICS. If, for example, you notice that the cache’s rate
of use is close to 100%, you may want to consider increasing the size that has been
allocated to it.
The /4DSTATS and /4DHTMLSTATS URLs allow you to also obtain information about the
cache’s state. Please refer to section Information about the Web Site.
This option indicates the strictly high limit of Maximum Concurrent Web Processes of
any type (contextual, non-contextual or belonging to the“pool of processes”) that can be
simultaneously open on the server. This parameter allows prevention of 4D Server
saturation as the result of massive number of requests or an excessive demand of contexts
creation.
By default, this value is 32000. You can set the number anywhere between 10 and 32000.
When the maximum number of concurrent Web processes (minus one) is reached, 4D no
longer creates new processes and sends the following message “Server unavailable” (status
HTTP 503 – Service Unavailable) for each new request.
By default, the 4D Web server converts the extended ASCII characters in the dynamic
and static Web pages according to HTML standards before sending them. They are then
interpreted by the browsers.
You can set the Web server so that the extended ASCII characters are sent “as is”, without
converting them into HTML entities. This option has shown a speed increase on most
foreign operating systems (especially the Japanese system).
Character Sets
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The Standard Set drop-down list allows you to define the set of characters to be used by
the 4D Web server.
You can also define a customized set of characters by modifying the ASCII character
conversion tables (Web filters) for both input and output of data.
To do this, check the User Defined radio button. This parameter is equivalent to selecting
the “x-user-defined” set of characters.
The buttons associated with Edit Input Filter and Edit Output Filter are now enabled. The
input filter interprets the characters sent by the browser to 4D Web server. The output
filter interprets the characters sent by 4D Web server to the browser.
Click the button that corresponds to the filter that you want to modify.
Input filter interprets characters sent by the browser to the 4D Web server and Output
filter interprets characters sent by the 4D Web server to the browser.
The following dialog box appears:
In the scrollable area, look for and click on the Mac character that you want to filter.
In the “ASCII Code” entry area, enter the character’s new ASCII code.
Repeat this operation for all the characters you want to filter.
You can click on the Save... button in order to save the filter. You can then load it
subsequently using the Load... button.
This option allows you to define the notation to use when inserting 4D variables on static
pages.
• When the option is checked (default value), the syntax you need to use is the standard
HTML notation <!--4DVAR MYVAR--> (A space character must be inserted between 4DVAR
and the variable name).
• When the option is not checked, the syntax you need to use is the notation with square
brackets ([MYVAR]) — which is a proprietary solution used in former versions of the 4D
Web server.
When this option is checked (default value), in contextual mode the Web server places
the current context number in the basic URL of the documents sent to the browsers.
With the previous system (option not checked), the 4D Web server sends the context
number for each element of a page to the browser, which slows down processing.
This option can be unchecked for reasons of compatibility. Keep in mind that after
modifying it, you must restart the database in order for the new operation to take effect.
When this option is checked, in contextual mode a part of the data entry controls can be
done on the browsers by using automatic Javascripts.
On the browser, the data entry controls and the data types (fields or variables) to which
they can be applied are as follows:
• minimum value (for numeric values)
• maximum value (for numeric values)
• mandatory value (for numeric and alphanumeric values)
Generated Javascripts, which are small in size, display alert dialog boxes without
preventing the user from accepting a data entry (it is still 4D’s responsibility).
Actually, if a data entry area contains an incorrect value, an alert message is displayed on
the browser when the user clicks on a button (OK, Cancel, etc.):
Once the alert dialog box is validated, if the user clicks a second time on the button, the
button’s action is then taken into account.
The complete data entry control is done on the Web server, in User and Custom Menus
mode.
4D WebSTAR page
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
For security reasons, the Allow 4D WebSTAR to connect via 4D Connect option is not
checked by default. Depending on your Web configuration, 4D S.A. recommends the
following settings:
• If your 4D Web server is not connected to a 4D WebSTAR server using the 4D Connect
plug-in, leave this option unchecked.
• If your 4D Web server is connected to a 4D WebSTAR server using the 4D Connect
plug-in, you should check this option for it to work.
In this configuration, it is recommended to run the 4D Web server behind a firewall and
to filter, using this firewall, requests addressed to 4D.
See Also
Connection Security, SET DATABASE PARAMETER, SET HOME PAGE, Using the Contextual
Mode.
4D allows you to obtain information about the functioning of your 4D Web site.
• You can control the site by using particular URLs (/4DSTATS, /4DHTMLSTATS,
/4DCACHECLEAR and /4DWEBTEST).
• You can generate a log of all the requests.
• You can obtain information regarding the Web Server in the Watch page of the
Runtime Explorer window.
/4DSTATS
The /4DSTATS URL returns the following information in pure text form:
• the number of “hits” (low-level connections),
• the number of contexts created,
• the number of contexts that could not be created,
• the number of password errors,
• the number of pages stored in the cache,
• the percentage of cache used,
• the list of pages and JPEG or GIF files stored in the cache of the static pages (*).
(*) For more information about the cache of static pages and pictures, please refer to
section Web Server Settings.
This information can allow you to check the functioning of your server and eventually
adapt the corresponding parameters.
Note: The command WEB CACHE STATISTICS allows you to also obtain information about
how the cache is being used for static pages.
/4DHTMLSTATS
The /4DHTMLSTATS URL returns, also in pure text form, the same information as the
/4DSTATS URL. The difference is that in the last field (contained in the cache), only the
list of HTML pages — without the .GIF and .JPEG files — present in the cache is returned.
/4DWEBTEST
The /4DWEBTEST URL is designed to check the Web Server status. When this URL is
called, 4D returns a text file only with the following HTTP fields filled:
• Date: current date at the RFC 822 format
For example: “Date: Wed, 26 Jan 2000 13:12:50 GMT”
• Server: 4D WebStar_D/internal version number
For example: “4D WebStar_D/7.0”
• User-Agent: name and version @ IP client address
For example: “Mozilla/4.08 (Macintosh; I; PPC, Nav) @ 192.193.00.00”
4D allows you to obtain a log of requests. The log is presented in the form of a text file
named “weblog.txt” automatically placed at the same level as the structure file of the
database. This file is in CLF (Common Log File) format or NCSA format, recognized by
most Web site analysis tools.
Each field is separated by a space and each line ends by the CR/LF sequence (character 13,
character 10).
• host: IP address of the client (ex. 192.100.100.10)
• rfc931: information not generated by 4D, it’s always - (a minus sign)
• user: user name as it is authenticated, or else it is - (a minus sign). If the user name
contains spaces, they will be replaced by _ (an underscore).
• DD: day, MMM: a 3-letter abbreviation for the month name (Jan, Feb,...), YYYY: year,
HH: hour, MM: minutes, SS: seconds
• The date and time are local to the server.
• request: request sent by the client (ex. GET /index.htm HTTP/1.0)
• state: response given by the server.
• length: size of the data returned (except the HTTP header) or 0.
Note: For performance reasons, the operations are saved in a memory buffer in packets of
1Kb before being written to disk. The operations are also written to disk if no request has
been sent every 5 seconds.
Warning: The log file can be imported into a spreadsheet or directly into 4D. However,
you must imperatively stop the Web server before importing it.
By default, the log file of requests is not generated. To request the generation of a log file
of all the Web requests you must check the Save Request in File (logweb.txt) option on
the Configuration page of the Web theme of the database Preferences.
The Watch page (“Information” heading) in the Runtime Explorer displays three pieces of
information relative to the Web Server:
• Web Cache Usage: indicates the number of pages present in the Web cache as well as its
use percentage. This information is only available if the Web server is active and if the
cache size is greater than 0.
• Web Server Elapsed Time: indicates the duration of use (in hours:minutes:seconds
format) of the Web server. This information is only available if the Web server is active.
See Also
WEB CACHE STATISTICS, Web Server Settings.
The 4D Web server can operate in two different modes: non-contextual mode (standard
mode) and contextual mode. This section describes these two modes and details the
particularities of the contextual mode.
Warning: The contextual mode can only be used with 4th Dimension and 4D Server. The
4D Client Web server does not support this mode.
Note: The section Your First Time with the Web Server gives a complete example of the
publication of a database in contextual mode.
Starting with version 2003 of 4th Dimension, the 4D Web server uses the non-contextual
mode by default (disconnected mode). In this mode, the operation of the 4D Web server
is comparable to that of standard Web servers: when an HTTP request is received from a
browser (URL, posted form, etc.), the server processes the request, then returns a response
when necessary (sending a Web page, for example). No specific connection is maintained
subsequently between the server and the browser.
In non-contextual mode, the Web server can send static or semi-dynamic pages. Semi-
dynamic pages allow you to access data in the database or to carry out any type of
processing using special 4D tags that are evaluated at the time the page is sent. Semi-
dynamic pages allow you to build, manage and send Web pages whose content originates
in whole or in part from processing carried out by 4D. Non-contextual mode generally
meets most Web site development needs.
Choice of mode
Choosing the 4D Web server operating mode is carried out as follows:
• on startup of the server, using the Starting Mode option of the database Preferences,
• during Web server use, according to the URLs sent or the commands executed.
The URLs are automatically maintained by 4D during the whole Web session in contextual
mode. Each time an HTTP request is received via TCP/IP, 4D extracts the context ID from
the URL, and thereby can redirect the request to the right Web Connection process.
Context IDs:
• Enable 4D to maintain both a Web and Database session over each Web connection.
• Transparently handle multiple concurrent Web connections.
• Prevent future undesirable connections when using bookmarks, because a different
context ID is generated at each connection.
Usually, a Web browser includes navigation controls, such as the Back and Forward
buttons, History windows, and so on. These controls are useful when you are browsing
documents, news, bulletin boards, etc. They are less appealing when you perform a
database transaction.
This synchronization is also essential for the Web Connection process. You need to
correctly get out of, for example, an ADD RECORD ([...]) to pursue the execution of your
4D code.
The synchronization is selective. If the current Web page displayed on the browser side is
a 4D form (ADD RECORD, DISPLAY SELECTION, DIALOG, etc.), the synchronization will
eventuallly occur.
If the current Web page is an HTML page accessed by link from another Web page (sent
using the command SEND HTML FILE), then you can navigate freely through the pages.
From a Design viewpoint, the Web Connection process should be seen as a 4D process
whose domain of execution is 4th Dimension or 4D Server, but whose user interface is
remotely echoed on the connected Web browser.
With this in mind, always take into account this duality of the Web Connection process
when designing Web database applications in contextual mode. For example:
• During data entry of any kind, the main menu bar is that of the browser, not that of
4D. Within a form, do not rely on the 4D menu bar; it is on the Web server machine, not
on the Web browser machine,
• When you design forms to be used on the Web browser, remember that the 4D form set
of features is limited to that of HTML (but sometimes with some 4D additions). Do not
rely on the whole 4D forms feature set (i.e., object types and form events). For more
information on this point, refer to the paragraph “Automatic HTML conversion” below.
• In terms of interprocess communication, CALL PROCESS, when applied to a Web
Connection process, has no effects because its current active form is displayed on the
Web browser. On the other hand, a Web Connection process can issue a CALL PROCESS
toward another 4D process.
In addition, interprocess communication can be indifferently performed in both
directions using the GET PROCESS VARIABLE and SET PROCESS VARIABLE commands, which
do not require a process to have a user interface.
The scope of the Web Server Connections Timeout setting is the database session. All
contextual Web Connection processes are subjected to that value; they are immediately
affected if that setting is changed. The default value is 5 minutes.
Note: The command SET WEB TIMEOUT allows you to specify a different Timeout for each
Web process.
You can increase or decrease this timeout at your convenience. For example, you can
increase the timeout if your application allows Web users to surf to other Web sites via
HTML links in the pages served by your database. By increasing the timeout, you enable
users to navigate longer within the other Web sites without closing their connections to
your databases.
Tip: Unlike Web Server process, Web Connection processes can be aborted using the
Abort command (available in the Runtime Explorer when the Process page is displayed).
This paragraph specifies the elements, objects and mechanisms handled automatically
during database conversion into HTML by 4th Dimension in contextual mode.
Menu Bars
• Each menu bar is translated into one HTML page. Each menu title appears as text only
and menu commands associated with 4D methods appear as links to these 4D methods.
Menu commands that are only associated with automatic actions appear as text only.
• Clicking a menu item on the Web Browser side starts the execution of the associated 4D
method on the Web Connection process side.
Note: When the “Start a New Process” property is assigned to a menu command, the
associated method is executed by the 4D Web server in a new Web connection process
using the 4DMETHOD URL. In this case, the method of the menu must have the
Available through 4DACTION attribute (unchecked by default for new databases). For
more information, refer to the Connection Security section.
• The picture associated with a menu bar is placed below the menus on the browser.
Forms
• Objects are translated from top to bottom and from left to right, and they have the
same position on the browser as they do in the 4D form. Note, however, that HTML is a
word processing oriented application; horizontal objects positions may be different and
wrap-around may occur.
• Multi-page forms are supported transparently, including a page zero and inherited
forms.
• Automatic actions, when appropriate, are supported transparently.
• Form events (On Load, On Unload, On Clicked and On Timer) are supported. Other events
are not supported.
• The Header, Detail, Break and Footer tags are taken into account during calls to DISPLAY
SELECTION and MODIFY SELECTION. The Header of the form appears once at the
beginning of the HTML page, the detail area is repeated as many times as necessary, and
variables (such as buttons) placed in the Footer area appear at the end of the HTML page,
just under the automatic selection page navigation links.
Note: The 4D Web server uses CSS1 to produce HTML pages with a very similar
appearance to the 4D forms themselves. CSS1 (Cascading Style Sheet 1) specifications have
been defined by the World Wide Web Consortium (W3C). These style sheets set some
characteristics related to the document appearance: font, size, color, title, body, spacing,
etc. .CSS documents are sent with the MIME type “text/css”. In both contextual or non-
contextual mode, these documents are not processed by 4D.
For compatibility reasons, you can modify the Web conversion mode to use for the forms
using the SET DATABASE PARAMETER command (selector 8, Web Conversion Mode).
Fields Objects
When a 4D form is translated to an HTML page, field objects are translated as follows:
4D Field Type HTML Object HTML Markup
Alphanumeric Text field (*) <INPUT Type="text" ...>
Text Text field (*) <TEXTAREA ...> (**)
<INPUT Type="text" ...> (***)
Real Text field (*) <INPUT Type="text" ...>
Integer Text field (*) <INPUT Type="text" ...>
Long Integer Text field (*) <INPUT Type="text" ...>
Date Text field (*) <INPUT Type="text" ...>
Time Text field (*) <INPUT Type="text" ...>
Boolean Radio or Check box (*) <INPUT Type="radio" ...>
<INPUT Type="checkbox" ...>
Picture Image (always non-enterable) <IMG SRC="..." ...>
Subtable No HTML support None
BLOB No HTML support None
(*) or text only if non-enterable
(**) If the text value is composed of several lines
(***) If the text value is composed of only one line or is empty
Note: Enterable variables behave like fields of the same type.
The following objects are not supported by HTML and therefore are ignored during the
translation:
Hierarchical Pop-up menu, Hierarchical List, Subform, Radio Picture, Thermometer, Ruler, Dial,
Picture Pop-up Menu, Picture Button, 3D Check Box, 3D Radio Button.
Notes
1. Non-horizontal lines are not supported in HTML; they are therefore ignored.
If the array elements are empty strings, 4D displays 1, 2, 3... on the browser.
6. Plug-in areas are publishable on the Web, by first being converted into HTML, Image or
Image Map. This last solution allows you to manage mouse clicks inside the plug-in area
(for example, the integrated plug-in 4D Chart is published in an Image Map and the
4D_Pack _AP External clock area is published as an Image). The way in which a plug-in
area, which is on a 4D form, is published on the Web depends on the plug-in editor’s
specifications.
Commands that are not affected by execution from within a Web Connection process
A command such as CREATE RECORD works within the executing process; in this case, it
creates a record within the Web Connection process. The same applies to commands such
as Screen width, which returns the width of the screen on the Web Server machine (the
machine on which the process is executing).
Commands that include extra built-in capabilities for transparent Web support
Command Name Comments
ADD RECORD Automatic translation of the form, multi-page forms supported
ALERT Automatic translation of the dialog box
CONFIRM Automatic translation of the dialog box
DIALOG Automatic translation of the form, multi-page forms supported
DISPLAY SELECTION Automatic translation of the form
Built-in Web paging mechanism
UserSet mechanism is not supported
MODIFY RECORD Automatic translation of the form, multi-page forms supported
MODIFY SELECTION Automatic translation of the form
Built-in Web paging mechanism
UserSet mechanism is not supported
QUERY Standard Query dialog box supported
QUERY BY EXAMPLE Automatic translation of the form, multi-page forms supported
Request Automatic translation of the dialog box
REDRAW Update of the form displayed on the browser
For example, you can invoke the printing of a selection from a Web Browser. However,
the printing will be performed on the Web Server machine.
In addition, when a user interface component is involved, it appears on the Web Server
machine, i.e., Open document("") vs Open Document("This document"). You should avoid
such calls, because the Web Browser will wait for a reply until the dialog box is closed on
the Web Server machine. On the other hand, it is perfectly OK to call these routines
when no dialog boxes are involved.
Embedding HTML
___________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
You can customize the content of 4D forms converted into HTML by embedding HTML
code (or Javascript) into the form. The resulting form, on the Web browser side, is a
combination of HTML and 4D objects.
In contextual mode, to insure the maintenance of the database context and subcontext
IDs, 4D automatically remaps file references and URLs. For example, 4D remaps all IMG
and HREF references to local files.
If you insert your own HTML code into a 4D form using a text variable, you must follow
the 4D remapping syntax.
Example
The following 4D method returns the remapped reference for the pathname received as
parameter:
Note: For details about the method HTML Pathname, see the examples of the command
Mac to ISO.
Then, when inserting HTML code into a 4D form using a text variable, you can write:
vtHTML:=Char(1)+"<P><IMG SRC="+Char(34)
+WWW Local GIF URL("F:\ThisImage.HTM"+Char(34)
+" ALIGN=MIDDLE></P>"+Char(13)
This will insert the GIF document in the 4D form at the location of the 4D variable
vtHTML.
Important: You only need to write this kind of code to insert custom HTML code into a
4D form. If you just send an HTML page using SEND HTML FILE or if you use a command
such as ADD RECORD, remember that 4D transparently translates and remaps the HTML.
See Also
Connection Security, On Web Authentication Database Method, On Web Connection
Database Method, SET DATABASE PARAMETER.
The 4D Web server can communicate in secured mode through the SSL protocol (Secured
Socket Layer).
At the network level, the SSL protocol is inserted between the TCP/IP layer (low level) and
the HTTP high level protocol. SSL has been designed mainly to work with HTTP.
Network configuration using SSL:
Note: The SSL protocol can also be used to secure standard 4D Server client/server
connections. For more information, refer to the section Encrypting Client/Server
Connections in the 4D Server Reference manual.
The SSL protocol is designed to authenticate the sender and receiver and to guarantee the
confidentiality and integrity of the exchanged information:
• Authentication: The sender and receiver identities are confirmed.
• Confidentiality: The sent data is encrypted so that no third person can understand the
message.
• Integrity: The received data has not been changed, by accident or malevolently.
4. Once you get your certificate, create a text file named “cert.pem” and paste the
contents of the certificate into it.
You can receive a certificate in different ways (usually by E-mail or HTML form). The 4D
Web Server accepts all platform-related text formats for certificates (Mac OS, PC, Linux...).
However, the certificate must be in PKCS format.
Files required to implement SSL with 4D Web server (4th Dimension and 4D Server):
Note: 4DSLI.DLL is also necessary to use the encryption commands ENCRYPT BLOB and
DECRYPT BLOB.
The installation of these elements makes it possible to use SSL for connections to the 4D
Web server. However, in order for SSL connections to be accepted by the 4D Web server,
you must “activate” the SSL. This parameter is accessible on the Publishing page of the
Web theme in the database Preferences:
The TCP port dedicated to SSL data exchange is 443. As a result, you cannot install more
than one Web server using SSL on a machine. The TCP port defined in this page of the
Preferences is used for standard mode Web server connections.
Note: The other Preferences defined for the 4D Web Server management (password,
timeout, cache size, etc.) are applied, regardless of whether or not the server is operating
in SSL mode.
The encryption algorithm used for the connection is then decided by the browser and the
Web server. The server offers several symetric encryption algorithms (RC2, RC4, DES...).
The most powerful common algorithm is used.
Warning: The level of encryption allowed depends on current laws in the country of use.
The level of encryption offered by 4D Web Server depends on the version of the
encryption system library used. By default, 4D provides an "Export" version of the library
whereby symetric algorithms are limited to 40 bits.
See Also
DECRYPT BLOB, ENCRYPT BLOB, GENERATE CERTIFICATE REQUEST, GENERATE
ENCRYPTION KEYPAIR, Secured Web connection, Web Server Settings.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
WML
4D Web Server supports WML (Wireless Markup Language) technology. This feature allows
a mobile phone or a PDA’s owner to read and enter data in a 4D database.
Note: The WML language associated to the WAP (Wireless Application Protocol) is
developed by several companies. The WAP technology offers a set of network
communication tools so that mobile phones and PDA users can visualize text published
on Web pages. The WML technology is open and free of charge. For more information
on WML, please refer to the Phone.com Web site: http://www.phone.com/.
The data can be entered or read through WML pages using 4DVAR or 4DSCRIPT tags.
XML
The 4D Web server supports .xml,.xls and .dtd documents which are sent with the
following MIME type: “text/xml” and “text/xsl”.
See Also
Binding 4D objects with HTML objects.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The 4D Web Server supports CGIs (Common Gateway Interface). CGIs for Web servers are
similar to plug-ins for 4D methods. They are called by the Web server to execute a task
and return an answer, i.e. a full Web page or some HTML code inserted in the page sent
by the server. CGIs are frequently used to display visitors counters, generate guest books,
receive a form-mail, etc.
Note: Originally, CGI was a standard for interfacing external applications with HTTP
server. The "CGI" word is now used for the external applications themselves.
A CGI can be an application, a PERL script or a DLL interfacing with a Web server. Many
CGIs are now available and most of them are freeware.
The CGI should be located at the root of the folder named cgi-bin. This folder should be
placed at the Web server root or in a subfolder. A server can have several cgi-bin folders.
This folder can contain other files than executable application, but only the latest can be
called from a Web client.
• On Windows
Under Windows, the following CGIs can be used:
- Executables (.EXE) using the “console” and the environment variables. The source code
is usually cross-platform (Windows and Unix). The CGI names are usually written as
follows: nnn.exe or nph-nnn.exe. For more information on this kind of CGI, please refer to
the http://hoohoo.ncsa.uiuc.edu/cgi/ Internet site.
- DLL ISAPI, i.e. extensions for IIS (Internet Information Server). The CGI names are
written as follows: nnn.dll or nph-nnn.dll. The DLLs are downloaded once the Web server
has been stopped for performance purposes.
For more information on this type of CGI, please refer to the
http://www.microsoft.com/iis/ Internet site.
• On Mac OS
Under MacOS, the CGI can have the following types:
- Applications, 4D WebStar and MacHTTP extensions. Their names are written as follows:
nnnn.cgi and nnnn.acgi (they are always applications).
For more information on this type of CGI, please refer to the http://dev.starnine.com/
Internet site.
- PERL scripts. These CGI require MacPERL. Their names are written as follows: nnnn.pl,
nph-nnnn.pl, nnnn.cgi or nph-nnnn.cgi (they are text files).
For more information on this type of CGI, please refer to the http://www.macperl.com/
Internet site.
A CGI is always executed without context, regardless of the calling mode. Note however,
that in contextual mode, we strongly recommend that you not use a CGI sending back
HTML code, as it might desynchronize the context.
This functionality makes form processing easier (it is not necessary to parse strings such as
a=1&b=2&...), however the CGI is made 4D-specific.
Regarding 4D WebStar CGIs, 4D allows splitting responses with size greater than 32 Kb.
4D WebSTAR® is one of the most popular Web servers on MacOS. 4D gives direct access
to 4D WebSTAR from 4D and 4D can directly answer a 4D WebSTAR request.
4D WebSTAR does not require any specific component, in fact 4D acts like a CGI for 4D
WebSTAR.
To activate the 4D WebSTAR feature, copy 4th Dimension or an alias in the folder
containing the pages to publish or in the 4D WebSTAR cgibin folder. The name of the 4D
application must end with “.acgi”, for example 4D.acgi. The 4D Web server should be
activated prior to each request and should communicate on a different port than the one
used by 4D WebSTAR.
The 4D WebSTAR server works as follow: when an URL or an action such as “/cgi-
bin/4d.acgi$/4daction/proc” is received by the 4D WebSTAR server, it returns an event
specific to 4D.acgi through an Apple Event. 4D processes the Apple Event as a HTTP
request. In this example, the HTTP request would be “/4daction/proc”.
The 4D WebSTAR CGI mode is not compatible with the contextual mode.
Note: Other interaction possibilities between 4D and 4D WebSTAR have been developed,
in particular the 4D WebSTAR plug-ins called 4D Connect and 4D Link. For more
information about these plug-ins, please refer to the 4D WebSTAR documentation.
4th Dimension is provided with two new extensions, 4DISAPI.DLL and NPH-CGI4D.EXE.
These extensions have been designed to allow a HTTP server to send requests to a 4D
HTTP server. For example, a non secured 4D Web server can be interrogated via another
HTTP server, running in secured mode.
Warning: These two extensions are available under Windows only.
• The 4DISAPI extension complies to the specifications defined by ISAPI (Internet Services
Application Programming Interface). The ISAPI technology has been developed originally by
Microsoft® for the IIS server but since it has been made compatible with various HTTP
servers such as Netscape®, Apache® or Sambar®.
• The NPH-CGI4D.EXE extension complies to the CGI specifications (Common Gateway
Interface) and can be used with all the CGI compatible servers.
• The extensions identify the GET, HEAD and POST methods which manage the various
status sent back by 4D (200 OK, 302 Moved Temporarily, 404 Not Found...).
Each installed extension file is provided with a configuration file (.INI file). The .INI file
should bear the same name as the extension (for example 4DISAPI.INI). The extension and
configuration files should be located in the same folder.
An HTTP server can be defined to target several other HTTP servers. In this case, copy in
the HTTP server [Scripts] folder as many extensions as target servers. You just need to
rename them (for example, 4DISAPI2.DLL, 4DISAPI3.DLL, etc.). Make sure that a
configuration file is associated to each extension and that its name is correct
(4DISAPI2.INI, 4DISAPI3.INI, etc.).
A .INI file contains one section: [Forward] which authorizes the following commands:
• TargetServer =
IP name or address of the Web server to target (for example, myserver.net or
192.193.194.195). The line can be left blank for targeting a server by its address if the
name resolution is unavailable.
The “localhost” name is identified to the 127.0.0.1 address.
The address 127.0.0.1 is used by default.
• TargetPort =
Port used by the target server (by example, 81). The port number 8080 is used by default.
• Timeout =
Maximum timeout for the server answer (in seconds). The default value is set to 30
seconds.
• Allowed =
Allowed URL list, separated by a comma. For example: /pages, /img to give access only to
the URL starting with /pages and /img. To give access to the full site, enter a slash
character / (default setting).
• Forbidden =
Forbidden URL list, separated by a comma. For example: /4DMETHOD, /pages2 to forbid
the access to the URL starting with /4DMETHOD and /pages2. To give unlimited access,
do not enter anything in the list (default setting).
If a forbidden URL is called, the extension directly returns the error “HTTP/1.0 403
Forbidden”.
• 4D call (4D will receive only the URL part located after the extension name):
http://server-address/cgi-bin/4disapi.dll/[Path]
http://server-address/cgi-bin/nph-cgi4d.exe/[Path]
• Checking of the extension (echo of the request):
http://server-address/cgi-bin/4disapi.dll/~~echo
http://server-address/cgi-bin/nph-cgi4d.exe/~~echo
• Information about the extension (technical support):
http://server-address/cgi-bin/4disapi.dll/~~info
http://server-address/cgi-bin/nph-cgi4d.exe/~~info
The following information is returned:
name and version of the extension, for example "Script name: 4disapi.dll (6.7.0b1.2)"
name and version of the server calling the extension, for example "Server software:
4D_WebStar_D/6.7"
version of the HTTP protocol, for example "Server protocol: HTTP/1.0"
version of the CGI protocol, for example "Gateway interface: CGI/1.1"
• Checking of the target server (is the server available?) :
http://server-address/cgi-bin/4disapi.dll/~~target
http://server-address/cgi-bin/nph-cgi4d.exe/~~target
The answer is either:
"Good: target server reached.": the target server answered (whatever the contents of the
answer).
or "Bad: target server not reached.": the target server cannot be reached or did not answer.
In this case, the fail can be caused by:
- the configuration file is missing;
- the target address or port is incorrect;
- the target server is out;
- the target server did receive the request but is unable to answer.
Description
The START WEB SERVER command starts the Web server of the 4th Dimension application
on which it has been executed (4th Dimension, 4D Server or 4D Client). The database is
therefore published on your Intranet network or on the Internet.
If the Web Server is successfully started, OK is set to 1, otherwise OK is set to 0 (zero). For
example,
if the TCP/IP network protocol is not properly configured, OK is set to 0.
See Also
STOP WEB SERVER.
Description
The STOP WEB SERVER command stops the Web server of the 4th Dimension application
on which it has been executed (4th Dimension, 4D Server or 4D Client). If the Web
server has been started, all Web connections are stopped, and all Web processes
terminated.
If the Web server has not been started, the command does nothing.
See Also
START WEB SERVER.
Description
The SET WEB TIMEOUT command sets the timeout for the Web Connection processes in
contextual mode. The default timeout is 5 minutes.
You reduce or increase this delay by passing, in the timeout parameter, the new timeout
expressed in seconds.
The command takes effect immediately, and its scope is the working session.
• If SET WEB TIMEOUT is called from within a Web process, the value of timeout is applied
to that process only.
• If SET WEB TIMEOUT is not called from a Web process, all the Web Connection processes
are affected.
See Also
Using the Contextual Mode, Web Server Settings.
Description
The SET HTML ROOT command is used to modify the default directory or folder where 4D
looks for the HTML file you pass as a parameter to the command SEND HTML FILE.
Warning: The SET HTML ROOT command works in contextual mode only. To set a default
HTML root folder in non-contextual mode, use the Default HTML Root area in the
Preferences dialog box. For performance reasons, it is usually more judicious to set the
default HTML root folder in the Preferences, whatever the execution mode of the Web
server.
The pathname you specify must be an HTML pathname, where the directory or folder
names are separated by a slash (“/”) character, no matter what the platform. For more
information about HTML pathnames, please refer to the Language Reference part of any
HTML manual you can find in bookstores.
If you specify an invalid pathname, an OS File manager error is generated. You can
intercept the error with an ON ERR CALL method. If you display an alert or a message
from within the error method, it will appear on the browser side.
Note: The SET HTML ROOT command takes into account the default HTML root folder
defined in the Preferences of the database. For more information on this folder, please
refer to section Connection Security.
See Also
ON ERR CALL.
Error Handling
If you specify an invalid pathname, an OS File manager error is generated. You can
intercept the error with an ON ERR CALL method.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET WEB DISPLAY LIMITS command modifies the way 4th Dimension displays a
selection of records on the Web browser side when you call DISPLAY SELECTION or
MODIFY SELECTION. This command only operates in contextual mode.
When you display a selection of records using 4th Dimension, the program does not load
all the records of the selection; it only loads (from the disk) the records that are visible in
the window at one time. In doing so, although you create a selection of thousands of
records, displaying them is quite fast. Then, if you scroll or resize the window, 4D loads
the records appropriately.
By default, 4th Dimension displays the first 20 records of the selection and includes, at
the end of each HTML page, 20 links to the first 20 pages of the selection. This means
that, by default, you can browse the first 400 records of the selection by clicking on the
page links located at the end of each selection page. Note that this paging system is
transparent to your coding; everything happens within the call to DISPLAY SELECTION or
MODIFY SELECTION.
SET WEB DISPLAY LIMITS enables you to change these settings. In the numberRecords
parameter, you indicate the maximum number of records you want to display per
selection page. In numberPages, you indicate the maximum number of selection page
links you want at the end of each selection page.
For example, if you have a selection of 10,000 records and want to browse all of them in
one display selection, you can pass numberRecords=100 and numberPages=100. However,
remember that the data is going over the network or Internet; with the Internet, you
must take the speed factor into account when changing the display selection settings.
SET WEB DISPLAY LIMITS only affects subsequent calls to DISPLAY SELECTION or MODIFY
SELECTION, and its scope is local to the current process.
Example
In the following example, a DISPLAY SELECTION or a MODIFY SELECTION is issued for a
[Zip Codes] table. By default, 4D displays the records on the Web browser side as shown
here:
Then the selection on the Web browser side ends up looking like this:
You can now browse the first 5,000 records of the selection.
See Also
DISPLAY SELECTION, MODIFY SELECTION, Using the Contextual Mode.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET HOME PAGE command allows you to modify the custom home page for the
current Web process.
The defined page is linked to the Web process, you can therefore define the different
home pages depending, for example, on the user that is connected. This page can either
be static or semi-dynamic.
You pass the name of the HTML home page or the page’s HTML access path to the
homePage parameter.
To stop sending homePage as home page for the current Web process, execute SET HOME
PAGE with an empty string ("") passed in homePage.
Note: 4D also allows you to define a default home page in the Preferences dialog box. In
this case, the page applies to all the Web connections whatever the Web server’s startup
mode (contextual or non-contextual).
See Also
Web Server Settings.
Description
The SEND HTML FILE command sends, to the Web browser, the Web page stored in the
HTML document whose pathname you pass in htmlFile.
By default, 4th Dimension looks for the HTML document within the HTML root folder,
defined in the application Preferences.
This command will only acccept path names in HTML syntax as a parameter: names of
directories or folders must be separated with a slash ("/") regardless of the platform.
If you specify an invalid HTML pathname, 4D sends the message “The requested HTML
page could not be found” to the Web browser.
The alternate syntax SEND HTML FILE(""), in which you pass an empty string in hmtlFile,
allows you, in contextual mode, to terminate the call to SEND HTML FILE, which initiated
the HTML mode. This is illustrated in the following diagram:
2. The initial Web page sent to the browser may have HTML links to other Web pages or
can itself refer to 4D Methods that call SEND HTML FILE to send other Web pages. These
other pages may have links or refer to 4D Methods for accessing other pages, and so on.
While navigating through the Web pages, you can also use browser’s navigation controls,
such as the Back button.
3. Any of the Web pages can include references to a 4D method that issues a SEND HTML
FILE("") call. This call terminates the SEND HTML FILE call that initiated the whole thing,
and you go back, pursuing the execution 4D Method that originally started the free Web
navigation.
Once SEND HTML FILE is executed, the OK system variable is updated: if the file to be sent
exists and if the timeout has not run out, OK is equal to 1. Otherwise, it is equal to 0.
Note: If you call SEND HTML FILE from within a process that is not a Web process, the
command does nothing and returns no error; the call is simply ignored.
The references to 4D variables and 4DSCRIPTS type tags in the page are always parsed,
whatever the mode.
Examples
(1) The HTML root folder of the database is the WebDocs folder. It contains the following
elements:
..\WebDocs\HTM\MyPage.HTM
Sending the Web page "MyPage.HTM" must be carried out in the following manner :
On the 4D side, the project method htm_Help_Done terminates the SEND HTML FILE
initiated by the bHelp button:
` htm_Help_Done Project Method
⇒ SEND HTML FILE ("")
The call to SEND HTML FILE in the object Method of the bHelp button is the last line of
the method. When the method is completed, you return to data entry.
See Also
Binding 4D objects with HTML objects, SEND HTML BLOB, Your First Time with the Web
Server.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SEND HTML BLOB command allows you to send blob to the browser.
The type of data contained in the BLOB is indicated by type. This parameter can be one of
the following types:
• type = Empty String (""): In this case, you don’t need to supply any more information in
the BLOB. The browser will try to interpret the contents of the BLOB.
• type = File extension (example: ".HTM", ".GIF", ".JPEG", etc.): In this case, you specify
the MIME type of the data contained in the BLOB by indicating its extension. The BLOB
will then be interpreted according to its extension. However, the extension must be a
standard one so that the browser can correctly interpret it.
• type = Mime/Type (example: “text/html”, “image/tiff”, etc.): In this case, you directly
specify the MIME type of data contained in the BLOB. This solution offers you more
freedom. Besides the standard types, you can pass a custom MIME type to send
proprietary documents via Intranet. To do so, you only need to configure the browsers so
that they recognize the type sent and so that they can open the appropriate application.
The value you pass to type is, in this case, “application/x-[TypeName]”. In the client
workstations’s browser, you reference this type and associate it to the “Launch the
application” action. The SEND HTML BLOB command allows you to therefore send all
types of documents, the Intranet clients automatically open the associated application.
Note: If the BLOB is of type “text/html” (.htm, .html, .shtm, .shtml), it is translated and
analyzed as an HTML file. In this case, when used in contextual mode, SEND HTML BLOB
works exactly as SEND HTML FILE. That is, a 4D method that issues a SEND HTML BLOB("")
call should be called in one of the HTML pages, in order to terminate the original SEND
HTML BLOB call. For more information, refer to the SEND HTML FILE command
description.
Note: For more information, go to http://www.iana.org and look for “Protocol Numbers
and Assignment Services” topics.
Example
Refer to the example of the routine PICTURE TO GIF.
See Also
SEND HTML FILE.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SEND HTML TEXT command directly sends HTML formatted text data.
The htmlText parameter contains the data to be sent. As 4D does not check the parameter
content, make sure that the HTML encoding is correct. The text variable should be
expressed using the ISO Latin-1 character map.
Note: This command is similar to the SEND HTML BLOB command using a BLOB with a
“html/txt” type.
The noContext parameter indicates to the 4D Web server that you want to switch from
the contextual mode to the non-contextual mode when executing the command.
In this case, pass True in the noContext parameter if you want to use the non-contextual
mode. Pass False or nothing if you want to use the current mode.
The references to the 4D variables and 4DSCRIPT type tags (if any) in the text are always
analyzed, regardless of the mode.
Example
The following method:
TEXT TO BLOB("<html><head></head><body>"+String(Current time)
+"</body></html>";$blob;Text without length)
SEND HTML BLOB($blob;"text/html")
See Also
Mac to ISO, SEND HTML BLOB.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET WEB FORM VARIABLES command fills the text arrays nameArray and valueArray
with the variable names and values contained in the Web form “submitted” (i.e. sent to
the Web server).
This command gets the value for all the variables which can be included in HTML pages:
text area, button, checkbox, radio button, pop up menu, choice list...
Note: Regarding checkboxes, the variable name and value (“On”) are returned only if the
checkbox has been actually checked.
This command is valid for non-contextual mode or in contextual mode (except for 4D
Client) when it is called with the following conditions:
• a form is submitted with the “POST” method (action starting with /4DACTION,
/4DMETHOD or /4DCGI),
• a form is submitted with the “GET” method (action starting with /4DACTION,
/4DMETHOD or /4DCGI),
• an URL containing a request string is sent to the Web server.
This command can be called, if necessary, in the On Web Connection Database Method or
any other 4D method resulting from a form submission.
The vNAME variable contains ROBERT and the vCITY variable contains DALLAS.
See Also
Binding 4D objects with HTML objects, URLs and Form Actions.
Description
The Web Context command must be called from a Web process. It returns a boolean that
indicates if the Web connection is executing in contextual mode (True) or in non-
contextual mode (False).
Note : The Web Context command always returns False when it is:
• called from a process other than a Web process,
• executed on a 4D Client machine.
The use of this function is advocated in the On Web Connection Database Method.
Example
Here is an example of the On Web Connection database method:
⇒ If (Web Context)
WithContext ($1;$2;$3;$4;$5;$6)
Else
WithoutContext ($1;$2;$3;$4;$5;$6)
End if
See Also
On Web Connection Database Method, PROCESS PROPERTIES, Using the Contextual Mode.
Description
The SET HTTP HEADER command allows you to set the fields in the HTTP header of the
reply sent to the Web browser by 4D. It only has an effect in a Web process in non-
contextual mode.
This command allows you to manage “cookies”.
Note: The command will not accept a literal text type constant as the header parameter, it
must be a 4D variable or field.
For more information about the syntax, please refer to the R.F.Cs (Request For Comments)
that can be found at the following Internet address: http://www.w3c.org.
valueArray{1}:="HTTP/1.0" *
valueArray{2}:="200 OK" *
valueArray{3}:="C=HELLO"
* The first two items are the first line of the answer. When they are entered, they should
be the first and second items array. However, it is possible to omit them and to only write
— 4D taking care of the header format:
fieldArray{1}:="Set-Cookie"
valueArray{1}:="C=HELLO"
If several SET HTTP HEADER calls occur in the same Web process, only the last call is taken
into account.
The Server, Date and Content-Length fields are always set by 4D.
See Also
GET HTTP HEADER.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET HTTP HEADER command returns either a string or two arrays, containing the
HTTP header used for the currently processed request.
This command works only in non-contextual mode. It can be called from within any
method (On Web Connection Database Method or On Web Authentication Database
Method, method called by '/4DACTION'...) executed in a Web process in a non-contextual
mode. If GET HTTP HEADER is called in contextual mode, it returns empty strings.
Each header field is separated by a CR+LF (Carriage return+Line feed) sequence under
Windows and MacOS.
To comply with the HTTP standard, field names are always written in English.
Example
The following method allows getting any HTTP request header field content:
` Project method GetHTTPField
` GetHTTPField (Text) -> Text
` GetHTTPField (HTTP header name) -> HTTP header content
C_TEXT($0;$1)
C_LONGINT($vlItem)
ARRAY TEXT($names;0)
ARRAY TEXT($values;0)
$0:=""
⇒ GET HTTP HEADER($names;$values)
$vlItem:=Find in array($names;$1)
If ($vlItem>0)
$0:=$values{$vlItem}
End if
• Once this project method has been written, it can be called as follows:
` Cookie header content
$cookie:=GetHTTPField("Cookie")
• You can send different pages according to the language set in the browser (for example
in the On Web Connection Database Method):
$language:=GetHTTPField("Accept-Language")
Case of
:($language="@fr@") `French (see list ISO 639)
SEND HTML FILE("index_fr.html")
:($language="@sp@") `Spanish (see list ISO 639)
SEND HTML FILE("index_es.html")
Else
SEND HTML FILE("index.html")
End case
See Also
SET HTTP HEADER.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SEND HTTP REDIRECT command allows you to transform a URL into another one.
The url parameter contains the new URL that allows you to redirect the request. If this
parameter is a url to a file, it must contain the reference to this file, for example: SEND
HTTP REDIRECT ("/MyPage.HTM").
When this command is called in contextual mode, the Web process is aborted just after
being executed. The command prevails over commands that send data (SEND HTML FILE,
SEND HTML BLOB, etc.) that may be in the same method.
This command also allows you to redirect a request to another Web server.
4D automatically encodes the URL’s special characters. If you pass the * character, 4D will
not translate them.
Example
You can use this command to execute custom requests in 4D by using static pages.
Imagine that you have placed the following elements in a static HTML page:
Note: The POST action “/4dcgi/rech” has been associated to the text area and to the OK
and Cancel buttons.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command WEB CACHE STATISTICS allows you to obtain information about the most
consulted pages loaded in the Web server’s cache. Consequently, these statistics only
concern static pages, GIF pictures, JPEG pictures <100 KB and style sheets (.css).
Note: For more information about setting the 4D Web server’s cache, please refer to
section Web Server Settings.
The command fills the pages Text array with the names of the most consulted pages. The
hits Longint array receives the number of “hits” for each page. The usage parameter
receives the percentage of the Web cache used by each page.
Example
Let’s assume that you want to generate a semi-dynamic page that displays the statistics of
the Web cache. For this, in a static HTML page named “stats.shtm”, you place the tag
<!--4DACTION/STATS--> . Then you insert two 4D variables, vPages and vUsage.
In the project method STATS, you write the following code:
C_TEXT ($1)
ARRAY TEXT (pages;0)
ARRAY LONGINT (hits;0)
C_LONGINT (vUsage)
See Also
Web Services, Web Server Settings.
version 6.7
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Secured Web connection returns a boolean indicating if the 4D Web server
connection was done in secured mode through SSL (the request starts with “https:”
instead of “http:”).
Note: For more information on the SSL protocol, refer to section Using SSL Protocol.
This command allows, for example, denying connections made in a non secured mode (if
any).
See Also
GENERATE CERTIFICATE REQUEST, Web Services, Using SSL Protocol.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command OPEN WEB URL launches your Web browser and opens it on the URL
passed in the url parameter.
If your Web browser was already opened when you execute this command:
• On Windows, an additional instance of the browser is executed and displays the
specified page by url.
• On MacOS, the specified page by url replaces the current page in the browser.
If there is no browser on the volumes connected to the computer, this command has no
effect.
Note: Under MacOS, this command will read the Internet settings (default browser)
defined in the Internet Control panel, if any.
4D automatically encodes the URL’s special characters. If you pass the * character, 4D will
not translate the URL’s special characters. This option allows you to access and to send
URLS of type "http://www.server.net/page.htm?q=something".
Note: This command does not work when called from a Web process.
Examples
(1) When the following line of code is executed:
⇒ OPEN WEB URL("file:///D:/web file.htm")
The Web browser is launched and the URL is translated into
"file:///D%3A/web%20file.htm".
(3) The following line of code launches the browser and connects it to 4D’s home page:
⇒ OPEN WEB URL("http://www.4d.com/")
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Subscription to Web Services with 4th Dimension is easy to carry out using the Web
Services Wizard. In most cases, this Wizard will be sufficient for you to be able to use Web
Services. However, if you want to customize certain mechanisms, you must use the client
SOAP commands of 4th Dimension 2003.
This section describes the commands used for subscription to external Web Services
(client part). For more general information about Web Services or for a description of the
commands used for the publication of Web Services (server part), refer to the Web Services
(Server) commands section.
Note: By convention, the terms “SOAP” and “Web Service” have been used to
differentiate between command (and constant) names on the server and client side,
respectively. These two concepts refer to the same technology.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SET WEB SERVICE PARAMETER command enables the definition of a parameter used
for a client SOAP request. Call this command for each parameter in the request (the
number of times the command is called depends on the number of parameters).
In name, pass the name of the parameter as it must appear in the SOAP request.
In value, pass the 4D variable containing the value of the parameter. In the case of proxy
methods, this variable is generally $1, $2, $3, etc., corresponding to a 4D parameter
passed to the proxy method when it was called. It is, however, possible to use
intermediary variables.
Note: Each 4D variable or array used must first be declared using the commands of the
“Compiler” and “Arrays” themes.
By default, 4th Dimension automatically determines the most appropriate SOAP type for
the name parameter according to the content of value. The indication of the type is
included in the request.
However, you may want to “force” the definition of the SOAP type of a parameter. In this
case, you can pass the optional soapType parameter using one of the following character
strings (primary data types):
soapType Description
string String
int Longint
boolean Boolean
float 32-bit real
decimal Real with decimal
double 64-bit real
duration Duration in years, months, days, hours, minutes, seconds, for example
P1Y2M3DT10H30M
datetime Date and time in ISO8601 format, for example 2003-05-31T13:20:00
time Time, for example 13:20:00
date Date, for example 2003-05-31
gyearmonth Year and month (Gregorian calender), for example 2003-05
Example
This example defines two parameters:
C_TEXT($1)
C_TEXT($2)
⇒ SET WEB SERVICE PARAMETER("city";$1)
⇒ SET WEB SERVICE PARAMETER("country";$2)
See also
CALL WEB SERVICE, GET WEB SERVICE RESULT.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The CALL WEB SERVICE command is used to call a Web Service by sending an HTTP
request. This request contains the SOAP message created previously using the SET WEB
SERVICE PARAMETER command.
Any subsequent call to the SET WEB SERVICE PARAMETER command will cause the creation
of a new request. The execution of the CALL WEB SERVICE command also erases any result
from a previously-called Web Service and replaces it with the new result(s).
In accessURL, pass the complete URL allowing access to the Web Service (do not confuse
this URL with that of the WSDL file, which describes the Web Service).
• Access in secure mode (SSL): If you want to use a Web Service in secure mode using SSL,
pass https:// in front of the URL instead of http://. This configuration automatically
enables connection in secure mode.
In soapAction, pass the contents of the SOAPAction field of the request. This field
generally contains the value “ServiceName#MethodName”.
In methodName, pass the name of the remote method (belonging to the Web Service)
that you want to execute.
In namespace, pass the XML namespace used for the SOAP request. For more information
about XML namespaces, refer to the Design Mode manual of 4D.
The optional complexType parameter specifies the configuration of the Web Service
parameters sent or received (defined using the SET WEB SERVICE PARAMETER and GET WEB
SERVICE RESULT commands). The value of the complexType parameter depends on the
publication mode of the Web Service (DOC or RPC, cf. Design Mode manual of 4D) and
on its own parameters.
The following table shows all the possible configurations as well as the corresponding
constants:
Input parameters
Output parameters Simple Complex
Simple Web Service Dynamic Web Service Manual In
(RPC mode) (RPC mode)
Complex Web Service Manual Out Web Service Manual
(RPC mode) (RPC or DOC mode)
The five configurations described below can therefore be implemented. In all cases, 4th
Dimension will handle the formatting of the SOAP request to be sent to the Web Service
as well as its envelope. It is up to you to format the contents of this request according to
the configuration used.
Note: Despite the fact that they are complex XML types, data arrays are handled by 4D as
simple types.
To use a Web Service published in DOC mode (or in RPC mode with complex types), it is
advisable to proceed as follows:
• Generate the proxy method using the Client Web Services Wizard.
The proxy method will be called in the following manner:
$XMLresultBlob:=$DOCproxy_Method($XMLparamBlob)
• Familiarize yourself with the contents of SOAP requests to be sent to the Web Service
using an on-line test (for instance, http://soapclient.com/soaptest.html). This type of tool is
used to generate HTML test forms based on the WSDL of the Web Service.
• Copy the XML contents generated from the first child element of <body>.
• Write the method enabling you to place the real parameter values into the XML code;
this code must then be placed in the $XMLparamBlob BLOB.
• To parse the response, you can also use an on-line test, or make use of the WSDL that
specifies the returned elements.
See also
GET WEB SERVICE RESULT, SET WEB SERVICE PARAMETER.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET WEB SERVICE RESULT command is used to retrieve a value sent back by the Web
Service as a result of the processing performed.
Note: This command must be used only after the CALL WEB SERVICE command.
The returnValue parameter receives the value sent back by the Web Service. Pass a 4D
variable in this parameter. This variable is generally $0, corresponding to the value
returned by the proxy method. It is, however, possible to use intermediary variables (you
must use process variables only).
Note: Each 4D variable or array used must be previously declared using the commands of
the “Compiler” and “Arrays” themes.
The optional returnName parameter is used to specify the name of the parameter to be
retrieved. However, since most Web Services only return a single value, this parameter is
generally not necessary.
The optional * parameter signals the program to free up the memory devoted to the
processing of the request. You must pass this parameter after retrieving the last value sent
by the Web Service.
If (OK=1)
⇒ GET WEB SERVICE RESULT($0;"return";*)
End if
See also
CALL WEB SERVICE, SET WEB SERVICE PARAMETER.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The AUTHENTICATE WEB SERVICE command enables the use of Web Services requiring
authentication of the client application (simple authentication).
In the name and password parameters, pass the required identification information (user
name and password). This information will be encoded and added to the HTTP request
sent to the Web Service using the CALL WEB SERVICE command. It is thus necessary to call
the AUTHENTICATE WEB SERVICE command before calling the CALL WEB SERVICE
command.
The authentication information is reset to zero after each request. Therefore, you must
use the AUTHENTICATE WEB SERVICE command before each CALL WEB SERVICE command.
If authentication fails, the SOAP server returns an error that you can identify using the
Get Web Service error info command.
See also
CALL WEB SERVICE, Get Web Service error info.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Get Web Service error info command returns information about the last error
encountered during the execution of a SOAP request sent to a remote Web Service.
The infoType parameter allows you to indicate the type of information that you want to
obtain. You must pass one of the constants listed below, located in the Web Services
(Client) theme:
Constant Type Value
Web Service Error Code Longint 0
Web Service Detailed Message Longint 1
Web Service HTTP Error code Longint 2
Web Service Fault Actor Longint 3
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Starting with version 2003, 4th Dimension supports“Web Services”, meaning that the
program enables you to publish (server part) and/or use (client part) Web Services directly
from your database.
A Web Service is a set of functions published on a network. These functions can be called
and used by any application compatible with Web Services and connected to a network.
Web Services can carry out all types of tasks, such as supervising the routing of packages
at a transporter’s, e-commerce, monitoring market values, etc.
For more information about the concept and operation of Web Services, refer to the
Design Mode manual.
This section describes the commands used for the publication of Web Services in 4th
Dimension (server part). For a description of the commands used for subscription to Web
Services (client part), refer to the Web Services (Client) commands.
Publication of Web Services with 4th Dimension is carried out easily using the options in
the method properties. In most cases, this operation will be sufficient to enable you to
publish Web Services. However, if you want to customize certain mechanisms, use data
arrays, etc., you must use the server SOAP commands of 4th Dimension 2003.
Note: By convention, the terms “SOAP” and “Web Service” have been used to
differentiate between command (and constant) names on the server and client side,
respectively. These two concepts refer to the same technology.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SOAP DECLARATION command is used to explicitly declare the type of parameters
used in a 4D method published as a Web Service.
When a method is published as a Web Service, the standard parameters $0, $1... $n are
used to describe the parameters of the Web Service to the outside world (more particularly
in the WSDL file). The SOAP protocol requires that parameters be explicitly named; 4th
Dimension uses the names “FourD_arg0, FourD_arg1 ... FourD_argn” by default.
This default operation can nevertheless prove to be problematic for the following reasons:
• It is not possible to declare $0 or $1 an array. Therefore, it is necessary to use pointers;
however, in this case, the type of values must be known for the generation of the WSDL
file.
• Next, it can be useful or necessary to customize the parameter names (incoming and
outgoing).
• Finally, this operation makes it impossible to return more than one value per RPC call
(in $0).
The SOAP DECLARATION command allows you to be free from these limits. You can
execute this command for each incoming and outgoing parameter and assign it a name
and a type.
Note: Even if the SOAP DECLARATION command is used, it is always necessary to declare
4D variables using commands of the “Compiler” theme.
In variable, pass the 4D variable to be referred to when calling the Web Service.
Warning, you can only refer to process variables or 4D method arguments ($0 to $n).
Local and interprocess variables cannot be used.
In alias, pass the name of the argument as it must appear in the WSDL and in the SOAP
exchanges.
Warning: This name must be unique in the RPC call (both input and output parameters
taken together), otherwise, only the last declaration will be taken into account by 4D.
Note: In conformity with the XML standard for marker names, the argument names
Examples
(1) This example specifies a parameter name:
` During generation of the WSDL file and SOAP calls, the word
` zipcode will be used instead of fourD_arg1
C_LONGINT($1)
⇒ SOAP DECLARATION($1;Is LongInt;SOAP Input;"zipcode")
(2) This example is used to retrieve an array of zip codes in the form of longints:
ARRAY LONGINT(codes;0)
⇒ SOAP DECLARATION(codes;LongInt array;SOAP Input;"in_codes")
(3) This example is used to refer to two return values without specifying an argument
name:
See also
Get SOAP info, Is data file locked, SEND SOAP FAULT.
Constants
Field and Variable Types and Web Services themes.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SEND SOAP FAULT command is used to return an error to a SOAP client indicating the
origin of the fault: client or server. Using this command enables you to indicate an error
to a client without having to return a result.
For instance, a fault on the client side may be detected when you publish a “Square_root”
Web Service and a client sends a request with a negative number; you can use this
command in order to indicate to the client that a positive value is required.
A possible fault on the server side may be, for instance, a lack of memory occurring
during method execution.
Pass the origin of the error in faultType. You can use the following predefined constants,
located in the “Web Services (Server)” theme:
Constant Type Value
SOAP Client Fault Longint 1
SOAP Server Fault Longint 2
Example
To go back to the example of the “Square_root” Web Service provided in the command
description, the following command can be used to process requests with negative
numbers:
See also
Get SOAP info, SOAP DECLARATION.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Is SOAP request command returns True if the code being executed is part of a SOAP
request.
This command can be used for security reasons in the On Web Authentication Database
Method in order to determine the nature of the received requests.
See also
On Web Authentication Database Method, SOAP DECLARATION.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Get SOAP info command is used to retrieve, in the form of a character string, the
different types of information concerning a SOAP request.
When you process a SOAP request, it may be useful to obtain additional information —
other than the RPC parameter values — about the request. For instance, for security
reasons, you can use this command in the On Web Authentication Database Method to
find out the name of the requested Web Service method.
Pass the number of the type of SOAP information you want to get in the infoNum
parameter. You can use the following predefined constants, located in the “Web Services
(Server)” theme:
Constant Type Value
SOAP Method Name Longint 1
SOAP Service Name Longint 2
• SOAP Method Name = name of the Web Service method about to be executed.
• SOAP Service Name = name of the Web Service to which the method belongs.
Note: Also for security reasons, it is possible to set the maximum size for Web Services
requests sent to 4D. This configuration is carried out using the SET DATABASE PARAMETER
command (“Structure Access” theme).
See also
SEND SOAP FAULT, SET DATABASE PARAMETER.
Windows
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Windows are used to display information to the user. They have three main uses: to enter
data, to display data, and to inform the user in messages and dialogs.
There is always at least one window open. Scroll bars are added, when needed, to let the
user scroll in a form that is larger than the window. In the User environment, this
window displays either the record list (output form) or the data entry screen (input form).
In the Custom Menus environment, this window displays a splash screen (a custom
graphic).
When you execute a menu command within the Custom Menus process, the splash
screen can be replaced with data by commands that display forms. When the commands
finish executing, the splash screen is displayed again.
You can open various types of custom windows with the Open Window command. When
you no longer need a custom window, you should close it using the CLOSE WINDOW
command or by clicking the Control-menu box (Windows) or Close Box (Macintosh), if
it exists.
Some commands open their own windows. Commands such as GRAPH TABLE, REPORT,
and PRINT LABEL open a window that becomes the frontmost window.
If you start a new process and do not open a window at the beginning of the process
method, 4D will automatically open a default one as soon as a form is to be displayed.
See Also
Open window, Window Types.
You can use one of the following predefined constants to specify the type of window that
you open with Open window:
Floating Windows: If you pass one of these constants to Open window, you open a regular
windows. To open a floating windows, pass a negative window type value to Open
window.
The following tables shows each window type, on Windows (left) and on Mac (right).
When you call Open window, you can add one or several of the following constants to
Palette window in order to obtain variations in the behavior of the window:
Constant Type Value
Has zoom box Long Integer 8
Has grow box Long Integer 4
Has window title Long Integer 2
Has highlight Long Integer 1
See Also
Open external window, Open window.
Open window (left; top; right; bottom{; type{; title{; controlMenuBox}}}){ → WinRef }
Description
Open window opens a new window with the dimensions given by the first four
parameters:
• left is the distance in pixels from the left edge of the application window to the left
internal edge of the window.
• top is the distance in pixels from the top of the application window to the top internal
edge of the window.
• right is the distance in pixels from the left edge of the application window to the right
internal edge of the window.
• bottom is the distance in pixels from the top of the application window to the bottom
internal edge of the window.
If you pass -1 in both right and bottom, you instruct 4D to automatically size the window
under the following conditions:
• You have designed a form and set its Sizing Options in the Design environment Form
properties window
• Before calling Open window, you selected the form using the command INPUT FORM, to
which you passed the optional * parameter.
Important: This automatic sizing of the window will occur only if you made a prior call to
INPUT FORM for the form to be displayed, and if you passed the * optional parameter to
INPUT FORM.
If you pass an empty string ("") in title, you instruct 4D to use the Window Title set in the
Design environment Form Properties window for the form to be displayed.
Important: The default form title will be set to the window only if you made a prior call to
INPUT FORM for the form to be displayed, and if you passed the * optional parameter to
INPUT FORM.
• The controlMenuBox parameter is the optional Control-menu box method for the
window. If this parameter is specified, a Control-menu box (Windows) or a Close Box
(Macintosh) is added to the window. When the user double-clicks the Control-menu box
(Windows) or clicks on the Close Box (Macintosh), the method passed in controlMenuBox
is called.
Version 6 Note: You can also manage the closing of the window from within the form
method of the form displayed in the window when an On Close Box event occurs. For
more information, see the command Form event.
If more than one window is open for a process, the last window opened is the active
(frontmost) window for that process. Only information within the active window can be
modified. Any other windows can be viewed. When the user types, the active window will
always come to the front, if it is not already there.
Forms are displayed inside an open window. Text from the MESSAGE command also
appears in the window.
Examples
1. The following project method opens a window centered in the main window
(Windows) or in the main screen (Macintosh). Note that it can accept two, three, or four
parameters:
` OPEN CENTERED WINDOW project method
` $1 – Window width
` $2 – Window height
` $3 – Window type (optional)
` $4 – Window title (optional)
$SW:=Screen width\2
$SH:=(Screen height\2)
$WW:=$1\2
$WH:=$2\2
After the project method is written, you can use it this way:
OPEN CENTERED WINDOW (400;250;Movable dialog box;"Update Archives")
DIALOG([Utility Table];"UPDATE OPTIONS")
CLOSE WINDOW
If (OK=1)
` ...
End if
2. The following example opens a floating window that has a Control-menu box
(Windows) or Close Box (Macintosh) method. The window is opened in the upper right
hand corner of the application window.
3. The following example opens a window whose size and title come from the properties
of the form displayed in the window:
INPUT FORM([Customers];"Add Records";*)
⇒ Open window(10;80;-1;-1;Plain window;"")
Repeat
ADD RECORD([Customers])
Until (OK=0)
Reminder: In order to have Open window automatically use the properties of the form,
you must call INPUT FORM with the optional * parameter, and the properties of the form
must have been set accordingly in the Design environment.
See Also
CLOSE WINDOW, Open external window, Open form window.
Open external window (left; top; right; bottom; type; title; plugInArea) → Number
Description
Open external window opens a new window and displays the external area supported by
the command plugInArea provided by a 4D plug-in.
Open external window returns a Long Integer value that can be used both as a window
reference number (that can be used with other Windows commands) and as a reference
to the external area displayed in the window (that can be used with other routines
provided by the 4D plug-in).
The first six arguments are the same as those of the the Open window command.
However, none of the parameters are optional.
Open external window creates modeless windows. The command does not wait for user
input, so you can have several active windows open at once. You can click between each
window and edit the one in front. If the window type has a title bar, a Control-menu box
(Windows) or a Close Box (Macintosh) will be added to enable the user to close the
window.
Example
The following example opens an external window and displays the 4D Write external
area:
⇒ wrWind:=Open external window (50; 50; 350; 450; 8; "Letter Writing"; "_4D WRITE")
The following example closes the external window opened in the previous example:
CLOSE WINDOW (wrWind)
See Also
CLOSE WINDOW, Open window.
version 3
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
CLOSE WINDOW closes the active window opened by an Open window command in the
current process. CLOSE WINDOW has no effect if a custom window is not open; it does
not close standard windows. CLOSE WINDOW also has no effect if called while a form is
active in the window. You must call CLOSE WINDOW when you are done using a window
opened by Open window.
It is useless to pass a number to Close window when closing a window previously opened
by the Open window function, since a call to Close window will close the last window
created by Open window.
If you pass an external window reference number in the extWindowRef parameter, CLOSE
WINDOW closes the specified external window. For more information about external
windows, refer to the Open external window function.
Example
The following example opens a window and adds new records with the ADD RECORD
command. When the records have been added, the window is closed with CLOSE
WINDOW:
Open window (5; 40; 250; 300; 0; "New Employee")
Repeat
ADD RECORD ([Employees]) ` Add a new employee record
Until (OK = 0) ` Loop until the user cancels
⇒ CLOSE WINDOW ` Close the window
See Also
Open external window, Open window.
Description
The command ERASE WINDOW clears the contents of the window whose reference
number is passed in window.
If you omit the window parameter, ERASE WINDOW clears the contents of the frontmost
window for the current process.
Usually, you will use ERASE WINDOW in combination with MESSAGE and GOTO XY. In
this case, ERASE WINDOW clears the contents of the window and moves the cursor to the
upper-left corner of the window, the GOTO XY (0; 0) position.
Do not confuse ERASE WINDOW, which clears the contents of a window, with CLOSE
WINDOW, which removes the window from the screen.
See Also
GOTO XY, MESSAGE.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command REDRAW WINDOW provokes a graphical update of the window whose
reference number you pass in window.
If you omit the window parameter, REDRAW WINDOW applies to the frontmost window
for the current process.
Note: 4th Dimension handles the graphical updates of the windows each time you move
a window, resize it, or bring it to the front, as well as when you change the form and/or
the values displayed in the window. You will rarely use this command.
See Also
ERASE WINDOW.
DRAG WINDOW
Description
The command DRAG WINDOW allows users to drag the window on which they clicked
following the movements of the mouse. Usually you call this command from within an
object method of an object that can respond instantaneously to mouse clicks (i.e.,
invisible buttons).
Example
The following form, shown here in the Design Environment, contains a frame created
with a static picture, above which are four invisible buttons for each side:
Then you can drag the window by clicking anywhere on the borders.
See Also
GET WINDOW RECT, SET WINDOW RECT.
version 6.0.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The HIDE WINDOW command allows you to hide the window whose number was passed
in window or, if this parameter is omitted, the current process frontmost window. For
example, this command allows you to display only the active window in a process that
consists of several processes.
The window disappears from the screen but remains open. You can still programmatically
apply any changes supported by 4D windows.
To display a window that was previously hidden by the HIDE WINDOW command:
• Use the SHOW WINDOW command and pass the window reference ID.
• Use the Process page of the Runtime Explorer. Select the process in which the window is
handled, then click on the Show button.
To hide all the windows of a process, use the HIDE PROCESS command.
Example
This example corresponds to a method of a button located in an input form. This button
opens a dialog box in a new window that belongs to the same process. In this example,
the user wants to hide the other windows of the process (an entry form and a tool
palette) while displaying the dialog box. Once the dialog box is validated, other process
windows are displayed again.
` Object method for the "Information" button
See also
SHOW WINDOW.
version 6.0.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The SHOW WINDOW command allows you to display the window whose number was
passed in window. If this parameter is omitted, the frontmost window of the current
process will be displayed.
In order to use the SHOW WINDOW command, the window must have been hidden by
using the HIDE WINDOW command. If the window is already displayed, the command
does nothing.
Example
Refer to the example of the HIDE WINDOW command.
See also
HIDE WINDOW.
version 6.0.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The MAXIMIZE WINDOW command triggers the expansion of the window whose
reference number was passed in window. If this parameter is omitted, the effect is the
same but is applied to all the frontmost windows of the current process (Windows) or
to the frontmost window of the current process (Mac OS).
This command has the same effect as a click on the zoom box of a 4D application
window:
On Windows
The size of the window is increased to match the current size of the application window.
The maximized window is set to be the frontmost window. If you do not pass the window
parameter, the command is applied to all the application windows.
On Mac OS
The size of the window is increased to match the size of the main screen. If you do not
pass the window parameter, the command is applied to the frontmost window of the
current process.
This command only applies to windows that contain a zoom box. If the window type does
not include it, the command does nothing. For more information, please refer to the
Window Types section.
MAXIMIZE WINDOW sets a window to its "maximum" size. If the window is actually a
form whose size was defined in the form properties, the window size is set to those values.
If the window is already maximized, the command does nothing.
⇒ MAXIMIZE WINDOW
See also
MINIMIZE WINDOW.
version 6.0.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The MINIMIZE WINDOW command sets the size of the window whose number is passed
as window to the size it was before being maximized. If window is omitted, the command
applies to each window of the application (Windows) or to the frontmost window of the
process (on Mac OS).
This command has the same effect as one click on the reduction box of the 4D
application:
On Windows
The size of the window is set to its initial size, i.e., its size before being maximized. If the
window parameter is omitted, all the application windows are set to their initial sizes.
On Mac OS
The size of the window is set to its initial size (i.e. its size before being maximized). If the
window parameter is omitted, the frontmost window of the current process is set to its
initial size.
If the windows to which the command is applied were not previously maximized
(manually or using MAXIMIZE WINDOW), or if the window type does not include a zoom
box, the command has no effect. For more information on window types, refer to the
Window Types section.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Get window title returns the title of the window whose reference number is
passed in window. If the window does not exist, an empty string is returned.
If you omit the window parameter, Get window title returns the title of the frontmost
window for the current process.
Example
See example for the command SET WINDOW TITLE.
See Also
SET WINDOW TITLE.
Description
The command SET WINDOW TITLE changes the title of the window whose reference
number is passed in window to the text passed in title (max. length 80 characters). If the
window does not exist, SET WINDOW TITLE does nothing. If you omit the window
parameter, SET WINDOW TITLE changes the title of the frontmost window for the current
process.
Note: In the User environment, 4th Dimension changes the window titles automatically
—i.e., “Entry for Table” when you perform data entry. If you change a window title, 4D
will probably override it. On the other hand, in the Custom Menus environment, 4th
Dimension does not change the titles of the windows.
Example
While performing data entry in a form, you click on a button that executes a lengthy
operation (i.e., browsing programmatically related records shown in a subform). You keep
informed about the progress of the operation using the title of the current window:
` bAnalysis button Object Method
Case of
: (Form event=On Clicked)
$vsCurTitle:=Get window title ` Save current window title in a local variable
FIRST RECORD([Invoice Line Items]) ` Start the lengthy operation
For($vlRecord;1;Records in selection([Invoice Line Items]))
DO SOMETHING
` Show progress information
⇒ SET WINDOW TITLE("Processing Line Item #"+String($vlRecord))
End for
` Restore original window title
⇒ SET WINDOW TITLE($vsCurTitle)
End case
See Also
Get window title.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command WINDOW LIST populates the array windows with the window reference
numbers of the windows currently open in all running processes (kernel or user
processes).
If you do not pass the optional * parameter, floating windows are ignored.
Example
The following project method tiles all the current open window, except floating windows
and dialog boxes:
` TILE WINDOWS project method
⇒ WINDOW LIST($alWnd)
$vlLeft:=10
$vlTop:=80 ` Leave enough room for the Tool bar
For ($vlWnd;1;Size of array($alWnd))
If (Window kind($alWnd{$vlWnd}) # Modal Dialog)
GET WINDOW RECT($vlWL;$vlWT;$vlWR;$vlWB;$alWnd{$vlWnd})
$vlWR:=$vlLeft+($vlWR-$vlWL)
$vlWB:=$vlTop+($vlWB-$vlWT)
$vlWL:=$vlLeft
$vlWT:=$vlTop
SET WINDOW RECT($vlWL;$vlWT;$vlWR;$vlWB;$alWnd{$vlWnd})
$vlLeft:=$vlLeft+10
$vlTop:=$vlTop+25
End if
End for
Note: This method could be improved by adding tests on the size of the main window
(on Windows) or the size and location of the screens (on Macintosh).
See Also
Window kind, Window process.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Window kind returns the 4th Dimension type of the window whose
reference number is passed in window. If the window does not exist, Window kind returns
0 (zero).
If you omit the window parameter, Window kind returns the type of the frontmost
window for the current process.
Example
Set example for the command WINDOW LIST.
See Also
GET WINDOW RECT, Get window title, Window process.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Window process returns the process number that runs the window whose
reference number is passed in window. If the window does not exist, 0 (zero) is returned.
If you omit the window parameter, Window process returns the process of the current
frontmost window.
See Also
Current process.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET WINDOW RECT returns the global coordinates of the window whose
reference number is passed in window. If the window does not exist, the variable
parameters are left unchanged.
If you omit the window parameter, GET WINDOW RECT applies to the frontmost window
for the current process.
The coordinates are expressed relative to the top left corner of the contents area of the
application window (on Windows) or of the main screen (on Macintosh). The coordinates
return the rectangle corresponding to the contents area of the window (excluding title
bars and borders).
Example
See example for the command WINDOW LIST.
See Also
SET WINDOW RECT.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command SET WINDOW RECT changes the global coordinates of the the window
whose reference number is passed in window. If the window does not exist, the command
does nothing.
If you omit the window parameter, SET WINDOW RECT applies to the frontmost window
for the current process.
This command can resize and move the window, depending on the new coordinates
passed.
The coordinates must be expressed relative to the top left corner of the contents area of
the application window (on Windows) or to the main screen (on Macintosh). The
coordinates indicate the rectangle corresponding to the contents area of the window
(excluding title bars and borders).
Warning: Be aware that by using this command, you may move a window beyond the
limits of the main window (on Windows) or of the screens (on Macintosh). To prevent
this, use commands such as Screen width and Screen height to double-check the new
coordinates of the window.
Example
See example for the command WINDOW LIST.
See Also
DRAG WINDOW, GET WINDOW RECT.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Frontmost window returns the window reference number of the frontmost
window.
See Also
Frontmost process, Next window.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Next window returns the window reference number of the window
“behind” the window you pass in window (based on the front-to-back order of the
windows).
See Also
Frontmost window.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command Find window returns (if any) the reference number of the first window
“touched” by the point whose coordinates passed in left and top.
The coordinates must be expressed relative to the top left corner of the contents area of
the application window (Windows) or to the main screen (Macintosh).
If you specify the windowPart parameter, whether or not a window has been found, the
parameter returns one of the following values:
Constants Type Value Platform
In menu bar Long Integer 1 Macintosh only
In system window Long Integer 2 Macintosh only
In contents Long Integer 3 Windows or Macintosh
In drag Long Integer 4 Macintosh only
In grow Long Integer 5 Macintosh only
In go away Long Integer 6 Macintosh only
In zoom box Long Integer 7 Macintosh only
See Also
Frontmost window, Next window.
Open form window ({table; }formName{; type{; hPos{; vPos{; *}}}}) → WinRef
Description
The Open form window command opens a new window using the size and resizing
properties of the form formName.
Note that formName is not displayed in the window. If you want to display the form, you
have to call a command which loads a form (ADD RECORD for example).
By default (if the type parameter is not passed), a standard window with a close box is
opened. Unlike the Open window command, no method is associated to the window's
close box. Clicking on this close box cancels and closes the window, except if the On
Close Box form event has been activated for the form. In this case, the code associated to
the On Close Box event will be executed.
If formName is resizable, the window opened will contain a zoom box as well as a grow
box.
Note: To know the main properties of a form, use the GET FORM PROPERTIES command.
The optional type parameter allows you to specify a type for the window. You must pass
one of the following predefined constants (placed in the “Open form window” theme):
Constant Type Value
Standard form window Longint 8
Modal form dialog box Longint 1
Movable form dialog box Longint 5
Palette form window Longint 1984
Note: The attributes (grow box, close box...) of the window created depend on the
interface specifications of the operating system for the chosen type. It is therefore
possible to obtain different results depending on the platform used.
The optional parameter vPos allows you to define the vertical position of the window. You
can pass a defined position, expressed in points, to this parameter (refer to the Open
window command) or one of the following predefined constants placed in the “Open
form window” theme:
Constant Type Value
Vertically Centered Longint 262144
At the Top Longint 327680
At the Bottom Longint 393216
These parameters take into account the presence of the tool bar and menu bar as well as
the current size of the application's window (on Windows).
If you pass the optional parameter *, the current position and size of the window are
memorized when closed. When the window is reopened again, its previous position and
size are respected. In this case, the vPos and hPos parameters are only used the first time
the window is opened.
Examples
(1) The following statement opens a standard window with a close box and automatically
adjusts it to be the same size as the "Input" form. Since the form has been defined as
resizable, the window also has a grow and a zoom box:
(2) The following statement opens a floating palette in the upper left portion of the
screen. This palette uses the last position it was in when the user closed it each time it is
reopened:
⇒ $winRef := Open form window ([Table1]; "Tools"; Palette form window; On the Left;
At the Top;*)
See Also
GET FORM PROPERTIES, Open window.
version 6.5
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The command GET FORM PROPERTIES returns the properties of the form formName.
The width and height parameters return the form’s width and height in pixels. These
values are determined from the form’s Default window size properties:
• If the form’s size is automatic, its width and height are calculated so that all the form’s
objects are visible, by taking into consideration the horizontal and vertical margins that
were defined.
• If the form’s size is set, its width and height are those manually entered in the
corresponding areas.
• If the form’s size is based on an object, its width and height are calculated in relation to
this object’s position.
The numPages parameter returns the number of pages in the form, excluding page 0
(zero).
The fixedWidth and fixedHeight parameters indicate if the length and width of the form
are resizable (the parameter returns False) or set (the parameter returns True).
The title parameter returns the title of the form's window as it was defined. If no name
was defined, the title parameter returns an empty string.
See Also
Open form window.
XML
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension 2003 includes a set of commands used for parsing objects containing
XML (eXtensible Markup Language) data.
The XML language is a data exchange standard. It is based on the use of tags and enables
precise description of the data exchanged as well as their structure. XML files are Text
format files, their content is parsed by the applications importing the data. Many
applications now support this format.
For more information about XML, refer, for instance, to the sites http://xml.org and
http://www.w3.org.
Terminology
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The XML language uses a number of specific terms and acronyms. This non-exhaustive
list expldetails the main XML concepts used by the commands and functions of 4th
Dimension.
DTD: Document Type Declaration The DTD records the set of specific rules and properties
that the XML must follow. These rules define, more particularly, the name and content of
each tag as well as its context. This formalization of the elements can be used to check
whether an XML document is in compliance (in which case, it is declared “valid”).
The DTD may be included in the XML document (internal DTD) or in a separate
document (external DTD). Note that the DTD is not mandatory.
Element: an XML tag. An element always contains a name and a value. Optionally, an
element may contain attributes (cf. diagram).
ElementRef: XML reference used by the 4D XML commands to specify an XML structure.
This reference is made up of 8 coded characters in hexadecimal form, which means it
consists of 16 characters.
Structure XML: structured XML object. This object can be a document, a variable, or an
element.
XML: eXtensible Markup Language. A computerized data exchange standard enabling the
transfer of data as well as their structure. The XML language is based on the use of tags
and a specific syntax, in keeping with the HTML language. However, unlike the latter, the
XML language allows the definition of customized tags.
XSL: eXtensible Stylesheet Language. A language permitting the definition of style sheets
used to process and display the contents of an XSL document.
4D XML commands
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The objects parsed by 4D XML commands can be texts, URLs, documents or BLOBs.
To parse XML, 4th Dimension uses a library named Xerces.dll developed by the Apache
Software Foundation. 4th Dimension supports XML version 1.0.
The structure of the statements used for parsing XML objects in 4th Dimension is as
follows:
• Opening and parsing of source: Parse XML source, Parse XML variable.
• Identification and reading of elements: Count XML elements, Get First XML element, Get
Next XML element, Get XML element, GET XML ELEMENT NAME, GET XML ELEMENT
VALUE.
• Identification of attributes: Count XML attributes, GET XML ATTRIBUTE BY INDEX, GET
XML ATTRIBUTE BY NAME.
• Retrieval of errors and information: GET XML ERROR, Parse XML information.
• Closing of source: CLOSE XML.
Note: 4th Dimension allows direct importing and exporting of data in XML format using
the import/export editor in User mode.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Parse XML source command parses a document containing an XML structure and
returns a reference for this document. The command can validate (or not) the document.
The document can be located on the disk or on the Internet/Intranet.
The Boolean parameter validation is used to indicate whether or not to validate the
structure using the DTD.
• If validation equals True, the structure will be validated. In this case, the parser will
attempt to validate the XML structure of the document based either on the DTD defined
or referred to in the document, or that designated by the dtd parameter.
• If validation equals False, the structure will not be validated.
The third parameter, dtd, is used to indicate the specific DTD for document parsing. If
you use this parameter, the command will not take the DTD referred to in the XML
document into account.
There are two ways to specify a DTD:
• as a reference. To do this, pass the complete access path of the new DTD in the dtd
parameter. If the document indicated does not contain a valid DTD, the dtd parameter is
ignored and an error is generated.
• in a BLOB or Text. In this case, if the contents of the parameter begins with “<xml !”,
4D will consider that it is the DTD; otherwise, 4D will consider it as an access path.
If validation cannot be performed (no DTD, incorrect URL to DTD, etc.), an error is
generated. The Error system variable indicates the error number. You can intercept this
error using a method installed by the ON ERR CALL command.
(2) Opening an XML document located next to the database structure file, without
validation:
(3) Opening an XML document located on disk and validation using a DTD on the disk:
See also
Parse XML variable.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Parse XML variable command parses a BLOB or Text type variable containing an XML
structure and returns a reference for this variable. The command can validate (or not) the
document.
Pass the name of the BLOB or Text variable containing the XML object in the variable
parameter.
The Boolean parameter validation is used to indicate whether or not to validate the
structure using the DTD.
• If validation equals True, the structure will be validated. In this case, the parser will
attempt to validate the XML structure of the document based either on the DTD defined
or referred to in the document, or that designated by the dtd parameter.
• If validation equals False, the structure will not be validated.
The third parameter, dtd, is used to indicate the specific DTD for document parsing. If
you use this parameter, the command will not take the DTD referred to in the XML
variable into account.
If validation cannot be performed (no DTD, incorrect URL to DTD, etc.), an error is
generated. The Error system variable indicates the error number. You can intercept this
error using a method installed by the ON ERR CALL command.
The command returns a 16-character string (ElementRef) making up the reference in the
memory of the document virtual structure. This reference should be used with other XML
parsing commands.
DOCUMENT TO BLOB(“c:\import.xml”;myBlobVar)
⇒ $xml_Struct_Ref:=Parse XML variable(myBlobVar)
See also
Parse XML source.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Count XML elements command returns the number of “child” elements dependent
on the elementRef parent element and named elementName.
See also
Get XML element.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Get XML element command returns a reference to the “child” element dependent on
the elementName and index parameters.
See also
GET XML ELEMENT VALUE.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Get First XML element returns a reference to the first “child” of the XML element
passed in elementRef. This reference can be used with other XML parsing commands.
The childElemName and childElemValue parameters, if they are passed, receive respectively
the name and the value of the child element.
Examples
(1) Retrieval of the reference of the first XML element of the parent root. The XML
structure (C:\import.xml) is first loaded into a BLOB:
C_BLOB(myBlobVar)
C_STRING(16;$xml_Parent_Ref;$xml_Child_Ref)
DOCUMENT TO BLOB("c:\import.xml";myBlobVar)
$xml_Parent_Ref:=Parse XML variable(myBlobVar)
⇒ $xml_Child_Ref:=Get First XML element($xml_Parent_Ref)
DOCUMENT TO BLOB("c:\import.xml";myBlobVar)
$xml_Parent_Ref:=Parse XML variable(myBlobVar)
⇒ $xml_Child_Ref:=Get First XML element($xml_Parent_Ref;$childName;$childValue)
See also
Get Next XML element.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Get Next XML element command returns a reference to the next “child” of the XML
element passed as reference. This reference can be used with other XML parsing
commands.
The childElemName and childElemValue parameters, if they are passed, receive respectively
the name and the value of the “child” element.
This command is used to parse successively all the “children” of the XML element passed
as parameter.
Examples
(1) Retrieval of the reference of the next XML element following the element passed as
parameter:
C_STRING(16;$xml_Parent_Ref;$next_XML_Ref)
⇒ $next_XML_Ref:=Get Next XML element($xml_Parent_Ref)
See also
Get First XML element.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET XML ELEMENT NAME command returns, in the elementName parameter, the
name of the XML element designated by elementRef. For more information on XML
element names, refer to the Presentation of XML commands section.
Example
This method returns the name of the $xml_Element_Ref element:
C_STRING(16;$xml_Element_Ref)
C_TEXT($name)
See also
Get XML element, GET XML ELEMENT VALUE.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET XML ELEMENT VALUE command returns, in the elementValue parameter, the value
of the XML element designated by elementRef. 4th Dimension will attempt to convert the
value obtained into the same type as that of the variable passed as parameter.
Example
This method returns the value of the $xml_Element_Ref element:
C_STRING(16;$xml_Element_Ref)
C_REAL($value)
See also
Get XML element, GET XML ELEMENT NAME.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Count XML attributes command returns the number of XML attributes present in the
XML element designated by elementRef. For more information about XML attributes, refer
to the Presentation of XML commands section.
Example
Before retrieving the values of elements in an array, you want to know the number of
attributes in the following XML element:
C_BLOB(myBlobVar)
C_STRING(16;$xml_Parent_Ref;$xml_Child_Ref)
C_TEXT(myResult)
C_LONGINT($numAttributes)
$xml_Parent_Ref:=Parse XML variable(myBlobVar)
$xml_Child_Ref:=Get First XML element($xml_Parent_Ref)
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET XML ATTRIBUTE BY INDEX command is used to get the name of an attribute
specified by its index number as well as, optionally, its value.
Pass the reference of an XML element in elementRef and the index number of the
attribute that you want to know the name of in attribIndex. The name is returned in the
attribName parameter and its value is returned in the attribValue, parameter, if it is passed.
In this case, 4th Dimension will attempt to convert the value obtained into the same type
as that of the variable passed as parameter.
If the value passed in attribIndex is greater than the number of attributes present in the
XML element, an error is returned.
Example
Refer to the example in the Count XML attributes command.
See also
GET XML ATTRIBUTE BY NAME.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET XML ATTRIBUTE BY NAME command is used to get the value of an attribute
specified by name.
Pass the reference of an XML element in elementRef and the name of the attribute that
you want to know the value of in attribName. The value is returned in the attribValue
parameter. 4th Dimension will attempt to convert the value obtained into the same type
as that of the variable passed as parameter.
Examples
This method is used to retrieve the value of an XML attribute using its name:
C_BLOB(myBlobVar)
C_STRING(16;$xml_Parent_Ref;$xml_Child_Ref)
C_LONGINT($LineNum)
If this method is applied to the example below, $LineNum contains the value 1:
See also
GET XML ATTRIBUTE BY INDEX.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The Parse XML information command is used to retrieve diverse information about the
XML element designated by elementRef.
In xmlInfo, pass a code indicating the type of information to be retrieved. You can use the
following predefined constants, located in the “XML” theme:
Constant Type Value
PUBLIC ID Longint 1
SYSTEM ID Longint 2
DOCTYPE Name Longint 3
Encoding Longint 4
Version Longint 5
Document URI Longint 6
See also
GET XML ERROR.
Constants
XML theme.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The GET XML ERROR command returns, in the errorText parameter, a description of the
error encountered when processing the XML element designated by the elementRef
parameter. The information returned is supplied by the Xerces.DLL library.
The optional row and column parameters indicate the location of the error: they retrieve,
respectively, the row number and, in this row, the position of the first character of the
expression at the origin of the error.
See also
Parse XML information.
version 2003
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Description
The CLOSE XML command frees up the memory occupied by the XML object designated
by elementRef.
See also
Parse XML source, Parse XML variable.
Error Codes
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the syntax error codes for errors that may occur during code
execution in the User or Custom Menus environment. Some of these errors may occur in
interpreted mode only, some in compiled mode only, some in both modes. You can
intercept these errors using an error interruption method installed using ON ERR CALL.
Code Description
1 A “(” was expected.
2 A field was expected.
3 The command may be executed only on a field in a subtable.
4 Parameters in the list must all be of the same type.
5 There is no table to which to apply the command.
6 The command may only be executed on a Subtable type field.
7 A Numeric argument was expected.
8 An Alphanumeric argument was expected.
9 The result of a conditional test was expected.
10 The command cannot be applied to this field type.
11 The command cannot be applied between two conditional tests.
12 The command cannot be applied between two Numeric arguments.
13 The command cannot be applied between two Alphanumeric arguments.
14 The command cannot be applied between two Date arguments.
15 The operation is not compatible with the two arguments.
16 The field has no relation.
17 A table was expected.
18 Field types are incompatible.
19 The field is not indexed.
20 An “=” was expected.
21 The method does not exist.
22 The fields must belong to the same table or subtable for a sort or graph.
23 A “<” or “>” was expected.
24 A “;” was expected.
25 There are too many fields for a sort.
26 The field type cannot be Text, Picture, Blob or Subtable.
27 The field must be prefixed by the name of its table.
28 The field type must be Numeric.
29 The value must be 1 or 0.
30 A variable was expected.
31 There is no menu bar with this number.
32 A date was expected.
33 Unimplemented command or function.
Some of these error codes are due to simple programming errors. For example, you get an
error #5 if you execute an ADD RECORD command, when you have not first set the
default table (using the DEFAULT TABLE command), and do not pass the table parameter.
In this case, there is no table to which to apply the command. You eliminate the error by
checking to see if you forgot to set the default table or if you forgot to pass the table
parameter to the command for this occurrence.
Some of these error codes denote errors due to a flaw in the design. For example, you get
an error #16 if you apply RELATE ONE to a field that is not related to any other field. You
eliminate the error by checking to see if your code is actually wrong or if you simply
forgot to create the relation starting from the field.
Some errors, when they occur, are not always located exactly where your code breaks. For
example, if in a subroutine you get an error #53 (indice out of range) on the line
vpFld:=Field($1;$2), the error is due to a wrong table and/or field number that has been
passed to the subroutine as a parameter. Therefore, the error is located in the caller
method and not where the error actually occurs. In this case, trace your code in the
Debugger window to determine which line of code is the real culprit, then fix it in the
Design Method Editor.
See Also
ON ERR CALL.
This table lists the error codes generated by the 4th Dimension Database Engine. These
codes cover errors that occur at a low level of the database engine, such as user
interruption, privilege errors, and damaged objects.
Code Description
1006 Program interrupted by user—user pressed Alt-click (Windows) or Option-click
(MacOS)
3. The error -10503 Record # is out of range does NOT always mean that the database
needs to be repaired. This error may occur if you attempt to use the record number (i.e.,
the command GOTO RECORD) for a newly created record in transaction. The reason is
that newly created records, while in a transaction, are assigned temporary record numbers
until the transaction is validated. If this error occurs in that context, your database is fine,
but your algorithm is not.
4. The error -9999 No more room to save the record occurs when all the segments of your
database are full or located on full volumes. This error can also be generated if the data file
is locked or located on a locked volume.
See Also
ON ERR CALL.
The following table describes the errors that can occur with a network connection.
Code Description
-10001 The actual connection to the database has been disrupted.
-10002 The connection for this process has been disrupted.
-10003 Bad connection parameters.
-10020 No server was selected while using OP Select 4D server.
-10021 No server was found while using OP Find 4D server.
-10030 Desynchronization has occured during the write cycle.
-10031 Desynchronization has occured during the read cycle.
-10033 Incorrect data size during read cycle.
-10050 Unknown option in Get/SetOption.
-10051 Incorrect value in Get/SetOption.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists codes returned by the Operating System File Manager. These
codes can be returned when you are using, for example, the System Documents
commands. In this list, the word “file” indicates a document on disk and not a file in
your database structure.
Code Description
-33 File directory full. You cannot create new files on disk.
-34 Disk is full. There is no more room available on the disk.
-35 Specified volume doesn’t exist.
-36 I/O error. There is probably a bad block on the disk.
-37 Bad filename or volume name.
-38 Tried to read or write to a file that is not open.
-39 Logical end-of-file reached during read operation.
-40 Attempt to position before start of file.
-41 Not enough memory to open a new file on the disk.
-42 Too many files open at the same time.
-43 File not found.
-44 Volume is locked by a hardware setting.
-45 File is locked.
-46 Volume is locked by an application.
-47 Tried to access a file that has been deleted.
-48 Tried to rename a file with the name of an already deleted file.
-49 Tried to open a file already open with write permission.
-51 Tried to access a document with an invalid document reference number.
-52 Internal file manager error (position of file marker is lost).
-53 Volume not on line.
-54 Attempt to open locked file for writing.
-57 Tried to work with a non-Macintosh disk.
-58 Error in the external file system.
-60 Bad master directory block. Your disk is damaged.
-61 Read/write permission doesn’t allow writing.
-64 There is a hardware problem with the disk (bad installation, incorrect formatting...)
-84 There is a hardware problem with the disk (bad installation, incorrect formatting...)
-120 Tried to access a file by using a pathname that specifies a non existing directory.
-121 An access path could not be created.
-124 Tried to access a disconnected shared volume.
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the error codes returned by the Operating System Memory
Manager.
Code Description
-108 Not enough memory to perform an operation.
Give more memory to your 4D application.
-109 Internal Memory problem. Memory is probably logically corrupted.
Exit as soon as possible. Restart your machine and reopen the database.
-111 Internal Memory problem. Memory is probably logically corrupted.
Exit as soon as possible. Restart your machine and reopen the database. (*)
-117 Internal Memory problem. Memory is probably logically corrupted.
Exit as soon as possible. Restart your machine and reopen the database.
Tip: When allocating and working with large arrays, BLOBs, pictures, as well as sets
(objects that can hold large amount of data), use an ON ERR CALL project method to test
the error -108.
(*) Error -111 can also occur when you attempt to read a value from a BLOB with an offset
out of range. In this case, the error is minor and you do not need to terminate the
working session. Just fix the offset you pass to the BLOB command.
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the error codes returned by the Operating System Printing
Manager. These codes can be returned during printing.
Code Description
-1 Problem saving file to be printed
-27 Problem opening or closing connection with printer
-128 Printing interrupted by the user
-193 Resource file not found
-4100 Printer connection has been interrupted
-4101 Printer busy or not connected
-8150 A LaserWriter is not selected
-8151 The printer has been initialized with a different driver version
-8192 LaserWriter time-out
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the error codes returned by the Operating System Resource
Manager.
Code Description
-1 Resource file could not be opened
-192 Resource not found
-193 Resource map is damaged (file needs to be repaired)
-194 Resource could not be added
-196 Resource could not be deleted
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the NaN codes returned by the Operating System. NaN is a
Standard Apple Numeric Environment (SANE) representation which means “Not a
Number.” NaN appears when an operation produces a result that is beyond SANE’s scope.
Code Description
1 Invalid square root
2 Invalid addition
4 Invalid division
8 Invalid multiplication
9 Invalid remainder
17 Converting an invalid ASCII string
20 Converting a Comp type number to floating-point
21 Creating a NaN with a zero code
33 Invalid argument to a trig function
34 Invalid argument to an inverse trig function
36 Invalid argument to a log function
37 Invalid argument to an xi or xy function
38 Invalid argument to a financial function
255 Uninitialized storage
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists the codes returned by the Operating System Sound Manager.
Code Description
-203 Too many sound commands
-204 The sound resource cannot be loaded
-205 The sound channel is logically corrupted
-206 The format of the sound resource is wrong
-207 Not enough memory to perform the sound
-209 The sound channel is busy
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists error codes returned by the Operating System Serial Ports
Manager.
Code Description
-28 There is no open serial port
See Also
ON ERR CALL.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following table lists some of the MacOS system errors. It is usually not possible to
recover from these errors.
Code Description
4 Zero divide
15 Segment Loader Error:
4th Dimension failed in loading one of its own code segments.
You must allocate more memory to 4th Dimension.
17 to 24 A system package is missing.
Check if your system directory has been correctly installed
25 Out of memory
You must allocate more memory to 4th Dimension
28 Stack has moved into the application heap.
You must allocate more memory to 4th Dimension
ASCII Codes
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
• The ASCII codes 128 through 255 are different on Windows and Macintosh. In order to
maintain platform independence, the Windows version of 4th Dimension automatically
converts ASCII codes from Windows to Macintosh ASCII maps when characters are
entering the 4D environment (Data entry, Edit/Paste, Import, etc.) and from Macintosh
to Windows ASCII maps when characters are leaving the 4D environment (Edit/Cut or
Copy, Export, etc.).
The ASCII codes 128 through 255 are listed in ASCII Codes 128..191 and ASCII Codes
192..255.
The codes work the same when you type ALT+0233 in the Procedure editor. However, to
look for a character using its ASCII code, you use the Macintosh ASCII code of the
character.
For example:
QUERY (...; [MyFile]MyField="é") ` é is Alt+0233
See Also
Ascii, ISO to Mac, Mac to ISO, Mac to Win, ON EVENT CALL, Win to Mac.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The standard ASCII codes (0 through 127) are common to Windows and Macintosh.
See Also
Char, ISO to Mac, Mac to ISO, Mac to Win, ON EVENT CALL, Win to Mac.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The standard ASCII codes (0 through 127) are common to Windows and Macintosh.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following tables list the characters displayed by 4th Dimension for each ASCII code,
on Macintosh and Windows. In addition, the tables present the key combination required
to produce each character, using a US keyboard.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
The following tables list the characters displayed by 4th Dimension for each ASCII code,
on Macintosh and Windows. In addition, the tables present the key combination required
to produce each character, using a US keyboard.
version 6.0
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
4th Dimension returns values for Function keys in the KeyCode system variable, which is
used within project methods installed by the ON EVENT CALL command. These project
methods are used to catch events. The values for Function keys are not based on ASCII
codes. They are:
Reminder: The KeyCode system variable is to be used in a project method installed using
ON EVENT CALL.
In addition to the function keys, the following table lists the values returned in KeyCode
when you press one of the common keys, such as Return or Enter.
Command Syntax
A
ABORT
Abs (number) → Number
ACCEPT
ACCUMULATE (data{; data2; ...; dataN})
Activated → Boolean
ADD DATA SEGMENT
ADD RECORD ({table}{; }{*})
ADD SUBRECORD (subtable; form{; *})
Add to date (date; years; months; days) → Date
ADD TO SET ({table; }set)
After → Boolean
ALERT (message{; ok button title})
ALL RECORDS {(table)}
ALL SUBRECORDS (subtable)
Append document (document{; type}) → DocRef
APPEND MENU ITEM (menu; itemText{; process})
APPEND TO CLIPBOARD (dataType; data)
APPEND TO LIST (list; itemText; itemRef{; sublist{; expanded}})
Application file → String
Application type → Long Integer
Application version {(*)} → String
APPLY TO SELECTION ({table; }statement)
APPLY TO SUBSELECTION (subtable; statement)
Arctan (number) → Number
ARRAY BOOLEAN (arrayName; size{; size2})
ARRAY DATE (arrayName; size{; size2})
ARRAY INTEGER (arrayName; size{; size2})
ARRAY LONGINT (arrayName; size{; size2})
ARRAY PICTURE (arrayName; size{; size2})
ARRAY POINTER (arrayName; size{; size2})
ARRAY REAL (arrayName; size{; size2})
ARRAY STRING (strLen; arrayName; size{; size2})
ARRAY TEXT (arrayName; size{; size2})
ARRAY TO LIST (array; list{; itemRefs})
ARRAY TO SELECTION (array; field{; array2; field2; ...; arrayN; fieldN})
ARRAY TO STRING LIST (strings; resID{; resFile})
Ascii (character) → Number
B
BEEP
Before → Boolean
Before selection {(table)} → Boolean
Before subselection (subtable) → Boolean
BEST OBJECT SIZE ({*;}object; bestWidth; bestHeight{; maxWidth})
BLOB PROPERTIES (blob; compressed{; expandedSize{; currentSize}})
BLOB size (blob) → Number
BLOB TO DOCUMENT (document; blob{; *})
BLOB to integer (blob; ordreOctet{; offset}) → Number
BLOB to list (blob{; offset}) → ListRef
BLOB to longint (blob; byteOrder{; offset}) → Number
BLOB TO PICTURE (pictureBlob;picture})
BLOB to real (blob; realFormat{; offset})
BLOB to text (blob; formatTexte{; offset{; longueurTexte}})
BLOB TO VARIABLE (blob; variable{; offset})
BOOLEAN ARRAY FROM SET (booleanArr {;set})
BREAK LEVEL (level{; pageBreak})
BRING TO FRONT (process)
BUTTON TEXT ({*; }object; buttonText)
C
CALL PROCESS (process)
CALL WEB SERVICE (accessURL; soapAction; methodName; namespace{; complexType})
CANCEL
CANCEL TRANSACTION
Caps lock down → Boolean
CHANGE ACCESS
CHANGE LICENSES
CHANGE PASSWORD (password)
Change string (source; newChars; where) → String
Char (asciiCode) → String
CLEAR CLIPBOARD
CLEAR LIST (list{; *})
CLEAR NAMED SELECTION (name)
CLEAR SEMAPHORE (semaphore)
CLEAR SET (set)
CLEAR VARIABLE (variable)
CLOSE DOCUMENT (docRef)
E
EDIT ACCESS
ENABLE BUTTON ({*; }object)
ENABLE MENU ITEM (menu; menuItem{; process})
ENCRYPT BLOB (toEncrypt; sendPrivKey{; recipPubKey})
End selection {(table)} → Boolean
End subselection (subtable) → Boolean
ERASE WINDOW {(window)}
EXECUTE (statement)
EXECUTE ON CLIENT (clientName; methodName {; param1; ...; paramN})
Execute on server (procedure; stack{; name{; param{; param2; ...; paramN}{; *}}}) → Number
Exp (number) → Number
EXPAND BLOB (blob)
EXPORT DATA (fileName {; project{; *}})
EXPORT DIF ({table; }document)
EXPORT SYLK ({table; }document)
EXPORT TEXT ({table;} document)
False → Boolean
Field (tableNum | fieldPtr{; fieldNum}) → Number | Pointer
Field name ({tableNum; }fieldNum | fieldPtr) → String
FILTER EVENT
FILTER KEYSTROKE (filteredChar)
G
GENERATE CERTIFICATE REQUEST (privKey; certifRequest; codeArray; nameArray)
GENERATE ENCRYPTION KEYPAIR (privKey; pubKey {; length})
Gestalt (selector; value) → Number
Get 4D folder → String
Get alignment ({*; } objet) → Number
GET CLIPBOARD (dataType; data)
Get component resource ID (compName; resType; originalNumRes) → Number
Get current printer → String
Get document position (docRef) → Number
Get database parameter ({table;} selector) → Longint
GET DOCUMENT ICON (docPath; icon{; size})
GET DOCUMENT PROPERTIES (document; locked; invisible; created on; created at;
modified on; modified at)
Get document size (document{; *}) → Number
Get edited text → Text
GET FIELD ENTRY PROPERTIES(fieldPtr | tableNum{; fieldNum}; list{; mandatory{;
nonEnterable{; nonModifiable}}})
GET FIELD PROPERTIES ({tableNum; }fieldNum | fieldPtr; fieldType{; fieldLen{; indexed{;
unique{; invisible}}}})
Get First XML element (elementRef{; childElemName{; childElemValue}}) → ElementRef
GET FORM PROPERTIES ({table;} formName; width; height{; title{; widthVar{; heightVar
{; numPages}}}})
GET GROUP LIST (groupNames; groupNumbers)
GET GROUP PROPERTIES (groupID; name; owner{; members})
H
HIDE MENU BAR
HIDE PROCESS (process)
HIDE TOOL BAR
HIGHLIGHT TEXT (area; startSel; endSel)
HIGHLIGHT RECORDS ({setName})
I
IDLE
IMPORT DIF ({table; }document)
IMPORT SYLK ({table; }document)
IMPORT TEXT ({table; }document)
IMPORT DATA (fileName {; project{; *}})
In break → Boolean
In footer → Boolean
In header → Boolean
In transaction → Boolean
INPUT FORM ({table; }form{; *})
INSERT ELEMENT (array; where{; howMany})
INSERT IN BLOB (blob; offset; len{; filler})
INSERT LIST ITEM (list; beforeItemRef | *; itemText; itemRef{; sublist{; expanded}})
INSERT MENU ITEM (menu; afterItem; itemText{; process})
Insert string (source; what; where) → String
Int (number) → Number
INTEGER TO BLOB (integer; blob; byteOrder{; offset | *})
INTERSECTION (set1; set2; resultSet)
INVERT BACKGROUND (textVar | textField)
Keystroke → string
P
PAGE BREAK {(* | >)}
PAGE SETUP ({table; }form)
Parse XML information (elementRef; xmlInfo) → String
Parse XML source (document{; validation{; dtd}}) → ElementRef
Parse XML variable (variable{; validation{; dtd}}) → ElementRef
PAUSE PROCESS (process)
PICTURE LIBRARY LIST (picRefs; picNames)
PICTURE PROPERTIES (picture; width; height{; hOffset{; vOffset{; mode}}})
Picture size (picture) → Number
PLATFORM PROPERTIES (platform; system; machine)
PLAY (objectName{; channel})
PICTURE TO BLOB(picture;pictureBlob;format})
PICTURE TO GIF (pict; blobGIF)
PICTURE TYPE LIST (formatArray{; nameArray})
POP RECORD {(table)}
Pop up menu (contents{; default}) → Number
Position (find; string) → Number
POST CLICK (mouseX; mouseY{; process}{; *})
POST EVENT (what; message; when; mouseX; mouseY; modifiers{; process})
POST KEY (code{; modifiers{; process}})
Q
QUERY ({table}{; queryArgument}{; *})
QUERY BY EXAMPLE {(table)}
QUERY BY FORMULA ({table}{; }{queryFormula})
QUERY SELECTION ({table}{; queryArgument}{; *})
QUERY SELECTION BY FORMULA ({table}{; }{queryFormula})
QUERY SUBRECORDS (subtable; queryFormula)
QUERY WITH ARRAY (indexedField; array)
QUIT 4D ({delay})
Random → Number
READ ONLY {(table | *)}
Read only state {(table)} → Boolean
READ WRITE {(table | *)}
READ PICTURE FILE (fileName; picture)
REAL TO BLOB (real; blob; realFormat{; offset | *})
RECEIVE BUFFER (receiveVar)
RECEIVE PACKET ({docRef; }receiveVar; stopChar | numChars)
RECEIVE RECORD {(table)}
RECEIVE VARIABLE (variable)
Record number {(table)} → Number
Records in selection {(table)} → Number
Records in set (set) → Number
Records in subselection (subtable) → Number
Records in table {(table)} → Number
S
SAVE LIST (list; listName)
SAVE OLD RELATED ONE (field)
SAVE PICTURE TO FILE (document; picture)
SAVE RECORD {(table)}
SAVE RELATED ONE (field)
SAVE SET (set; document)
SAVE VARIABLES (document; variable{; variable2; ...; variableN})
SCAN INDEX (field; number; > or <)
SCREEN COORDINATES (left; top; right; bottom{; screen})
SCREEN DEPTH (depth; color{; screen})
Screen height {(*)} → Number
Screen width {(*)} → Number
SEARCH BY INDEX
Secured Web connection → Boolean
Select folder ({message}) → Alpha
SELECT LIST ITEM (list; itemPos)
SELECT LIST ITEM BY REFERENCE (list; itemRef)
SELECT LOG FILE (logFile)
Selected list item (list) → Long
Selected record number {(table)} → Number
SELECTION TO ARRAY (field | table; array{; field2 | table2; array2; ...; fieldN | tableN; arrayN})
W
WEB CACHE STATISTICS (pages; hits; usage)
Web Context → Boolean
Win to Mac (text) → String
Window kind {(window)}
WINDOW LIST (windows{; *})
Window process {(window)} → Number
Windows Alt down → Boolean
Windows Ctrl down → Boolean
WRITE PICTURE FILE (fileName; picture{; format})
HH MM Long Integer 2
HH MM AM PM Long Integer 5
HH MM SS Long Integer 1
Hour Min Long Integer 4
Hour Min Sec Long Integer 3
B
BEEP 1367
Before 484
Before selection 1134
Before subselection 1242
BEST OBJECT SIZE 731
BLOB PROPERTIES 238
BLOB size 233
BLOB TO DOCUMENT 242
BLOB to integer 260
BLOB to list 249
BLOB to longint 262
BLOB TO PICTURE 836
BLOB to real 264
BLOB to text 266
BLOB TO VARIABLE 247
BOOLEAN ARRAY FROM SET 225
BREAK LEVEL 794
BRING TO FRONT 873
BUTTON TEXT 712
C
CALL PROCESS 859
CALL WEB SERVICE 1582
CANCEL 450
CANCEL TRANSACTION 1346
Caps lock down 1380
CHANGE ACCESS 1402
CHANGE LICENSES 1419
CHANGE PASSWORD 1404
Change string 1194
Char 1188
D
Data file 145
DATA SEGMENT LIST 150
Database event 1361
Date 380
F
False 281
Field 1214
Field name 1211
FILTER EVENT 592
FILTER KEYSTROKE 457
Find in array 207
Find index key 930
Find window 1633
FIRST PAGE 502
FIRST RECORD 1130
FIRST SUBRECORD 1238
FLUSH BUFFERS 153
FOLDER LIST 1281
FONT 705
FONT LIST 1308
Font name 1309
G
GENERATE CERTIFICATE REQUEST 1117
GENERATE ENCRYPTION KEYPAIR 1115
Gestalt 1320
Get 4D folder 148
Get alignment 733
GET CLIPBOARD 292
Get component resource ID 1111
Get current printer 793
Get database parameter 1221
GET DOCUMENT ICON 1292
Get document position 1295
GET DOCUMENT PROPERTIES 1285
Get document size 1293
Get edited text 493
GET FIELD ENTRY PROPERTIES 1217
GET FIELD PROPERTIES 1215
Get First XML element 1647
GET FORM PROPERTIES 1636
GET GROUP LIST 1414
GET GROUP PROPERTIES 1415
GET HIGHLIGHT 1393
GET HTTP HEADER 1568
GET ICON RESOURCE 1095
Get indexed string 1088
GET LIST ITEM 559
GET LIST ITEM PROPERTIES 554
GET LIST PROPERTIES 541
Get menu item 658
Get menu item key 664
Get menu item mark 662
H
HIDE MENU BAR 650
HIDE PROCESS 871
HIDE TOOL BAR 1335
HIDE WINDOW 1619
HIGHLIGHT RECORDS 1148
HIGHLIGHT TEXT 1394
I
IDLE 342
IMPORT DATA 581
IMPORT DIF 577
IMPORT SYLK 573
IMPORT TEXT 569
In break 488
In footer 489
In header 487
In transaction 1347
INPUT FORM 1328
INSERT ELEMENT 209
INSERT IN BLOB 268
INSERT LIST ITEM 551
INSERT MENU ITEM 670
Insert string 1195
Int 624
INTEGER TO BLOB 251
INTERSECTION 1169
K
Keystroke 452
L
Last object 1396
LAST PAGE 503
LAST RECORD 1132
LAST SUBRECORD 1239
Length 1185
Level 806
List item parent 556
List item position 555
LIST TO ARRAY 212
LIST TO BLOB 248
LOAD COMPRESS PICTURE FROM FILE 829
Load list 523
LOAD RECORD 1012
LOAD SET 1166
LOAD VARIABLES 1424
Locked 1014
LOCKED ATTRIBUTES 1015
Log 631
LOG EVENT 1321
LONGINT ARRAY FROM SELECTION 224
M
Mac to ISO 1200
Mac to Win 1198
Macintosh command down 1383
Macintosh control down 1385
Macintosh option down 1384
MAP FILE TYPES 1283
Max 745
MAXIMIZE WINDOW 1621
MENU BAR 648
Menu bar height 1307
Menu bar screen 1306
Menu selected 653
MESSAGE 684
MESSAGES OFF 675
MESSAGES ON 676
Method called on error 597
Method called on event 591
Milliseconds 386
Min 744
MINIMIZE WINDOW 1623
Mod 629
Modified 366
Modified record 1023
MODIFY RECORD 359
MODIFY SELECTION 1141
MODIFY SUBRECORD 363
Month of 374
MOVE DOCUMENT 1267
MOVE OBJECT 729
MULTI SORT ARRAY 205
O
Old 368
OLD RELATED MANY 1054
OLD RELATED ONE 1052
ON ERR CALL 593
ON EVENT CALL 587
ONE RECORD SELECT 1147
OPEN DATA FILE 154
Open document 1259
Open external window 1613
Open form window 1634
Open resource file 1074
OPEN WEB URL 1575
Open window 1610
ORDER BY 931
ORDER BY FORMULA 936
ORDER SUBRECORDS BY 1244
OUTPUT FORM 1330
Outside call 492
R
Random 628
READ ONLY 1010
Read only state 1011
READ PICTURE FILE 838
READ WRITE 1009
REAL TO BLOB 255
RECEIVE BUFFER 315
RECEIVE PACKET 312
RECEIVE RECORD 320
RECEIVE VARIABLE 318
Record number 1028
Records in selection 1124
Records in set 1164
Records in subselection 1236
Records in table 1027
REDRAW 1397
REDRAW LIST 533
REDRAW WINDOW 1616
REDUCE SELECTION 1144
REGISTER CLIENT 904
REJECT 464
S
SAVE LIST 525
SAVE OLD RELATED ONE 1053
SAVE PICTURE TO FILE 832
SAVE RECORD 1025
SAVE RELATED ONE 1051
SAVE SET 1165
SAVE VARIABLES 1423
SCAN INDEX 1146
SCREEN COORDINATES 1302
SCREEN DEPTH 1303
Screen height 1299
Screen width 1300
SEARCH BY INDEX 737
Secured Web connection 1574
Select folder 1271
SELECT LIST ITEM 565
SELECT LIST ITEM BY REFERENCE 566
SELECT LOG FILE 158
Selected list item 563
Selected record number 1127
SELECTION RANGE TO ARRAY 217
T
Table 1212
Table name 1210
Tan 635
Temporary folder 1317
Test clipboard 299
Test path name 1269
Test semaphore 858
TEXT TO BLOB 258
Tickcount 385
Time 384
Time string 383
TRACE 617
Trigger level 1363
TRIGGER PROPERTIES 1364
True 280
Trunc 627
Type 603
V
Validate password 1403
VALIDATE TRANSACTION 1345
VARIABLE TO BLOB 244
VARIABLE TO VARIABLE 866
Variance 747
Version type 138
VOLUME ATTRIBUTES 1279
VOLUME LIST 1278
W
WEB CACHE STATISTICS 1573
Web Context 1565
Win to Mac 1199
Window kind 1627
WINDOW LIST 1626
Window process 1628
Windows Alt down 1382
Windows Ctrl down 1381
WRITE PICTURE FILE 837